I'm really new to this framework, and it seem so magic to me. I can't even find where it call the function reset() in route and controller. but I know it's been call before controller after browsing around the googles for whole day.
Here's the problem, I've been testing to override function reset and function validatePasswordWithDefaults in PasswordBroker
I do it by extends PasswordBroker, but seem like I have to fully migrate all the function in Illuminate\Auth\Passwords\PasswordBroker into my App\Services\PasswordBroker else i will hit error:
Target [Illuminate\Contracts\Auth\UserProvider] is not instantiable
My sample code is here:
Custom PasswordServiceProviders that bind my PasswordBroker to Illuminate PasswordBroker:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class PasswordResetServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind(
'Illuminate\Contracts\Auth\PasswordBroker','App\Services\PasswordBroker'
);
}
}
Custom PasswordBroker:
<?php
namespace App\Services;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Auth\Passwords\TokenRepositoryInterface;
use Illuminate\Auth\Passwords\PasswordBroker as BasePasswordBroker;
use Illuminate\Contracts\Auth\PasswordBroker as ContractPasswordBroker;
use Closure;
class PasswordBroker extends BasePasswordBroker
{
public function reset(array $credentials, Closure $callback)
{
dd($callback);
$user = $this->validateReset($credentials);
if ( ! $user instanceof CanResetPasswordContract)
{
return $user;
}
$pass = $credentials['password'];
call_user_func($callback, $user, $pass);
$this->tokens->delete($credentials['token']);
return PasswordBrokerContract::PASSWORD_RESET;
}
protected function validatePasswordWithDefaults(array $credentials)
{
list($password, $confirm) = [
$credentials['password'], $credentials['password_confirmation'],
];
return $password === $confirm && mb_strlen($password) >= 4;
}
}
?>
This is not straightforward, on my opinion the framework shouldn't send an email so deep into the code and provide a way to override it from a controller.
I had to override the email sending because I needed to use Mandrill's api, so I had to send extra headers in the very instant the mail gets sent. This is what I did:
Create a provider class on App\Providers\PasswordResetServiceProvider. I copied the framework's default provider (Illuminate\Auth\Passwords\PasswordResetServiceProvider) but I had to do some slight modifications on the order of the registrations and later on the way you retrieve the tokens service. Also you had to specify where your PasswordBroker is (in my case is on \App\Services\PasswordBroker)
use Illuminate\Support\ServiceProvider;
use Illuminate\Auth\Passwords\DatabaseTokenRepository as DbRepository;
class PasswordResetServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerTokenRepository();
$this->registerPasswordBroker();
}
/**
* Register the password broker instance.
*
* @return void
*/
protected function registerPasswordBroker()
{
return $this->app->singleton('auth.password', function($app)
{
// The password token repository is responsible for storing the email addresses
// and password reset tokens. It will be used to verify the tokens are valid
// for the given e-mail addresses. We will resolve an implementation here.
$tokens = $app['auth.password.tokens'];
$users = $app['auth']->driver()->getProvider();
$view = $app['config']['auth.password.email'];
// The password broker uses a token repository to validate tokens and send user
// password e-mails, as well as validating that password reset process as an
// aggregate service of sorts providing a convenient interface for resets.
return new \App\Services\PasswordBroker(
$tokens, $users, $app['mailer'], $view
);
});
}
/**
* Register the token repository implementation.
*
* @return void
*/
protected function registerTokenRepository()
{
$this->app->singleton('auth.password.tokens', function($app)
{
$connection = $app['db']->connection();
// The database token repository is an implementation of the token repository
// interface, and is responsible for the actual storing of auth tokens and
// their e-mail addresses. We will inject this table and hash key to it.
$table = $app['config']['auth.password.table'];
$key = $app['config']['app.key'];
$expire = $app['config']->get('auth.password.expire', 60);
return new DbRepository($connection, $table, $key, $expire);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['auth.password', 'auth.password.tokens'];
}
}
Create the class \App\Services\PasswordBroker, there you can override emailResetLink(), there is no mystery on that step.
Register the new provider on the providers array from config\app.php (App\Providers\PasswordResetServiceProvider). Comment out the default one (Illuminate\Auth\Passwords\PasswordResetServiceProvider)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With