Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override a core Laravel 4 class method

Apologies if this is a dumb question as a lot of Laravel 4 is new to me. I'm trying to override a couple of the methods in the core password functionality as I want to define my own password validation rules (hardcoded into core at the time of posting), and change the method of error reporting ($errors array used on other forms, rather than than session-based).

So my approach was to create a new class in /app/lib/MyProject/User called Password.php that looks like this:

<?php namespace MyProject\User;

use Closure;
use Illuminate\Mail\Mailer;
use Illuminate\Routing\Redirector;
use Illuminate\Auth\UserProviderInterface;

    class Password extends \Illuminate\Support\Facades\Password
    {
        /**
     * Reset the password for the given token.
     *
     * @param  array    $credentials
     * @param  Closure  $callback
 * @return mixed
 */
public function reset(array $credentials, Closure $callback)
{
    // If the responses from the validate method is not a user instance, we will
    // assume that it is a redirect and simply return it from this method and
    // the user is properly redirected having an error message on the post.
    $user = $this->validateReset($credentials);

    if ( ! $user instanceof RemindableInterface)
    {
        return $user;
    }

    $pass = $this->getPassword();

    // Once we have called this callback, we will remove this token row from the
    // table and return the response from this callback so the user gets sent
    // to the destination given by the developers from the callback return.
    $response = call_user_func($callback, $user, $pass);

    $this->reminders->delete($this->getToken());

    return $response;
}

}

I've copied the reset method from /vendor/laravel/framework/src/Illuminate/Auth/Reminders/PasswordBroker.php, which appears to be where the core Password facade resolves to.

Then in my composer.json file, I've added the following to the autoload:classmap array:

"app/lib/MyProject/User"

Finally, in my /app/config/app.php file I've amended the Password alias:

'Password' => 'MyProject\User\Password',

OK. In my routes.php file I have the following which is pretty much taken straight from the docs:

Route::post('password/reset/{token}', function()
{
    $credentials = array('email' => Input::get('email'));

    return Password::reset($credentials, function($user, $password)
    {
        $user->password = Hash::make($password);

        $user->save();

        return 'saved - login';
    });
});

When this reset() method runs, I get the following error:

Non-static method MyProject\User\Password::reset() should not be called statically

The reset() method in the class I'm extending isn't static so that surprised me, however setting my reset method to static clears that error. Next though, I get the following error:

Using $this when not in object context

Which comes when trying to run $this->validateReset($credentials).

I'm completely out of my depth now. Am I going about this the right way or completely off the right path?

Thanks for any advice

like image 339
Russ Back Avatar asked Oct 04 '22 01:10

Russ Back


1 Answers

You should extends the Illuminate\Auth\Reminders\PasswordBroker class, not the \Illuminate\Support\Facades\Password.

the \Illuminate\Support\Facades\Password class is a Facade, not the final class.

You can see the final classes of the facades by:

get_class(Password::getFacadeRoot());
like image 106
Miguel Borges Avatar answered Oct 07 '22 19:10

Miguel Borges