Codeigniter: Passing form data from view to controller - codeigniter

Which is right? notice in the second option, I'm passing the form values using the $_POST variable. Whereas the first option, I call and assign variables for each form field.
I've seen this ...
<validation code> ....
$todo = array(
'name'=>$this->input->post('title'),
'description'=>$this->input->post('description')
);
$this->Todo_model->add($todo);
But I've also seen the following ...
$records['email'] = "trim|required|min_length[4]|xss_clean";
...
...
$this->validation->set_rules($records);
if ($this->validation->run())
{
$this->account_model->saveAccountSettings("sam", $_POST);
$this->session->set_flashdata('message', 'Done!');
redirect('account/settings');
} else {
...
}

I tend to use a mix of your two examples. I'm pretty sure things like trim won't modify the actual post data, so you can only take advantage of it if you go through the validation framework to get the data. I actually never access POST directly anymore using CI.
Plus I'd be worried in your second example about just shoving POST into my model. What happens if someone clever adds "lastname" to the post data sent in and your db column is named the same? Even though you weren't expecting to deal with that data now you've got unvalidated data coming in. That's why I employ part of your first example and manually pull out the items I want to save into an array first.
So I'd recommend a hybrid.
Normally my code looks something like this:
$fields['email'] = "trim|required|valid_email|min_length[4]|xss_clean";
...
...
$this->validation->set_rules($fields);
if ($this->validation->run())
{
$account = new array();
$account['id'] = $accountId; //wherever you get the Id from
$account['email'] = $this->validation->email;
$this->account_model->save($account);
$this->session->set_flashdata('message', 'Done!');
redirect('account/settings');
} else {
...
}

The first option is better easy to read or trace
Pass values using post variables is better option

What the real benefit to use this
$account['email'] = $this->validation->email;
Instead of
$account['email'] = $this->input->post('email');

Related

Why do I get \r\n stored in the database and how to display it back as a new line? [duplicate]

For this query, is necessary to use mysql_real_escape_string?
Any improvement or the query is fine ?
$consulta = $_REQUEST["term"]."%";
($sql = $db->prepare('select location from location_job where location like ?'));
$sql->bind_param('s', $consulta);
$sql->execute();
$sql->bind_result($location);
$data = array();
while ($sql->fetch()) {
$data[] = array('label' => $location);
}
The query speed is important in this case.
No, prepared queries (when used properly) will ensure data cannot change your SQL query and provide safe querying. You are using them properly, but you could make just one little change. Because you are using the '?' placeholder, it is easier to pass params through the execute method.
$sql->execute([$consulta]);
Just be careful if you're outputting that to your page, SQL parameter binding does not mean it will be safe for display within HTML, so run htmlspecialchars() on it as well when outputting.

How to apply an operation/functionality on one column during getting data of a table in Laravel Controller?

I want to get all the data of today's Date, but during getting it I want to apply an operation on the data of one column only NOT others. This operation is from another function.
$data = Net::whereDate('created_at', Carbon::today())->get();
I have two options:
During getting data, call to that function on the specific column
After getting data, put a loop and then apply that operation and save data into new object
In this table, there is a column called profit, and I want to encode this profit into alphabets by calling encode_code() function remaining the other data as it is.
I don't know how I can do this, please help me if anyone knows.
You can use a foreach loop to get each object from the collection and for each of those object,call the desired function.
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $key => $dat)
{
$data[$key]->profit = encode_code($dat->profit);
}
I think you should call the function and turn it like this
I just didn't know what you wanted to do, so this is my best
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $i => $d){
$data[$i]->profit = encode_codeļ¼ˆ$d->profit);
}
Of course you could loop through your result and encode each row, but this would prevent you from reusing this code.
Instead you could put that encode function directly into the model, so that you can reuse it everywhere:
public function getEncodedProfit() {
return encode_code($this->profit);
}
Now you can just use this function everywhere in your controllers or views like that:
echo $net->getEncodedProfit();

How to pass input request to foreach loop in controller to store data

I'm building a site with localizations using laravel. Trying to store names and texts in 3 languages using a form. I have a model for each article and another for article translations.
Using inputs for names and texts with input names like name_en, text_en, name_de, text_de etc...
But i can't figure out how to pass input values to a foreach loop in the store method in my controller.
I tried to pass (Request $request) object into foreach loop but it returns an error. Code is below:
public function store(Request $request)
{
$test = new Test;
$test->isActive = true;
$test->save();
//TRANSLATED INPUTS = name_tr,text_tr,name_en,text_en,name_de,text_de
foreach (['tr', 'en', 'de'] as $locale => $request)//OBVIOUSLY WRONG
{
$test->translateOrNew($locale)->name = $request->input('name_'.$locale);
$test->translateOrNew($locale)->text = $request->input('body_'.$locale);
}
$test->save();
dd($test);
//echo 'Created new article with some translations!';
}
Trying to get translated inputs itno database.
It is possible to do this the way you have it set up. You could use a series of if str contains, then str replace on name, and text, until you get the right language. But that's potentially a lot of work and likely pretty confusing if you have many names and texts coming from your form (which I assume you do from the need for a foreach on the incoming data).
I suggest you re-work your form slightly to return a bit more information. Consider the following as possible elements to return from the form:
name[]
text[]
language[]
Then, in your store method you can run through each of these in a number of ways, but to explain, I'll use the clearest (though not the most efficient):
Set an index:
$i = 0;
Run through all of the form's returns, and get the corresponding text and language that comes with the name (through the same index):
foreach($request->get('name') as $name){
$lang = $request['language'][$i];
$test->translateOrNew($lang)->name = $name;
$test->translateOrNew($lang)->text = $request['text'][$i];
$i ++;
}
This is almost pseudo code, and you will have to re-factor to make it work for you, but it should give you one idea on how you might do this. You will need to validate that the user provides each set (name, text, language) as complete, or the index will fail.

