Search code examples
laravel-5service-providerlaravel-facade

Laravel Facade and Service Provider


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()

Solution

  • 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.