Laravel Session Flash persists for 2 requests - php

Recently I have changed to Laravel from Codeigniter, everything was going fine except I encountered a problem with Session::flash.
when I create new user I get success message but It will persist for 2 requests, even I didn't pass the validator:
my code in UsersController:
function getCreateUser(){
$config = array(
'pageName' => 'createUser',
'pageTitle' => 'Create User',
'formUrl' => action('UsersController#postCreateUser'),
'modelFields' => array(
array('db_name' => 'employee_id', 'text' => 'Employee Id', 'mandatory' => TRUE),
array('db_name' => 'full_name', 'text' => 'Full Name', 'mandatory' => TRUE),
array('db_name' => 'email', 'text' => 'Email', 'mandatory' => FALSE),
array('db_name' => 'password', 'text' => 'Password','value' => '12345', 'mandatory' => TRUE)
),
'submit_text' => 'Create'
);
return View::make('layouts.form', $config);
}
function postCreateUser(){
$config = array(
'pageName' => 'createUser',
'pageTitle' => 'Create User',
'formUrl' => action('UsersController#postCreateUser'),
'modelFields' => array(
array('db_name' => 'employee_id', 'text' => 'Employee Id', 'mandatory' => TRUE),
array('db_name' => 'full_name', 'text' => 'Full Name', 'mandatory' => TRUE),
array('db_name' => 'email', 'text' => 'Email', 'mandatory' => FALSE),
array('db_name' => 'password', 'text' => 'Password','value' => '12345', 'mandatory' => TRUE)
),
'submit_text' => 'Create'
);
$validator = User::validate(Input::all());
if($validator->passes()){
$user = new User(Input::all());
$user->password = Hash::make(Input::get('password'));
$user->Company_id = '1';
$user->save();
Session::flash('message', 'User Created Successfully!');
Session::flash('alert-class', 'alert-success');
return View::make('layouts.form', $config);
}
return View::make('layouts.form', $config)->withErrors($validator->messages());
}
in form.blade:
#if ( $errors->count() > 0 )
<div class="alert alert-danger">
<p>The following errors have occurred:</p>
<ul>
#foreach( $errors->all() as $message )
<li>{{ $message }}</li>
#endforeach
</ul>
</div>
#endif
in master.blade:
#if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }} alert-dismissable"> {{ Session::get('message') }}</p>
#endif
Maybe I'm not alone with this issue, here is another unanswered question.
Update
For anyone in future facing this problem:
Never flash session data without redirecting.
My code now looks like this:
function postCreateUser(){
$validator = User::validate(Input::all());
if($validator->passes()){
$user = new User(Input::all());
$user->password = Hash::make(Input::get('password'));
$user->Company_id = '1';
$user->save();
Session::flash('message', 'User Created Successfully!');
Session::flash('alert-class', 'alert-success');
} else {
Session::flash('message', Helpers::formatErrors($validator->messages()->all()));
Session::flash('alert-class', 'alert-danger');
}
return Redirect::action('UsersController#getCreateUser');
}

You are Flashing session data and creating a view instead of redirecting, meaning the message will Flash for this request and for the next one, showing twice.
If you want to show the message on the current request without redirecting, I would suggest providing the errors to your View::make instead of trying to Flash the messages. If you MUST Flash the message on the current request, then you will need to Session::forget('key') or Session::flush() after your view.

The following seems to be available from version 5.1 onward. It used to be undocumented, now it is: see Laravel's session documentation.
session()->now()
This is the same as flash, except it won't persist to the next request.

As #Drew said earlier
You are Flashing session data and creating a view instead of
redirecting, meaning the message will Flash for this request and for
the next one, showing twice.
An easy way to flash a message once when you are creating a view is:
Session::flash($key, $value);
Session::push('flash.old', $key);
Happy coding!

I had a similar problem, but I couldn't use Return::redirct, as I was using Ajax to to post to and from a within a set of Tabs.
Therefore, I was calling
Input::flashExcept('_token');
only if the validation failed and returning a view with the old input. Assuming validation passed and I wanted to run some functions and create a new view based on new data, I would call:
Session::forget('_old_input');
I would put this before my final View::make
Hope this helps (or makes sense)...

create:
$request->session()->flash('status', 'Task was successful!');
delete:
$request->session()->forget('status');

Check the scope of your Api's both session put and session get Api's have to be in same scope(i e web.php or api.php).

A good method to repopulate form with old data:
Controller:
View::make( 'view.name' )->withOldFormData( Input::all() );
View:
{{ Form::model( $old_form_data ) }}

Related

Laravel 5.2 Validation not working

