1
votes

This is my first time using Laravel's Facades and Service Providers (I'm on Laravel 5).

I have this ServiceProvider:

<?php namespace App\Providers;
...
class AccessServiceProvider extends ServiceProvider {
    public function register() {
        $this->app->alias('access', 'App\Services\Permissions\Permissions');
        $this->app->bindShared('access', function() {
            return new Permissions();
        });
        return new App\Services\Permissions\Permissions();
    }

    public function provides(){
        return ['App\Services\Permissions\Permissions'];
    }
}

My Permissions class looks like this:

<?php namespace App\Services\Permissions;
class Permissions{
    private $permissions;
    public function __construct(){
        $this->permissions =  [
            "AssignQuotes" => new CanAssignQuotesPermission()
        ];
    }

    public function hasPermission($permission, $user){
        return $this->permissions[$permission]->canDo($user->role_id);
    }
}

I added this to my aliases in app.php:

'Access' => 'App\Services\Permissions\Access'

I added this to my providers in app.php:

'App\Providers\AccessServiceProvider',

I created this Facade class:

<?php namespace App\Services\Permissions;
use Illuminate\Support\Facades\Facade;

class Access extends Facade {
    protected static function getFacadeAccessor() { return 'access'; }
}

From my understanding, I register an alias, which points to a Facade class which references a binding which points to a class.

I registered the binding in the ServiceProvider which I registered in the app.php.

Now in my routes file I am testing with the following code:

Route::get('test', function(){
    $user = User::find(1);
    $access = Access::hasPermission("AssignQuotes", $user);
    return "test";
}

However I am getting this error:

FatalErrorException in Facade.php line 213:
Call to undefined method App\Services\Permissions\Access::hasPermission()
3
Laravel 5. Sorry for not including that. I've edited my postajon
Try to use get_class in Facade.php line 213 to see what kind of object you have there.bernie
When I use get_class I get: App\Services\Permissions\Access. Should I be getting the other class or the facade class?ajon
The $instance should definitely.be an instance of App\Services\Permissions\Permissions since that's the class with the hasPermission method. The __callStatic intercepts calls to non-existent static methods on the Facade and transfers it to the underlying instance.bernie
@bernie you were right... when I call get_class now that it is working it returns the Permissions class.ajon

3 Answers

1
votes

The only issues I found are :

Remove unnecessary code from your service provider:

<?php namespace App\Providers;
...
class AccessServiceProvider extends ServiceProvider {
    public function register() {
        $this->app->bind('access', 'App\Services\Permissions');
        // OR bindShared() if you need to share a single instance across the app
        $this->app->bindShared('access', function() {
            return new \App\Services\Permissions();
        });
    }

    // No need for a provides() method
}

in providers of app.php :

App\Providers\AccessServiceProvider::class,

in aliases of app.php :

'Access'      => App\Services\Permissions\Access::class,

Maybe something in there will fix it.

1
votes

My serviceProvider class had a few issues. It should be like this:

public function register() {
    $this->app->bind('access', function($app) {
        return new Permissions();
    });
}

I got rid of the extra code including the providers function as per @bernie. I also added the $app parameter to the binding.

The full issue is that the service provider wasn't being bootstrapped (maybe because composer wasn't finding it). If the service provider isn't bootstrapped then the binding won't happen and the facade doesn't work.

0
votes

Could this be the problem? NO

Change from (app.php):

'Access' => 'App\Services\Permissions\Access'

to

'Access' => 'App\Services\Permissions\Permissions'

The error you get

Call to undefined method App\Services\Permissions\Access::hasPermission()

shows that php is trying to call hasPermission on the Access class instead of on the Permissions class which implements that method.