Im making form via LaravelCollective forms in my app.
I have email changing form with fields:
New e-mail
Confirm Email
Password
I need to validate user password on this form with user password in database. Can i do it via Validate?
My form:
{{ Form::model($user, ['route' => ['profile.email.update']]) }}
<div class="form-group row">
<div class="col-md-12">
<h2>Edytuj email</h2>
<div class="form-group">
<label for="edit-page-email">Nowy adres email</label>
{{Form::text('email',null,['class' => 'form-control', 'id'=>'edit-page-email'])}}
</div>
<div class="form-group">
<label for="edit-page-repemail">Nowy adres email (powtórz)</label>
{{Form::text('email_confirmation',null,['class' => 'form-control', 'id'=>'edit-page-email'])}}
</div>
<div class="form-group">
<label for="edit-page-pass">Twoje hasło</label>
{{Form::password('password',['class' => 'form-control', 'id'=>'edit-page-npass'])}}
</div>
<div class="col-md-12 text-center">
{{Form::submit('Zapisz zmiany',['class' => 'btn btn-primary btm-sm']) }}
Anuluj
</div>
</div>
</div>
{{Form::close()}}
And validation is:
$request->validate([
'email' => 'required|confirmed',
'email_confirmation' => 'required',
'password' => 'required|confirmed',
]);
Any ideas how can i do this?
You can compare a string with the user's stored password using this
$pwd = "secret";
$user = User::find(1);
Hash::check($pwd, $user->password); //returns a boolean
Not sure when you say I need to validate user password on this form with user password in database
However the password and password confirm validation should look like the following
{{ Form::password('password',['class'=> 'form-control','placeholder'=>'Enter your Password']) }}
{{ Form::password('password_confirmation', ['class' => 'form-control','placeholder'=>'Re-enter your Password']) }}
Now your validation rules should be
'password' => 'required|confirmed',
No you cannot do this with built in validation rules of Laravel. Beside, you might already know that Laravel store password using bycrypt method. This is not just a plain string comparison operation too.
So, you need to write your own custom validation to check password, or you can just check password and return error if not matched instead of validation.
Note: The confirmed validation rule is to check one password is matched with another password filed or not. This is basically used to match two password form in single form. Not to check associated hashed password with the email in db.
Related
I am creating a form that has a field that is required (trip_route_name). I want to generate a name for this (say a random number for example) when the form is submited rather than having the user fill out the form. How do I do that? Here is the code for the form:
<div class="form-group">
<div class="col-md-6">
{!! Form::label('trip_route_name', 'Trip Route Name') !!}
{!! Form::text( 'trip_route_name', null, ['class' => 'form-control']) !!}
<p id="msg_trip_route_name" class="text-danger">{!! $errors->first('trip_route_name', ':message') !!}</p>
</div>
</div>
You can use str_random() helper:
{!! Form::text( 'trip_route_name', str_random(20), ['class' => 'form-control']) !!}
The str_random function generates a random string of the specified length.
If you don't want user could see generated random name, use hidden instead of text.
I am using Laravel 5.3.18 to build a form that allows the user to enter one or more dates. I am also using the HTML/Form library from the Laravel Collective along with a FormRequest object to validate the fields. My problem is when the user dynamically adds in more date inputs (via JavaScript) and submits the form, if it doesn't pass validation, the "dynamically" added data (and inputs) are not redisplayed on the form.
My question is: Does Laravel handle this use case? And if so, how can I make this work (or what am I doing wrong)? Your insights and help are much appreciated!
Here is the actual snippet of code that initially generates the date inputs:
#foreach ($eventDates as $index=>$eventDate)
<div class="form-group{{ $errors->has('eventDates.'.$index.'.start_datetime') ? ' has-error' : '' }}" id="{{ 'event_date_group_'.$index }}">
{!! Form::label('eventDates['.$index.'][start_datetime]', 'Event Dates (Day '.($index + 1).')', ['class' => 'col-md-4 control-label']) !!}
<div class="col-md-3">
{!! Form::text('eventDates['.$index.'][start_datetime]', $eventDate['start_datetime'], ['id' => 'start_datetime_'.$index, 'class' => 'datetimepicker form-control']) !!}
#if ($errors->has('eventDates.'.$index.'.start_datetime'))
<span class="help-block"><strong>{{ $errors->first('eventDates.'.$index.'.start_datetime') }}</strong></span>
#endif
</div>
</div>
#endforeach
which generates this:
<div class="form-group" id="event_date_group_0">
<label for="eventDates[0][start_datetime]" class="col-md-4 control-label">Event Dates (Day 1)</label>
<div class="col-md-3">
<input id="start_datetime_0" class="datetimepicker form-control" name="eventDates[0][start_datetime]" type="text">
</div>
</div>
So, if the user dynamically creates another date input, it will look as follows:
<div class="form-group" id="event_date_group_0">
<label for="eventDates[0][start_datetime]" class="col-md-4 control-label">Event Dates (Day 1)</label>
<div class="col-md-3">
<input id="start_datetime_0" class="datetimepicker form-control" name="eventDates[0][start_datetime]" type="text">
</div>
</div>
<div class="form-group" id="event_date_group_1">
<label for="eventDates[1][start_datetime]" class="col-md-4 control-label">Event Dates (Day 2)</label>
<div class="col-md-3">
<input id="start_datetime_1" class="datetimepicker form-control" name="eventDates[1][start_datetime]" type="text">
</div>
</div>
And here is part of my FormRequest object:
public function rules() {
return [
'name' => 'required|max:100',
'eventDates.*.start_datetime' => 'required',
'eventDates.*.end_datetime' => 'required',
...
];
}
public function messages() {
return [
'eventDates.*.start_datetime.required' => 'Start date/time is required.',
'eventDates.*.end_datetime.required' => 'End time is required.',
...
];
}
Lastly, the validation works. The error messages show up for the dates input. In fact, if I dynamically create the extra date inputs. Fill everything out but leave just the dynamic date inputs blank, the validation will fail and the form will redisplay but the dynamic inputs and data don't show up. I also put in the following debug statement in the template to see how many elements come back in the array and it always show just 1.
<p>Number of Dates: {{ count($eventDates) }}</p>
I have a slight problem. I have a system whereby I can drag and drop my own forms. The html code for a form is saved in my database. When it comes to the edit page, I do something like the following
{!! Form::model($project->document, [
'class'=>'form-horizontal',
'method' => 'PATCH',
'route' => ['projects.documents.update', $project, $document->id]
]) !!}
{!! $documentData->documentData !!}
<div class="form-group">
{!! Form::submit('Save Data', ['class' => 'btn btn-primary']) !!}
</div>
{!! Form::close() !!}
$documentData->documentData contains the html code for this particular form.
Now my problem is, $documentData->form_data contains the old inputs for this form.
Is there any way to get this old input into the form, the way I am currently handling things?
Thanks
in controller you can access old input by $request->flash(); while in frontend you can access old by input type="text" name="name" value="{{ $name }}"
I am working on laravel 5 eCommerce web portal.
I am having an issue when the user updates the password using the ready made scripts.
The issue is that I can send the link to the customer perfectly without any issue and the customer can change his password also. But when logged out and re-logging in, I get the error as Invalid credentials.
In my routes.php, I have this:
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
This is the login page:
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<label class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input type="email" class="form-control" name="email" value="{{ old('email') }}">
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password">
</div>
</div>
<div class="form-group">
<div class="col-md-4"></div>
<div class="col-md-4">
Forgot Password
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary btn-block">Login</button>
</div>
</div>
</form>
I cannot login again after I am logged out once the password has been reset.
EDIT 1:
When the login button is clicked on the login form page, the postLogin method is called. Here's the code
public function postLogin( Request $request ) {
$this->validate( $request, [
'email' => ['required', 'exists:users,email,role,customer'],
'password' => 'required'
]);
$credentials = $request->only('email', 'password');
if ( \Auth::attempt($credentials) ) {
\Session::flash('logged_in', 'You have successfully logged in.');
return redirect('/');
}
return redirect('/login')->withInput($request->all())->withErrors(['email' => 'Invalid Email Address Or Password']);
}
EDIT 2:
I just realize that login is not checking for the hash and hence returning false, on doing dd(\Hash::check($request->password, $user->password)), after updating the password and re-logging in. What could be the issue with this ?
Where have I made mistake ? Kindly guide me.
Thanks in advance.
P.S.: I am using the defaults only to update the password, rest all, I have made the controllers and models which are all working fine without any issue.
I stumbled upon this as well and found the answer here, just adding this for future reference..
The reason is that as soon as you add the setPasswordAttribute method on your User model, the password is hashed twice when using the built-in password reset functionality of Laravel. As explained on the Laracast page, all it needs is a check for an already hashed password, eg:
// Add Hash facade
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
// ...
/**
* Automatically hash password
*
* #param String $value The password, maybe hashed already
*
* #return string|null
*/
public function setPasswordAttribute($value)
{
if ($value) {
$this->attributes['password'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
}
}
}
If the new password does not work after changing then something goes wrong when changing the password.
Most likely suspect is the encryption. It can be possible that you are not using the Hash::make($password) and saving it in plaintext format.
You can doublecheck if the hash is saved correctly to DB with function Hash::check($password, $hash);
During the login you can check the password as
public function postLogin( Request $request ) {
$user=User::where('email', $request->email);
Log::debug("Testing $request->password $user->password ". Hash::check($request->password, $user->password));
}
If the Hash::check is false then something went wrong when saving new password. $user->password must be in hashed form.
I'm trying to check if the email is already exist my database on my subscribes table.
Form
{!! Form::open(array('url' => '/subscribe', 'class' => 'subscribe-form', 'role' =>'form')) !!}
<div class="form-group col-lg-7 col-md-8 col-sm-8 col-lg-offset-1">
<label class="sr-only" for="mce-EMAIL">Email address</label>
<input type="email" name="subscribe_email" class="form-control" id="mce-EMAIL" placeholder="Enter email" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;"><input type="text" name="b_168a366a98d3248fbc35c0b67_73d49e0d23" value=""></div>
</div>
<div class="form-group col-lg-3 col-md-4 col-sm-4"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="btn btn-primary btn-block"></div>
{!! Form::close() !!}
Controller
public function postSubscribe() {
// Validation
$validator = Validator::make( Input::only('subscribe_email'),
array(
'email' =>'unique:subscribes',
)
);
if ($validator->fails()) {
return Redirect::to('/#footer')
->with('subscribe_error','This email is already subscribed to us.')
->withErrors($validator)->withInput();
}else{
dd("HERE");
$subscribe = new Subscribe;
$subscribe->email = Input::get('subscribe_email');
$subscribe->save();
return Redirect::to('/thank-you');
}
}
Debuging Steps
I tried inputting email that I know already exist in my db.
I want to my validation to fail, and redirect me back to my /#footer (homepage).
I try printing dd("HERE"); if my vaildation not fail.
BUT I keep getting HERE to print which mean my validation is not failing.
Why is that happening ? I'm completely blank out now.
Can someone please point out what I missed ?
I know I am very close.
Thanks.
Your db field name is email not subscribe_email, your input param name however is. Laravel defaults to the fieldname given with the input, so in your case subscribe_email
Try this:
array(
'subscribe_email' => 'required|email|unique:subscribes,email',
)
This uses the db fieldname email, like you have, but the validation is on the field subscribe_email.
try specifying the column name of email in subscribes table
$rules = array(
'email' => 'email|unique:subscribes,email'
);
It looks like the reason this is not working is because you are trying to match the subscribe_email field against validation for a email field, no match is being made. To fix you need to do this:
$validator = Validator::make( Input::only('subscribe_email'),
array(
'subscribe_email' =>'email|unique:subscribes,email',
)
);
//put this in your controller
if (User::where('email', '=', Input::get('email'))->exists()) {
return back()->withErrors([
'message' => 'Email is already taken'
]);
//then go up and include
use Illuminate\Support\Facades\Input;