I have following forms
{{ Form::text("theme[header_color]", '', []) }}
{{ Form::text("theme[bg_color]", '', []) }}
{{ Form::text("theme[text_color]", '', []) }}
I added following rules in request method.
theme[text_color]="required",
theme[bg_color]="required",
theme[text_color]="required"
I enter value in all field but still getting required validation error.
Please help have a look and help us.
THanks
Try this code does this help
$rules = array(
'theme.text_color' => 'required',
'theme.bg_color' => 'required',
'theme.header_color' => 'required',
);
$messages = [
'theme.text_color.required' => 'Please add Text Color.',
'theme.bg_color.required' => 'Please add Text Color.',
'theme.header_color.required' => 'Please add Header Color.',
];

Unable to retain values in form after unsuccessful submission of form in codeigniter

I am creating a form in codeigniter where user needs to fill data and submit it, but after submission of form if there are any errors the user gets redirected back to the form, however at this stage the values that he had entered should stay in the form.
I am getting the flashdata error but the values are not getting retained in the form. I tried to use set_value but just getting blank form in return. Can any one please point out the error
View
<?php echo form_open_multipart('student/data/'.$student->id); ?>
<p><?php echo $this->session->flashdata('req_msg'); ?></p>
<?php
$data = array(
'type' => 'text',
'name' => 'name',
'placeholder' => 'Full Name',
'class' => 'form-control',
'id' => 'form-first-name',
'value' => set_value('name')
);
?>
<?php echo form_input($data); ?>
<?php
$data = array(
'type'=>'tel',
'pattern'=>'^\d{10}$',
'name' => 'contactno',
'placeholder' => 'Enter 10 digit Contact No',
'class' => ' form-control',
'required' => 'required',
'id' => 'form-first-name',
'value' => set_value('contactno')
);
?>
<?php echo form_input($data); ?>
<div class="form-group">
<?php
$data = array(
'type' => 'submit',
'class' => 'btn btn-primary',
'name' => 'submit',
'content' => 'Upload',
'id' => 'btn-submit'
);
echo form_button($data);
?>
</div>
<?php echo form_close(); ?>
Controller
$this->form_validation->set_rules('contactno', 'Contact Number', 'trim|is_unique[student.contactno]');
if ($this->form_validation->run() == FALSE)
{
$this->session->set_flashdata('req_msg', 'Contact number already exists');
redirect('student/data/'.$studentid);
}
Your view file's code is absolutely correct. You only need to few modifications in your controller's method.
There few key points you need to know before implementing solution in your code:
Redirect only when your validation rules passes successfully and your motive behind taking user's input is done
When your validation rules does not pass then load your view instead redirecting it
Put form_error(FIELD_NAME) along with each input to show validation error
Below is the example of action:
public function add()
{
$this->form_validation->set_rules('contactno', 'Contact Number', 'trim|is_unique[student.contactno]');
if ($this->form_validation->run() !== FALSE) {
// Your database or model function calling will be coded here and make sure it returns boolean value
if ($isTrue) {
$this->session->set_flashdata('req_msg', 'Congrats! You have successfully submitted data');
redirect('student/data/'.$studentid);
}else{
// Handle error logs here
}
}
$this->load->view('your_view', $this->view_data);
}
This is the complete solution. I am sure you will get all the values set in form field in case of validation rule fails.
Let me know if you face any issue.
The problem is caused because you redirect after FALSE form_validation. You must load the view there like below :
if ($this->form_validation->run() == FALSE) {
//your code
$this->load->view('your_view', $this->view_data);
}
In your view you have to use set_value() in your inputs.
More info # documentation

How pass data from controller to for_validation config file in Codeigniter?

im using a config form_validation.php, how can i send a variable from controller to this file (form_validation.php) ?
In my form_validation.php i have:
array(
'field' => 'edituser_email',
'label' => 'Email',
'rules' => "required|trim|xss_clean|valid_email|edit_unique[users.email.$user_id]",
'errors' => array(
'required' => 'Campo obligatorio.',
'valid_email' => 'Formato de correo no vĂ¡lido.',
'edit_unique' => 'Ya existe un usuario con este correo.'
)
)
i need send "user_id" variable through Controller.
I already tried with:
$data['user_id'] = $id;
if ($this->form_validation->run('edit_user',$data) === FALSE)
But I get errors :
Message: Undefined variable: user_id.
Thanks for your help.
No need to pass arguments to $this->form_validation->run() , just set rules before executing it.
$this->form_validation->set_rules('name', lang('title'), 'required|trim');
$this->form_validation->set_rules('description', lang('description'), 'required');
$this->form_validation->set_rules('slug', lang('slug'), 'trim|required|is_unique[categories.slug]|alpha_dash');
if ($this->form_validation->run() == true)
{
$data = array(
'name' => $this->input->post('name'),
'description' => $this->input->post('description'),
'parent_id' => $this->input->post('parent_category'),
'slug' => $this->input->post('slug'),
'active' => $this->input->post('active'),
'private' => $this->input->post('private'),
);
}
I don't try, but I think, if you add a variable to array post, like this, it works.
$this->input->post['user_id'] = $user_id;
as documentation here
In the documentation if you want to override post data you need to set data first before run validation.
for ex:
$post_data = array_merge(array('user_id' => $id), $this->input->post(NULL, TRUE)); //merge existing post data with your custom field
$this->form_validation->set_data($post_data);
then
if ($this->form_validation->run('edit_user') === FALSE){
// error view
}
else{
// success view
}

