Bypassing email = unique:users in laravel - php

I am using Laravel 5.2, and I am trying to create a dashboard where the user can update his information, but I am facing one problem which is bypassing unique:users in validator.
if the user wants to keep same email, validator gives an error of 'The email has already been taken', also user should not change email to another email which is reserved by another user.
How can I avoid this validation in case if this user is the only user has this email.
my controller function:
public function update(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
// if fails, return response with errors
if($validator->fails())
return back()->withErrors($validator)->withInput();
$user = Auth::user();
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->password = bcrypt($request->input('password'));
$user->update();
return back()->withInput();
}

Laravel's unique validator can take additional parameters that can help you exclude given ID from the unique check.
The syntax is:
unique:<table>,<column>,<id_to_exclude>
In your case, you'll need the follwing validation rule:
'email' => 'required|email|max:255|unique:users,email,'.$id

Just change your code to:
public function update(Request $request)
{
$id = Auth::user()->id;
$validator = Validator::make($request->all(), [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users'.$id,
'password' => 'required|min:6|confirmed',
]);
// if fails, return response with errors
if($validator->fails())
return back()->withErrors($validator)->withInput();
$user = Auth::user();
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->password = bcrypt($request->input('password'));
$user->update();
return back()->withInput();
}
Why this works? Well the laravel Unique validation searches for the unique value in the table specified. So unique:users searches if the email exists in db. The user id here works as a way to exclude the check for this user.
Also, if you want that email should not be edited, then just exclude it from the request.
$input = $request->excpet(['email']); check docs

Related

Laravel Redirection and logic queue with email verification

I have one form in frontend where I have there is some city details , rooms details and user registration in one form like I have city name , room name , address etc email addresss and password in same form and I have done 2 logics in one controller for creating cities and registering user
It is saving the both data in correct table in the database
but I want that first user should register and if user is vcerified only the room details should be saved in database
I am in confusion wheather to apply if again or what
public function checkLogin(Request $request)
{
$user = User::create([
'name'=>$request->name,
'email'=>$request->email,
'password'=>$request->password,
'role_id' => config('quickadmin.default_role_id'),
]);
if ($user) {
if (Auth::check()) {
$city = TotalCity::create([
'name'=>$request->name,
'created_by'=>$request->created_by_id,
]);
}
return redirect()->to('/admin/home');
}
}
Let me show you how I'd probably write this logic:
public function checkLogin(Request $request)
{
$user = User::firstOrCreate([
'email'=> $request->email,
],
[
'name'=> $request->name,
'password'=> bcrypt($request->password),
'role_id' => config('quickadmin.default_role_id'),
]);
if (Auth::check()) {
// it's not clear if you utilize `email_verified_at`, if so
// if (Auth::check() && Auth::user()->email_verified_at) {
$city = TotalCity::create([
'name'=>$request->name,
'created_by'=> Auth::user()->id, // or $user->id depending on your preference
]);
}
return redirect('/admin/home');
}
The firstOrCreate() checks if an entry with that email exists, it gets it, otherwise creates it.
Furthermore, if I want to check for Authentication, I'd use 'auth' middleware in my route.
Route::get('example', 'ExampleController#checkLogin')->middleware('auth');
That removes the need of entire check:
if (Auth::check()) { ... }

Reduce password validation code in Laravel

The following code is the implementation of the authentication based on whether or not a user enters a password in the edit page of user data.
How could I simplify this code using only a few methods?
...
$user = User::findOrFail($id); //Get role specified by id
if($request->password === null){
$this->validate($request, [
'name'=>'required|max:120',
'email'=>'required|email|unique:users,email,'.$id
]);
$request->password = $user->password;
}
else{
//Validate name, email and password fields
$this->validate($request, [
'name'=>'required|max:120',
'email'=>'required|email|unique:users,email,'.$id,
'password'=>'required|min:6|confirmed'
]);
}
$input = $request->only(['name', 'email', 'password']); //Retreive the name, email and password fields
$roles = $request['roles']; //Retreive all roles
$user->fill($input)->save();
...
Specs
Laravel ver.5.6
$this->validate($request, [
'name'=>'required|max:120',
'email'=>'required|email|unique:users,email,'.$id,
'password'=>'nullable|required|min:6|confirmed'
]);
Use nullable rule in password validation. White saving the password use code like this:
if($request->password){
$user->password = bcrypt($request->password);
}

Laravel 5 custom login with username OR email using the Attempt method

In my laravel app, at the start I had decided to create my own custom login controller, rather than use the base one.
public function postSignin(Request $request, AppMailer $mailer) {
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
if (!Auth::attempt($request->only(['email', 'password']), $request->has('remember'))) {
return redirect()->back()->with('info', 'Could not sign you in with those details.');
}
if (Auth::attempt(['email' => $request->input('email'), 'password' => $request->input('password'), 'verified' => 0]))
{
$mailer->sendEmailConfirmationTo(Auth::user());
Auth::logout();
return redirect()->back()->with('info', 'Email verification required.');
}
Auth::user()->last_login = new DateTime();
Auth::user()->save();
return redirect()->back()->with('info', 'You are now signed in.');
}
And now I want to edit this so that users can also login with their usernames and not just their emails, using the same field. However, the attempt method is confusing. It seems to expect an email even after I switch the values around.
The Auth documentation isn't very helpful in this case either. It asks me to add this:
public function username()
{
return 'username';
}
in the login controller, but obviously this is for a default setup.
You can use the 'FILTER_VALIDATE_EMAIL' checker.
$username = $request->get('username');
$password = $request->get('password');
$remember_me = $request->get('remember_me','1');
$field = filter_var($username,FILTER_VALIDATE_EMAIL)? 'email': 'username';
if(Auth::attempt([$field => $username,'password' => $password],$remember_me)){
//Auth successful here
}
Meaning FILTER_VALIDATE_EMAIL do check the string whether it is in email format or not.
I hope this sample code helps you.
-ken

