6
votes

Looked up a few tutorials on facades and laravel 4... tried some... not liked the way they work.

For instance, they don't all provide a way of defining where to store the facade files and service providers... and i tried to step away from that and got my head bumped into a few walls until i decided to do this thread.

So: Let's say i have an app called Laracms (laravel cms).

I'd like to store everything i create - facades, service providers, etc in a folder under app named laracms.

So i'd have /app/laracms/facades, /app/laracms/serviceproviders and so on. I don't want to mix the facades with the database models, i want to keep things as separate as possible.

Let's take now, in my case, the Settings name for the facade (i want to implement a settings class to use in views and admin to set up misc. stuff).

Settings::get(), Settings::set() as methods.

Can anyone explain how to set facades up correctly? I don't know what i'm doing wrong and i need a fresh start.

Thanks, Chris

Looking for a step by step with simple explanations of how and why.

2

2 Answers

13
votes

First you need to go to app/config/app.php and in providers section add:

'Laracms\Providers\SettingsServiceProvider',

In the same file in aliases section you should add:

 'Settings' => 'Laracms\Facades\Settings',

In your app/Laracms/Providers you should create file SettingsServiceProvider.php

<?php

namespace Laracms\Providers;

use Illuminate\Support\ServiceProvider;

class SettingsServiceProvider extends ServiceProvider {

    public function register()
    {
        $this->app->bind('settings', function()
            {
                return new \Laracms\Settings();
            });
    }

}

In your app/Laracms/Facades/ you should create file Settings.php:

<?php

namespace Laracms\Facades;

use Illuminate\Support\Facades\Facade;

class Settings extends Facade {

    protected static function getFacadeAccessor() { return 'settings'; }

}

Now in your app/Laracms directory you should create file Settings.php:

<?php

namespace Laracms;

class Settings {
   public function get() {echo "get"; }

   public function set() {echo "set"; }
}

As you wanted to have your files in custom folder Laracms you need to add this folder to your composer.json (If you used standard app/models folder you wouldn't need to add anything to this file). So now open composer.json file and in section autoload -> classmap you should add app/Laracms so this section of composer.json could look like this:

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php",
        "app/Laracms"
    ]
},

Now you need to run in your console inside your project foler:

composer dump-autoload

to create class map

If everything is fine, you should now be able to use in your applications Settings::get() and Settings:set()

You need to notice that I used folders with uppercases because namespaces by convention starts with upper letters.

2
votes

There are three components to making a Facade:

  • The wanna be Facade Class, that class that needs to become a facade.
  • The Facade required Class, which tells Laravel which registered class it pertains to
  • A Service Provider, which registers the Facade class in the App container

1. the wanna be Facade Class:

<?php namespace Moubarmij\Services\ModelsServices;

class AuthenticationService extends MoubarmijService implements AuthenticationServiceInterface{


    /**
     * @param $email
     * @param $password
     *
     * @return mixed
     */
    public function login($email, $password)
    {
        return Sentry::authenticate([
            'email'    => $email,
            'password' => $password,
        ]);
    }

    /**
     * @return mixed
     */
    public function logout()
    {
        return Sentry::logout();
    }

}

2. the required class for the facade to work:

<?php namespace Moubarmij\Facades;


use Illuminate\Support\Facades\Facade;

/**
 * Class AuthenticationServiceFacade
 * @package Moubarmij\Services\ModelsServices
 */
class AuthenticationServiceFacade extends Facade{

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'authentication_service'; }


}

note: authentication_service can be anything you want (its the name of the component registered in the IOC)

3. the service provider

<?php namespace Moubarmij\Providers;


use Illuminate\Support\ServiceProvider;

/**
 *  A service provider for the Authentication Service
 *
 * Class AuthenticationServiceSP
 * @package Moubarmij\Providers
 */
class AuthenticationServiceSP extends ServiceProvider {

    /**
     * bind interfaces
     *
     * @return void
     */
    public function register()
    {
        // Register 'authentication_service' instance container to our AuthenticationService object
        $this->app['authentication_service'] = $this->app->share(function($app)
        {
            return $app->make('Moubarmij\Services\ModelsServices\AuthenticationService');
        });

        // Shortcut to auto add the Alias in app/config/app.php
        $this->app->booting(function()
        {
            $loader = \Illuminate\Foundation\AliasLoader::getInstance();
            $loader->alias('AuthenticationService', 'Moubarmij\Facades\AuthenticationServiceFacade');
        });

    }
}