How to return custom error message from controller method validation

How to return a custom error message using this format?
$this->validate($request, [
'thing' => 'required'
]);
to get custom error message you need to pass custom error message on third parameter,like that
$this->validate(
$request,
['thing' => 'required'],
['thing.required' => 'this is my custom error message for required']
);
For Multiple Field, Role and Field-Role Specific Message
$this->validate(
$request,
[
'uEmail' => 'required|unique:members',
'uPassword' => 'required|min:8'
],
[
'uEmail.required' => 'Please Provide Your Email Address For Better Communication, Thank You.',
'uEmail.unique' => 'Sorry, This Email Address Is Already Used By Another User. Please Try With Different One, Thank You.',
'uPassword.required' => 'Password Is Required For Your Information Safety, Thank You.',
'uPassword.min' => 'Password Length Should Be More Than 8 Character Or Digit Or Mix, Thank You.',
]
);
https://laravel.com/docs/5.3/validation#working-with-error-messages
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);
"In most cases, you will probably specify your custom messages in a language file instead of passing them directly to the Validator. To do so, add your messages to custom array in the resources/lang/xx/validation.php language file."
Strangely not present in the documentation, you can specify the first parameter as the validation rules & the second parameter as the message format directly off of the Illuminate/Http/Request instead of invoking $this or the Validator class.
public function createCustomer(Request $request)
{
# Let's assume you have a $request->input('customer') parameter POSTed.
$request->validate([
'customer.name' => 'required|max:255',
'customer.email' => 'required|email|unique:customers,email',
'customer.mobile' => 'required|unique:customers,mobile',
], [
'customer.name.required' => 'A customer name is required.',
'customer.email.required' => 'A customer email is required',
'customer.email.email' => 'Please specify a real email',
'customer.email.unique' => 'You have a customer with that email.',
'customer.mobile.required' => 'A mobile number is required.',
'customer.mobile.unique' => 'You have a customer with that mobile.',
]);
}
You need to first add following lines in view page where you want to show the Error message:
<div class="row">
<div class="col-md-4 col-md-offset-4 error">
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
</div>
Here is a demo controller by which error message will appear on that page:
public function saveUser(Request $request)
{
$this->validate($request,[
'name' => 'required',
'email' => 'required|unique:users',
]);
$user=new User();
$user->name= $request->Input(['name']);
$user->email=$request->Input(['email']);
$user->save();
return redirect('getUser');
}
For details You can follow the Blog post.
Besides that you can follow laravel official doc as well Validation.

passing two parameter in form cant seem to figue out

Basically I have an event ID and User ID i need to pass in the form to store... however when i hit create it comes up with
Route pattern "/roles/{id}/{{id}}" cannot reference variable name "id" more than once.
However if i hit enter in the URL bar it works... so not to sure whats happening here... help would be greatful here the code.
Route file
// POST Add Users Race
Route::post('racehistory/{event_id}/store/{user_id}/race/', 'racehistoryController#store');
// GET Current Races
Route::get('events/currentRace', 'racingeventController#viewCurrentRace');
// GET Users
Route::get('events/{event_id}/users', 'racingeventController#users');
// GET Users with Group ID
Route::get('events/{event_id}/{group_id}', 'racingeventController#grouped');
// GET Add Users Race Form
Route::get('events/{event_id}/user/{user_id}/addrace', 'racingeventController#addUserRace');
// Add User to Event
Route::get('events/{event_id}/user/{user_id}', 'racingeventController#addUserToEvent');
// DELETE Remove User from Race Event
Route::get('events/{event_id}/delete/user/{user_id}', 'racingeventController#deleteUserToEvent');
// DELETE Race Event
Route::get('events/delete/{event_id}', 'racingeventController#destroy');
Route::resource('events', 'racingeventController');
Form View
{{ Form::open(array('class' => 'form-horizontal', 'method' => 'post', 'action' => array('racehistoryController#store', $user->id, $event->id))) }}
Controller - racehistoryController
public function store($event_id, $user_id)
{
$rules = array(
'start_event' => 'required',
'end_event' => 'required',
'pool_type' => 'required|max:3|min:3',
'name' => 'required|max:35|min:3',
'location' => 'required|max:35|min:3',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return 'form works';
}
}
Name your route:
Route::get(
'racehistory/{event_id}/store/{user_id}/race/',
['as' => 'store', 'uses' => 'racehistoryControlle#store']
);
Fix Form::open() helper:
{{
Form::open([
'class' => 'form-horizontal',
'method' => 'post',
'route' => ['store', $user->id, $event->id]
])
}}

Categories