Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.2 What goes in facade getFacadeAccessor return

So I am trying to create my first ever Service provider and complimentary Facade in Laravel.

Service Provider:

<?php namespace Jbm\Providers;

use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;

use Jbm\Helpers\ReportGenerator;

class ReportGeneratorServiceProvider extends BaseServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('Jbm\Helpers\Contracts\ReportGeneratorContract', function($app){
            return new ReportGenerator();
        });
    }

    /**
     * Add the Cors middleware to the router.
     *
     * @param Kernel $kernel
     */
    public function boot(Request $request, Kernel $kernel)
    {
        //
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return array('jbm.reportGenerator');
    }

}

Facade:

<?php

namespace Jbm\Facades;

use Illuminate\Support\Facades\Facade;

class ReportGenerator extends Facade 
{
    protected static function getFacadeAccessor() 
    { 
        return 'jbm.reportGenerator'; 
    }
}

It seems that every package I look at handles things different ways. One thing I am confused about is what is supposed to go in the return of getFacadeAccessor() in the Facade. In my service provider I say it provides jbm.reportGenerator and then use that in the Facade but I don't know how that connects to what I've registered. Any help would be greatly appreciated.

Update:

I decided to add my service provider and my facade to my config/app.php and then tried to use it in a controller and it says "Report Generator not found". So it obviously isn't working...no idea why

Update 2:

After removing the dot in the name I am now getting Call to undefined method Jbm\Facades\ReportGenerator::parseConfig().

like image 408
Bill Garrison Avatar asked Mar 05 '16 02:03

Bill Garrison


2 Answers

First, your service provider should be in the App\Providers namespace, and should extend ServiceProvider. So it will look like this:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Jbm\Helpers\ReportGenerator;

class ReportGeneratorServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('Jbm\Helpers\Contracts\ReportGeneratorContract', function($app){
            return new ReportGenerator();
        });
    }    
}

After that, the facade should be in the App\Facades namespace, and the getFacadeAccessor() method should return the class name of your service provider:

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class ReportGenerator extends Facade 
{
    protected static function getFacadeAccessor() 
    { 
        return App\Providers\ReportGeneratorServiceProvider::class;
    }
}

Now, let's add the service provider and facade to the app:

// config/app.php

'providers' => [
    App\Providers\ReportGeneratorServiceProvider::class,
]

'aliases' => [
    'ReportGenerator' => App\Facades\ReportGenerator::class,
]
like image 143
dotancohen Avatar answered Oct 17 '22 07:10

dotancohen


getFacadeAccessor should return a string that your container "knows about". That means something that is registered via a Provider.

You add your facade and an alias to app.php to be able to access something your registered statically.

So when you call YourFacadeAlias::doSomething(); laravel detects YourFacaseAlias, sees what is returned from getFacadeAccessor and uses that result to return an object associated with it from container.

Since both your facade and helper are called "ReportGenerator" the problem might be with both of them. But I think you should first check your app.php to see if you set it right. And then make sure your getFacadeAccessor and binded values match.

like image 31
MaGnetas Avatar answered Oct 17 '22 09:10

MaGnetas