2

I want to use my own PasswordBroker because the default one can't have its variable "emailView" modified after being initialized.

But I can't extend it in my custom class.

Class App\Http\Controllers\Auth\MyPasswordBroker cannot
    extend from interface Illuminate\Contracts\Auth\PasswordBroker

This is my code:

<?php namespace App\Http\Controllers\Auth;
use Illuminate\Support\Facades\Password;
use Illuminate\Contracts\Auth\PasswordBroker;


class MyPasswordBroker extends PasswordBroker {
    public function setEmailView($view) {
        $this->emailView = $view;
    }
}
Kalzem
  • 7,320
  • 6
  • 54
  • 79

2 Answers2

3

So what you'll want to do in this case is extend from the class, not the interface (Contract in Laravel-speak) and then bind that to the container. An implementation would look like follows:

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Support\Facades\Password;
use Illuminate\Auth\Passwords\PasswordBroker;

class MyPasswordBroker extends PasswordBroker 
{
    public function setEmailView($view) 
    {
        $this->emailView = $view;
    }
}

Then, in your AppServiceProvider's register method, you would place

$this->app->bind(\Illuminate\Contracts\Auth\PasswordBroker::class, \App\Http\Controllers\Auth::class)

This will register your implementation to the contract, rather than Laravel's own implementation.

Phroggyy
  • 423
  • 3
  • 10
  • For the register part, it says `Cannot instantiate interface Illuminate\Contracts\Auth\PasswordBroker` – Kalzem Mar 30 '16 at 03:41
  • Or maybe, do you know why it gives me `Target [Illuminate\Contracts\Auth\UserProvider] is not instantiable.` when I don't add to the register function of AppServiceProvider? I just want to use MyPasswordBroker in one very specific case and still keep using on the defaut PasswordBroker in the rest of the server. – Kalzem Mar 30 '16 at 03:54
  • Sorry, it should be `bind` not `register`. I've updated the answer to reflect that – Phroggyy Mar 30 '16 at 07:34
  • I still have the `Target [Illuminate\Contracts\Auth\UserProvider] is not instantiable.`. Here is the log http://pastebin.com/ZVFjfDjr. It seems that MyPasswordBroker can't correctly initiate because of the UserProvider from its construct parameters (which comes from PasswordBroker). But I'm not sure what I am supposed to do to make it work. – Kalzem Mar 30 '16 at 10:31
  • @BabyAzerty how are you attempting to access the password broker – Phroggyy Mar 30 '16 at 21:30
  • I am using dependency injection on my Controller `public function __construct(MyPasswordBroker $passwords)` and there is a function in my Controller where I call `$this->passwords->setEmailView($path)` with $this->passwords being set in the construct function. – Kalzem Mar 30 '16 at 22:26
  • You should DI the contract not the implementation if you really wanna make use of it – Phroggyy Mar 31 '16 at 06:31
  • I still get the `UserProvider` problem when I add `$this->app->bind(\Illuminate\Contracts\Auth\PasswordBroker::class, \App\Http\Controllers\Auth\MyPasswordBroker::class);` to AppServiceProvider and call `PasswordBroker` in DI of my controller – Kalzem Apr 01 '16 at 05:14
  • Well where is the user provider being used? – Phroggyy Apr 01 '16 at 06:11
  • In the default PasswordBroker which I extend. I have the same code as you wrote. Not using explicitly UserProvider for this service. – Kalzem Apr 01 '16 at 06:12
1

You cannot "extend" an interface. An interface is just a constraint that says any class that inherits an interface will implement a set of functions. See Interfaces and abstract class inheritance, implementation in extended classes for further information.

What you really want is the implements keyword, so

class MyPasswordBroker implements PasswordBroker {
    public function setEmailView($view) {
        $this->emailView = $view;
    }
}

See https://laravel.com/api/5.0/Illuminate/Contracts/Auth/PasswordBroker.html for the list of functions you need to implement.

Community
  • 1
  • 1
wonton
  • 7,568
  • 9
  • 56
  • 93
  • Just like with Phroggyy's answer, I get `Target [Illuminate\Contracts\Auth\UserProvider] is not instantiable.` when I use this implementation :/ – Kalzem Mar 30 '16 at 04:09