Session variable on refresh

I have laravel controller like this:
public function postSessionTopic() {
$article_id = Input::get('article_id', 0);
$comment_id = Input::get('comment_id', 0);
\Session::set('page_topic_id', $article_id);
\Session::set('page_comment_id', $comment_id);
\\comment - I have tried \Session::put too, but that doesn't change anything
}
I use it, when user click on a article. I print_r out my session variable in this controller and everything looks fine. But after that I refresh my page, and there I read value from session, and sometimes it load old value or doesn't load anything. I can't understand why, because in controller i can see, that correct value is saved!
In my page, i get that value like this:
\Session::get('page_topic_id', 0)
Probably you do something wrong. You should make sure that in both cases you uses exactly same domain (with or without www).
In this controller when you don't have any input you set to session variables 0. This can also be an issue if you launch this method when you don't have any input.
You could try with adding this basic route:
Route::get('/session', function() {
$page_topic = Session::get('page_topic_id', 1);
$page_comment = Session::get('page_comment_id', 1);
echo $page_topic.' '.$page_comment.'<br />';
$article_id = $page_topic * 2;
$comment_id = $page_comment * 3;
Session::set('page_topic_id', $article_id);
Session::set('page_comment_id', $comment_id);
});
As you see it's working perfectly (but you need to remove session cookie before trying with this path).
You get
1 1
2 3
4 9
8 27
and so on. Everything as expected
Answer was - two ajax at one time. Don't do that, if you store something in session.
The session in Laravel doesn't consider changes permanent unless you generate a response (and that's the result of using symphony as it's base). So make sure your app->run() ends properly and returns a response before refreshing. Your problem is mostly caused by a die() method somewhere along your code or an unexpected exit of PHP instance/worker.
This is probably not your issue but if you are storing your laravel session in the database their is a limit on how large that value can be. The Laravel session migration has a field called "payload" that is a text type. If you exceed the limit on that field the entire session gets killed off. This was happening to me as I was dynamically adding json model data to my session.
Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
});
How much UTF-8 text fits in a MySQL "Text" field?

CakePHP Pagination sort() on Related Models

I have two models: Plans and PlanDetails.
Relationship is: PlanDetails hasMany Plans. Plans belongTo PlanDetails.
In the PlanDetails view.ctp, I am pulling in related Plans.
I am trying to sort the Plans by ANY field (I've tried them all), and I cannot get it working. I assume I am overlooking something very simple.
Here is my base code:
PlanDetail >> view.ctp:
...foreach ($planDetail['Plan'] as $plan_edit) :
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}...
<?php echo $this->Paginator->sort('Plan ID', 'Plan.id'); ?>...
...<?php echo $plan_edit['id']; ?>
plan_details_controller.php:
...function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid plan detail', true));
$this->redirect(array('action' => 'index'));
}
$this->PlanDetail->recursive = 2; // To run the editable form deeper.
$this->set('planDetail', $this->PlanDetail->read(null, $id));
$this->set('plan', $this->paginate('Plan'));
}...
I should add, no errors are being thrown and the sort() arrows on the ID field are showing as expected, but the sort order DOES not change when clicked either way.
Sorry, I'm not able to comment on the question itself, but I've noticed that in your action, you set planDetail to be the PlanDetail record you read (with recursive set to 2), and then you set plan to be the result of the paginate call.
Then, in your view template, you're iterating over $planDetail's contained Plan association, like this:
foreach ($planDetail['Plan'] as $plan_edit):
But in order to get the sorting and pagination done, you need to be displaying the results of the paginate call i.e. iterate over the records contained in $plan.
Do a debug($plan) in your view template to see what results you get there and to see if the records' ordering changes when you sort by different fields.
Also, perhaps you're using syntax I'm not aware of, but if you simply call $this->paginate('Plan') in your controller, I don't know that you're going to get only the related Plan records for your particular PlanDetail record. (There's nothing tying the $id passed into your view action with the Plan records.) You might need to add some conditions to the paginate call, like so:
$this->paginate['Plan'] = array('conditions' => array('Plan.plan_detail_id' => $id));
$this->set('plans', $this->paginate('Plan'));
Here is what I did to solve this. Based on some helpful direction from johnp & tokes.
plan_details/view.ctp:
...$i = 0;
foreach ($plan as $plan_edit) : // note $plan here.
}...
In my plan_details_controller.php view action:
$conditions = array("Plan.plan_detail_id" => "$id");
$this->set('plan', $this->paginate('Plan', $conditions)); // note "plan" in the first argument of set (this is required to pass the results back to the view). Also. The $condition is set to return ONLY plans that match the plan_detail_id of id (on the plan_details table).
And in my view, in order to get my results (because I changed the array name), I had to change the way I was getting the values to:
$plan_edit['Plan']['modified'] // note I placed ['Plan'] in front of these calls as the array called for this to get the data...
Well until the next problem! SOLVED.

Resources