2
votes

I'm working with differing versions of Laravel and have built an addon that uses Laravel 5.4, Which unfortunatley is using a DB that references Laravel 3 sic

The "users" table has a column titled "user_email".

On the reset password, I want to change the DB Query to check against "user_email" not "email". As I currently get the error :

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'email' in 'where clause'

SQL Query that it's trying to run is :

SQL: select * from `users` where `email` = [email protected] limit 1

Is there any way of changing this to suit?

Thanks

3
Could you show your query?Felix Maxime
Sure : SQL: select * from users where email = [email protected] limit 1StuBlackett
I checked files in Illuminate/Auth/Passwords/. The email column is hardcoded.Orkhan Alikhanov
Which method is it hardcoded in @OrkhanAlikhanov ?StuBlackett
If you're using the stand 5.4 User model and authentication, you should be able to add a function named "getEmailForPasswordReset()" in your user model.rexw

3 Answers

1
votes

For correctly custom the Column email you need do some change, first need override that method (getEmailForPasswordReset and routeNotificationFor) into model User:

public function getEmailForPasswordReset()
{
    return $this->email_user;
}

public function routeNotificationFor($driver)
{
    if (method_exists($this, $method = 'routeNotificationFor'.Str::studly($driver))) {
        return $this->{$method}();
    }

    switch ($driver) {
        case 'database':
            return $this->notifications();
        case 'mail':
            return $this->email_user;
        case 'nexmo':
            return $this->phone_number;
    }
}

and implement:

use Illuminate\Support\Str;

into ForgotPasswordController need override the method called sendResetLinkEmail and validateEmail:

public function sendResetLinkEmail(Request $request)
{
    $this->validateEmail($request);

    // We will send the password reset link to this user. Once we have attempted
    // to send the link, we will examine the response then see the message we
    // need to show to the user. Finally, we'll send out a proper response.
    $response = $this->broker()->sendResetLink(
        $request->only('email_user')
    );

    return $response == Password::RESET_LINK_SENT
                ? $this->sendResetLinkResponse($response)
                : $this->sendResetLinkFailedResponse($request, $response);
}

protected function validateEmail(Request $request)
{
    $this->validate($request, ['email_user' => 'required|email']);
}

Afther you need Override some method (validateNewPassword, validatePasswordWithDefaults, reset) from PasswordBroker, but we need.

  1. Created a CustomPasswordResetServiceProvider inside App\Providers where I registered a CustomPasswordBrokerManager instance.

    namespace App\Providers;
    use Illuminate\Support\ServiceProvider;
    use App\Services\CustomPasswordBrokerManager; 
    class CustomPasswordResetServiceProvider extends ServiceProvider{
        protected $defer = true;
    
        public function register()
        {
            $this->registerPasswordBrokerManager();
        }
    
        protected function registerPasswordBrokerManager()
        {
            $this->app->singleton('auth.password', function ($app) {
                return new CustomPasswordBrokerManager($app);
            });
        }
    
        public function provides()
        {
            return ['auth.password'];
        }
    }
    
  2. In config/app.php commented out line:
    //Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
    and added:
    App\Providers\CustomPasswordResetServiceProvider::class,

  3. Inside App\Services folder created a CustomPasswordBrokerManager and copied the context of the default PasswordBrokerManager located at:
    Illuminate\Auth\Passwords\PasswordBrokerManager.php
    Then modified the function resolve to return an instance of my CustomPasswordProvider class.

    protected function resolve($name)
    {
        $config = $this->getConfig($name);
        if (is_null($config)) {
            throw new InvalidArgumentException("Password resetter [{$name}] is not defined.");
        }
    
        return new CustomPasswordBroker(
            $this->createTokenRepository($config),
            $this->app['auth']->createUserProvider($config['provider'])
    );
    }
    
  4. Finally inside App\Services folder I created a CustomPasswordBroker class which extends default PasswordBroker located at:
    Illuminate\Auth\Passwords\PasswordBroker and overridden the functions that I needed.

    use Illuminate\Auth\Passwords\PasswordBroker as BasePasswordBroker;    
    
    class CustomPasswordBroker extends BasePasswordBroker    
    {    
    // override the method validateNewPassword, validatePasswordWithDefaults and reset, you can take from Illuminate\Auth\Passwords\PasswordBroker   
    
    }      
    

Not sure if this is the best implementation.

Regards :)

0
votes

Add a class variable in ResetPasswordController

 protected $username = 'user_email';

Also add in LoginController for login purpose

0
votes

Add this method to your LoginController

public function username()
{
    return 'user_email';
}