Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create custom Facade in Laravel 4

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.

like image 859
ied3vil Avatar asked Sep 22 '14 16:09

ied3vil


People also ask

What is the facades in Laravel?

In a Laravel application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the Facade class. Laravel's facades, and any custom facades you create, will extend the base Illuminate\Support\Facades\Facade class.

What is facades PHP?

Facade is a structural design pattern that provides a simplified (but limited) interface to a complex system of classes, library or framework. While Facade decreases the overall complexity of the application, it also helps to move unwanted dependencies to one place.

What does Laravel use for seeding & facades?

Laravel includes the ability to seed your database with data using seed classes. All seed classes are stored in the database/seeders directory. By default, a DatabaseSeeder class is defined for you. From this class, you may use the call method to run other seed classes, allowing you to control the seeding order.


2 Answers

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');
        });

    }
}
like image 22
Mahmoud Zalt Avatar answered Sep 20 '22 19:09

Mahmoud Zalt


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.

like image 156
Marcin Nabiałek Avatar answered Sep 18 '22 19:09

Marcin Nabiałek