Laravel: How to mark Session data as flashed - laravel

I am trying to pre-populate an input on a form for the creation of a model entity in Laravel 5.4. But the form is a shared blade template with the edit form for the same model, where I want to use form-model binding to provide the input.
The way I have achieved this so far is to flash a session variable to _old_input in the controller for the creation route:
session()->flash('_old_input.description', $event->description);
This achieves exactly what I want it to, with the exception of not being cleaned out at the end of the request. My next request still has the session data flashed.
My question is how does Laravel know that this is the recipient of a flash message as opposed to the input of a flashed message? And is there a way to tell it that I've already used the session flash and it should be cleaned up at the end of this request...

You need to use redirect to flash the session... otherwise, you will end up with the flash staying on for the next request...
You can return a view... like
return redirect('view')->with('_old_input.description', $event->description);
Or you can even redirect to a controller action ... like
session()->flash('_old_input.description', $event->description);
return redirect()->action('MyController#function');
which would work also... the key is to return a redirect response...
Hope this helps...

Serge is correct that flash is intended for use to put data into the session for the NEXT request and thus redirecting is the correct way to do this, I will also provide here the solution I used to hack my way past this...
Laravel stores its flash data in the _flash value in the session array, with keys which are to be used in the NEXT request under the new key, and keys which were used in THIS request in the old key; see extract below.
[_flash] => Array
(
[old] => Array
(
)
[new] => Array
(
[0] => _old_input
)
)
Using session()->push('_flash.old', '_old_input'); fools Laravel into thinking that this is data that was flashed into this request from the previous one, and clears up the data at the end of its cycle.
For full effect, you can use session()->forget('_flash.new.0'); to remove it from the new key, although beware that this is not necessarily the first flashed var (in my case it is).
My total code is therefore:
session()->flash('_old_input', ['description' => $event->description]);
session()->push('_flash.old', '_old_input');
session()->forget('_flash.new.0');
Again, Serge is correct but if anyone else comes here to find out how Laravel's flashing works and wants to circumvent it, here is a bit of information

Related

How to return to another page after finishing process in Laravel?

This is a little bit hard to understand even the title I put. Sorry about that I just do not know how to clearly explain this, but I will try...
So for example I have a controller and inside that controller I have a function which return the data in the table of my database. then in the last column of every row, I make view,add,edit,delete options as links. When a user clicks on the add for example, they will redirect to an add page. After they submit the form of the add page. they should be redirected to the first page that return the data from the table. but the problem is, the variables of foreach loop in the first page do not got recognized by laravel anymore. because they do not got processed since the route does not goes to the controller and to the function that return the data instead it goes to add function.
So I want to know is there anyway to solve this? If you could provide sample code, I would appreciate a lot thanks
From your explanation, I believe the code to go back to the original page after adding, editing etc is simply return redirect()->back(). This will take the user back to the previous page. As for data continuity, one approach would be considering using sessions. They save data globally and can be accessed from any controller once saved. To do this, simply save the data with session(['session_name' => $data]) and to retrieve the data use session('session_name'). Let me know if this helps!
If you want ti redirect after something like a login or an activation process you can do it with something like this:
return redirect()->to('login')
You can specify the path from your web.php file as you can see in my example in 'myPath'
As #DerickMasai correctly pointed out it is better to use named routes instead of hard coding the path itself.
Naming a route can work like so:
Route::get('/login', [LoginController::class, 'index'])->name('login');

Using laravels {{old}} on dynamically created inputs

I have a form which allows a user to create an unlimited number of fields. If this forms fails validation I want the user to return to this page with the form populated with their previous input values - i.e. I want these fields to persist.
With a normal form I could do this with {{ old 'title' }}, however, these additional fields are being generated through JavaScript and so I cannot add this PHP snippet. What is the best way for me to retrieve these previous input values?
3 ways to do this, cache, sessions and cookies.
cache and sessions are server side which is much better for security, however it will take extra time and effort for setting up, but if the data is not sensible and can be passed within cookies, better to the cookies.
The best thing about cookies for your current situation is: you can set it up directly from your front end JS code.

CakePHP Auth Loads Too Many Session Variables