Unexpected T Variable Laravel

I'm getting an error on the following on:
$user->email = Input::get('email');
I'm really unsure what is wrong with the code, it seems perfectly fine. I looked up t variable errors, simply involve missing a bracket or semi colon. But as far as I'm aware it seems fine.
If anyone could help me out, that would be great.
If there is any other code, could you list it as a comment and i'll happily add it.
Thanks!
public function doRegister()
{
$rules = array(
'name' => 'required|min:3', // name
'email' => 'required|email', // make sure the email is an actual email
'password' => 'required|alphaNum|min:3' // password can only be alphanumeric and has to be greater than 3 characters
);
// run the validation rules on the inputs from the form
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()){
// validation not successful, send back to form
Redirect::back()->withErrors;
} else {
$user = Input::all();
User::addNewUser();
if (Auth::attempt($user)) {
return Redirect::to('member');
}
}
}
User model
public static function addNewUser()
{
$user = new User;
$user->name     = Input::get('name');
$user->email    = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->save();
}
It's because of $user->save; it's a method not a property and it should be called like
$user->save();
Instead of
$user->save;
Update : Also, it's U not u
$user = new user;
should be
$user = new User; // capital U
Also, after if ($validator->fails())
Redirect::back()->withErrors;
should be
return Redirect::back()->withErrors($validator);
Update : So, after fixing 3 errors (so far), your full code should be
public function doRegister()
{
$rules = array(
'name' => 'required|min:3',
'email' => 'required|email',
'password' => 'required|alphaNum|min:3'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()){
return Redirect::back()->withErrors($validator);
}
else {
$user = new User;
$user->name =Input::get('name');
$user->email= Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->save();
if (Auth::attempt($user)) {
return Redirect::to('member');
}
}
}

how to check if a user email already exist

In laravel, when a new user is registering to my site and the email they use already exist in the database. how can tell the user that the email already exist ?. I am new to laravel framework. A sample code would be nice too.
The validation feature built into Laravel lets you check lots of things, including if a value already exists in the database. Here's an overly simplified version of what you need. In reality you'd probably want to redirect back to the view with the form and show some error messages.
// Get the value from the form
$input['email'] = Input::get('email');
// Must not already exist in the `email` column of `users` table
$rules = array('email' => 'unique:users,email');
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
echo 'That email address is already registered. You sure you don\'t have an account?';
}
else {
// Register the new user or whatever.
}
);
Laravel has built-in human readable error messages for all its validation. You can get an array of the these messages via: $validator->messages();
You can learn more about validation and what all you can do with it in the Laravel Docs.
Basic Usage Of Unique Rule
'email' => 'unique:users'
Specifying A Custom Column Name
'email' => 'unique:users,email_address'
Forcing A Unique Rule To Ignore A Given ID
'email' => 'unique:users,email_address,10'
Adding Additional Where Clauses
You may also specify more conditions that will be added as "where" clauses to the query:
'email' => 'unique:users,email_address,NULL,id,account_id,1'
The above is from the documentation of Laravel
You could add:
public static $rules = [
'email' => 'unique:users,email'
];
You can add more rules to the $rules like:
public static $rules = [
'email' => 'required|unique:users,email'
];
It will automatically produce the error messages
and add:
public static function isValid($data)
{
$validation = Validator::make($data, static::$rules);
if ($validation->passes())
{
return true;
}
static::$errors = $validation->messages();
return false;
}
to the model User.php
Then in the function you're using to register, you could add:
if ( ! User::isValid(Input::all()))
{
return Redirect::back()->withInput()->withErrors(User::$errors);
}
if(sizeof(Users::where('email','=',Input::get('email'))->get()) > 0) return 'Error : User email exists';
The great resource is only Laravel Documentation #
enter link description here
I also did like below when integrating user management system
$user = Input::get('username');
$email = Input::get('email');
$validator = Validator::make(
array(
'username' => $user,
'email' => $email
),
array(
'username' => 'required',
'email' => 'required|email|unique:users'
)
);
if ($validator->fails())
{
// The given data did not pass validation
echo 'invalid credentials;';
// we can also return same page and then displaying in Bootstap Warning Well
}
else {
// Register the new user or whatever.
$user = new User;
$user->email = Input::get('email');
$user->username = Input::get('username');
$user->password = Hash::make(Input::get('password'));
$user->save();
$theEmail = Input::get('email');
// passing data to thanks view
return View::make('thanks')->With('displayEmail', $theEmail);
}
public function userSignup(Request $request, User $data){
# check user if match with database user
$users = User::where('email', $request->email)->get();
# check if email is more than 1
if(sizeof($users) > 0){
# tell user not to duplicate same email
$msg = 'This user already signed up !';
Session::flash('userExistError', $msg);
return back();
}
// create new files
$data = new User;
$data->name = $request->name;
$data->email = $request->email;
$data->password = md5($request->password);
$data->save();
//return back
Session::flash('status', 'Thanks, you have successfully signup');
Session::flash('name', $request->name);
# after every logic redirect back
return back();
}
I think when u try something like this you earn a smooth check using Model
We can use the Validator.
In your Controller.
$validator = $request->validate([
'name' => 'required',
'phone' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required',
]);
In View
#error('email') <span class="text-danger error">{{ $message }}</span>#enderror
$this->validate($request, [
'fname' => 'required',
'lname' => 'required',
'email' => 'required|min:4|email|unique:users',
'password' => 'required',
]);
Try This

Categories