Using CakePHP2.0 Beta I managed to write a custom login handler for my existing database schema. All's well, except that upon logging in I printed out the session variables stored and what Cake's Auth component did is store the entire record from the "Member" table (where my usernames+hashes come from) in session. It is storing an array with data fields that are totally irrelevant to the session. For instance it stores the date the member was created, their address, etc. All pretty useless information for me as I basically only need their ID and maybe username, name, email address.
The offending lines for me are found in: /lib/Cake/Controller/Component/AuthComponent.php line 512. It states,
$this->Session->write(self::$sessionKey, $user);
So my custom authenticate component returns $user and it throws this whole thing into the session. Now, I don't want to go about editing in the core libraries because this project is definitely going to be upgraded when 2.0 comes out. Is there any way to store less information in sessions? I want to keep this whole thing more lightweight.
Possible solution: Change my custom authentication component to only return the fields I need into the $user variable. Are there any concerns about what data I should/shouldn't be returning?
I've solved the problem using my "possible solution". In /app/Controller/Component/auth/MyController.php, I changed the "ClassRegistry::init($userModel)->find" method to have a parameter for 'fields' where I specify only the fields I need. Works like a charm.

Codeigniter using flashdata and form_validation

I am trying to learn PHP with codeigniter, had have come across a problem. Am writing a user registration form with form validation.
If the user input has passed validation, it will check database if the email is already existing in the database. If it exists, it should show an error to the user.
I am storing this error in the flashdata session variable, and redirecting the user to the registration form. But after redirection, the form set_values are empty.
I want it to be populated with the values the user already filled out earlier. If I use $this->load->view('registration_form').. the field values are populated like I want, but the database error does not show, since it's not a new server call.
Does the form_validation values (set_value()) disappear on a redirect? If it does, how can I prepopulate the field values?
If you redirect when a form that posts to itself is valid, then yes you will lose set_value() as there is now nothing in the $_POST array - this is why you redirect, so a user won't resubmit the form on refresh.
What you should do is create your own validation rule in a callback function in the same controller. See here http://codeigniter.com/user_guide/libraries/form_validation.html#callbacks
What you need to do is pass the email to a model in the callback that will check the email against your database and return false if it is already there. This way, your form will not be valid and not redirect if the email already exists.
I was just adding a form to an old CI installation minutes ago and had this issue. It's funny you should mention it.
Since set_value() and the related functions are only reading the $_POST data, they will not hold the value after a refresh. You have a few options:
Don't redirect until the form is valid.
Assign the $_POST array to a flashdata (session) variable, and copy it to the $_POST array manually after the redirect
Write your own group of functions to handle this with either flashdata or session data or other method, and don't use the set_value() functions.
For the quickest fix, use #1. I don't like manually setting $_POST values, so I don't really endorse #2, but it should work. For the long term - use #3. I find that the CI form handling is often lacking, and my personal form interaction code base has grown quite a bit over time.

Use CodeIgniter form validation in a view

I have footer view that's included on all my pages which contains a form. I would like to be able to make use of CI's form validation library to validate the form. Is that possible?
Currently the form posts back to the current page using the PHP_SELF environment variable. I don't want to get it to post to a controller because when validation fails it loads the controller name in the address bar, which is not the desired behaviour.
Any suggestions gratefully received.
Thanks,
Gaz
One way, whilst far from ideal, would be to create a "contact" function in every controller. This could be in the form of a library/helper.
CI doesn't natively let you call one controller from another, although I believe there are extensions that enable this.
Another option would be an AJAX call instead, which would allow you to post to a generic controller, validate etc whilst remaining on the current page.
In this use case, I would definitely go for an AJAX call to a generic controller. This allows you to show errors even before submitting in the origin page.
Another way (slightly more complex), involves posting your form data to a generic controller method, passing it a hidden input containing the current URL.
The generic controller method handling your form can then redirect to the page on which the user submitted the form, passing it the validation errors or a success message using flash session variables: $this->session->set_flashdata('errors',validation_errors()) might do the trick (untested)
The good thing about this is that you can use the generic form-handling method for both the ajax case (suppressing the redirect) and the non-ajax case
AJAX would be best, just like everyone else says.
I would redirect the form to one function in one controller, you could make a controller just for the form itself. Then have a hidden value with the return URL. As far as errors go you could send them back with flashdata.
Just remember to never copy paste code, it a bad practice and guarantees bugs.
//make sure you load the proper model
if ($this->form_validation->run() == FALSE){
// invalid
$redirect = $this->input->post('url');
$this->session->set_flashdata('errors',validation_errors());
redirect($redirect);
} else {
/*
success, do what you want here
*/
redirect('send them where ever');
}

Resources