PHPackages                             distilleries/expendable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. distilleries/expendable

ActiveLibrary[Framework](/categories/framework)

distilleries/expendable
=======================

Expendable is an admin panel base on laravel 5.\*. This package give you some implementation do add a content management system of your application. You can override everything. This Cms give view few tools to develop your content management easily and properly.

2.24.1(6y ago)298.8k82MITCSSPHP &gt;=7.1.3

Since Feb 12Pushed 6y ago7 watchersCompare

[ Source](https://github.com/Distilleries/Expendable)[ Packagist](https://packagist.org/packages/distilleries/expendable)[ RSS](/packages/distilleries-expendable/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (15)Versions (116)Used By (2)

[![Scrutinizer Code Quality](https://camo.githubusercontent.com/2aed6eb32d6286d10136245254839deaa541964bc915cb4a50e34c53cb3e9cef/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f44697374696c6c65726965732f457870656e6461626c652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/Distilleries/Expendable/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/d166ad37d26fc9296718ac63e201c6d02af79c9ff818c64f9ca8c931e7d08ff7/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f44697374696c6c65726965732f457870656e6461626c652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/Distilleries/Expendable/?branch=master)[![Build Status](https://camo.githubusercontent.com/03d04f309b37cc1f831dad98966bc5f25c04af5365539b1db23a551f2d421062/68747470733a2f2f7472617669732d63692e6f72672f44697374696c6c65726965732f457870656e6461626c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/Distilleries/Expendable)[![Total Downloads](https://camo.githubusercontent.com/ef0b0962feae64105b00fc2496c65fbf7874baa7fb98ca0ffba397b92fcf5be5/68747470733a2f2f706f7365722e707567782e6f72672f64697374696c6c65726965732f657870656e6461626c652f646f776e6c6f616473)](https://packagist.org/packages/distilleries/expendable)[![Latest Stable Version](https://camo.githubusercontent.com/e4fad3be69315257282ff9d94d6d6dda4d013fdbf47d820193609f20fefad637/68747470733a2f2f706f7365722e707567782e6f72672f64697374696c6c65726965732f657870656e6461626c652f76657273696f6e)](https://packagist.org/packages/distilleries/expendable)[![License](https://camo.githubusercontent.com/f251623e510f5909f16ae3f4e6e548dac11340b9fde1a99be26b015b39272c00/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c6174)](LICENSE.md)

Expendable
==========

[](#expendable)

Expendable is an admin panel base on laravel 5.6.\* This package give you some implementation do add a content management system of your application. You can override everything. This Cms give view few tools to develop your content management easily and properly.

Table of contents
-----------------

[](#table-of-contents)

1. [Require](#require)
2. [Installation](#installation)
3. [Configurations](#configurations)
4. [Menu](#menu)
5. [State](#state)
    1. [Datatable](#1-datatable)
    2. [Order](#2-order)
    3. [Export](#3-export)
    4. [Import](#4-import)
    5. [Form](#5-form)
6. [Component](#component)
    1. [Admin BaseComponent](#admin-basecomponent)
    2. [Admin ModelBaseController](#admin-modelbasecontroller)
    3. [AdminBaseController](#admin-basecontroller)
7. [Model](#model)
8. [Global scope](#global-scope)
    1. [Status](#status)
9. [Permissions](#permissions)
10. [Views](#views)
11. [Assets (CSS and Javascript)](#assets-css-and-javascript)
    1. [Sass](#sass)
    2. [Images](#images)
    3. [Javascript](#javascript)
    4. [Gulp](#gulp)
12. [Create a new backend module](#create-a-new-backend-module)
13. [Case studies](#case-studies)
    1. [Generate your migration](#1-generate-your-migration)
    2. [Generate your model](#2-generate-your-model)
    3. [Generate you component](#3-generate-you-component)
    4. [Add your controller in the routes file](#4-add-your-controller-in-the-routes-file)
    5. [Add to the menu](#5-add-to-the-menu)

Require
-------

[](#require)

To use this project you have to install:

1. Php 7.1.3 or more
2. Active mpcrypt
3. Composer
4. Sass (`gem install sass`)
5. NodeJs version v9.4.0

Installation
------------

[](#installation)

Add on your composer.json

```
    "require": {
        "distilleries/expendable": "2.*",
    }
```

run `composer update`.

Add Application override to `bootstrap/app.php`:

```
$app = new \Distilleries\Expendable\Fondation\Application(
    realpath(__DIR__ . '/../')
);

$app->bind('path.storage', function ($app) {
    $path = env('STORAGE_PATH', base_path() . DIRECTORY_SEPARATOR . 'storage');

    return $path;
});
```

I add a bind event to override the storage path. If you want overrid it juste add `STORAGE_PATH=` on your .env. If you don't want override it juste to put it on your .env.

Add Service provider to `config/app.php`:

```
    'providers' => [

        /*
         * Package Service Providers...
         */
        Laravel\Tinker\TinkerServiceProvider::class,
        Distilleries\FormBuilder\FormBuilderServiceProvider::class,
        Distilleries\DatatableBuilder\DatatableBuilderServiceProvider::class,
        Distilleries\PermissionUtil\PermissionUtilServiceProvider::class,
        Maatwebsite\Excel\ExcelServiceProvider::class,
        Distilleries\Expendable\ExpendableServiceProvider::class,
        Distilleries\Expendable\ExpendableRouteServiceProvider::class,

    ]
```

And Facade (also in `config/app.php`) replace the laravel facade `Mail`

```
    'aliases' => [
        /**
         * Vendor facade
         *
         */

     'FormBuilder'    => \Distilleries\FormBuilder\Facades\FormBuilder::class,
     'Form'           => Collective\Html\FormFacade::class,
     'HTML'           => Collective\Html\HtmlFacade::class,
     'Datatable'      => \Distilleries\DatatableBuilder\Facades\DatatableBuilder::class,
     'PermissionUtil' => \Distilleries\PermissionUtil\Facades\PermissionUtil::class,
     'Excel'          => \Maatwebsite\Excel\Facades\Excel::class,
    ]
```

**Replace the service old facade Mail by the new one.**

Publish the configuration:

```
php artisan vendor:publish --provider="Distilleries\Expendable\ExpendableServiceProvider"

```

Configurations
--------------

[](#configurations)

```
    return [
        'login_uri'           => 'admin/login',
        'logout_action'       => 'Distilleries\Expendable\Http\Controllers\Admin\LoginController@getLogout',
        'admin_base_uri'      => 'admin',
        'config_file_assets'  => base_path().'/package.json',
        'folder_whitelist'    => [
            'moximanager'
        ],
        'listener'            => [
            '\Distilleries\Expendable\Listeners\UserListener'
        ],
        'mail'                => [
            'actions' => [
                'emails.password'
            ]
        ],
        'menu'                => \Distilleries\Expendable\Config\MenuConfig::menu([], 'beginning'),
        'menu_left_collapsed' => false,
        'state'               => [
            'Distilleries\DatatableBuilder\Contracts\DatatableStateContract' => [
               'color'    => 'bg-green-haze',
               'icon'     => 'th-list',
               'libelle'  => 'expendable::menu.datatable',
               'position' => 0,
               'action'   => 'getIndex'
           ],
           'Distilleries\Expendable\Contracts\OrderStateContract'           => [
               'color'    => 'bg-grey-cascade',
               'icon'     => 'resize-vertical',
               'libelle'  => 'expendable::menu.order_state',
               'position' => 1,
               'action'   => 'getOrder'
           ],
           'Distilleries\Expendable\Contracts\ExportStateContract'          => [
               'color'    => 'bg-blue-hoki',
               'icon'     => 'save-file',
               'libelle'  => 'expendable::menu.export',
               'position' => 2,
               'action'   => 'getExport'
           ],
           'Distilleries\Expendable\Contracts\ImportStateContract'          => [
               'color'    => 'bg-red-sunglo',
               'icon'     => 'open-file',
               'libelle'  => 'expendable::menu.import',
               'position' => 3,
               'action'   => 'getImport'
           ],
           'Distilleries\FormBuilder\Contracts\FormStateContract'           => [
               'color'    => 'bg-yellow',
               'icon'     => 'pencil',
               'libelle'  => 'expendable::menu.add_state',
               'position' => 4,
               'action'   => 'getEdit'
           ],
        ]
    ];
```

FieldUsagelogin\_uriUri to access of the login page by default `admin/login`.admin\_base\_uribase of the admin uri `admin` by default.config\_file\_assetsFile loaded to get the version number of the application. This version number is use to add it of the generated css and javascript to force the reload when you deploy your application.folder\_whitelistTable of folders accessible to display the assets.listenerTable of class autoloaded to listen a custom event.mail.actionsList of action available to send an email. This list is display in email module backend.menuUse the method \\Distilleries\\Expendable\\Config\\MenuConfig::menu() to merge the default menu with your menu. In the table you can define left key or tasks to display in menu left or in the menu task.menu\_left\_collapsedSet to tru to keep close the menu left. By default it set to false and the menu is open.stateList of state available, with the color, the logo and the name.### Menu

[](#menu)

I use a function to easily merge the default component with the component of the application.

By default you can find on the menu left:

1. Email
    1. List of email
    2. Add email
2. User
    1. List of user
    2. Add user
3. Role
    1. List of role
    2. Add role
4. Permission
    1. Associate permission
    2. List of service
    3. Add service
    4. Synchronize all services
5. Language
    1. List of language
    2. Add language

By default you can find on the menu task:

1. Generate a new component
2. Synchronize all services

To add a new item it's easy

```
        'menu' => \Distilleries\Expendable\Config\MenuConfig::menu([
                'left' => [
                    [
                        'icon'    => 'send',
                        'action'  => 'Admin\ContactController@getIndex',
                        'libelle' => 'Contact',
                        'submenu' => [
                            [
                                'icon'    => 'th-list',
                                'libelle' => 'List of Contact',
                                'action'  => 'Admin\ContactController@getIndex',
                            ],
                            [
                                'icon'    => 'pencil',
                                'libelle' => 'Add Contact',
                                'action'  => 'Admin\ContactController@getEdit',
                            ]
                        ]
                    ],
                ],

                'tasks' => [
                    [
                        'icon'    => 'console',
                        'action'  => 'Admin\TestController@getIndex',
                        'libelle' => 'Test',

                    ],
                ]
            ], 'beginning'),
```

OptionDescriptioniconName of the icon class actionAction call when you click ( use action helper to generate the url)libelleTranslation of your menu itemsubmenuIf you want add sub-item you can add an array with the same optionsThe method `\Distilleries\Expendable\Config\MenuConfig::menu` tak two parameters

1. An array with the content of the meny `['left'=>[],'tasks'=>[]]`
2. The second one is a string `beginning` or `end` to define the direction of the merge.

Example of menu left:

[![menu_left](https://camo.githubusercontent.com/b894250cc15d62da54e34f37fcb57eec5301a30a3fd3bceb3c5f164caf7ccfed/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f6d656e755f6c6566742e706e67)](https://camo.githubusercontent.com/b894250cc15d62da54e34f37fcb57eec5301a30a3fd3bceb3c5f164caf7ccfed/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f6d656e755f6c6566742e706e67)

Example of menu task:

[![tasks](https://camo.githubusercontent.com/bdb951b1c025e4412281354cea3a95e6d4627623839040535442f22f7678dad3/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f7461736b732e706e67)](https://camo.githubusercontent.com/bdb951b1c025e4412281354cea3a95e6d4627623839040535442f22f7678dad3/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f7461736b732e706e67)

### State

[](#state)

A state is a part of your controller where you define a list of actions. By default I implemented four states:

1. Datatable
2. Order
3. Export
4. Import
5. Form

To display the menu of state I provide a class for the interface `Distilleries\Expendable\Contracts\StateDisplayerContract`.

```
 	$this->app->singleton('Distilleries\Expendable\Contracts\StateDisplayerContract', function ($app)
    {
        return new StateDisplayer($app['view'],$app['config']);
    });
```

This class check the interface use on your controller and with the config `exependable::state` display the logo and the name of the state. If you want change the state display, just provide a new class for the contract `Distilleries\Expendable\Contracts\StateDisplayerContract`.

To display all the element I use a layout manager. you can override it to display what you want.

```
 	  $this->app->singleton('Distilleries\Expendable\Contracts\LayoutManagerContract', function ($app)
    {
        return new LayoutManager($app['config']->get('expendable'), $app['view'], $app['files'], app('Distilleries\Expendable\Contracts\StateDisplayerContract'));
    });
```

#### 1. Datatable

[](#1-datatable)

[![datatable](https://camo.githubusercontent.com/52df628cb5f3745188781858f735ac64c68390a8a28eb110434fea217917e3d5/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f7374617465732e706e67)](https://camo.githubusercontent.com/52df628cb5f3745188781858f735ac64c68390a8a28eb110434fea217917e3d5/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f7374617465732e706e67)

A datatable state it's use to display a list of content with filter if you need it. To use it you have to implement the interface `Distilleries\DatatableBuilder\Contracts\DatatableStateContract`.

```
  public function getIndexDatatable();
  public function getDatatable();
```

- `getIndexDatatable` it's form initilize the datatable.
- `getDatatable` it's for get the data in json.

You can use the trait :

```
use \Distilleries\Expendable\States\DatatableStateTrait;
```

On this trait you have a generic implementation to display the datatable and the data. This trait need to use two attributes of your controller:

1. `$datatable`, it's an instance of `EloquentDatatable` (come from [DatatableBuilder](https://github.com/Distilleries/DatatableBuilder)).
2. `model`, it's and instance of `Model` (come from laravel).

Inject them on your constructor:

```
    public function __construct(\Address $model, AddressDatatable $datatable)
    {
        $this->datatable  = $datatable;
        $this->model      = $model;
    }
```

#### 2. Order

[](#2-order)

Add basic order feature to a component .

Handle Controller
-----------------

[](#handle-controller)

- must implements `\Distilleries\Expendable\Contracts\OrderStateContract`
- methods are implemented in `\Distilleries\Expendable\States\OrderStateTrait`

Handle Model
------------

[](#handle-model)

- must implements `\Distilleries\Expendable\Contracts\OrderContract`

### Methods

[](#methods)

- `orderLabel()` must return a string displayed in order page (by using model attributes)
- `orderFieldName()` must return the name of the field where the model persist the order

#### 3. Export

[](#3-export)

[![export](https://camo.githubusercontent.com/aacbdd046046bf5c5955cf53daa2e0c889f98b99473767a665e8f5eebb8f0a65/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f6578706f72742e706e67)](https://camo.githubusercontent.com/aacbdd046046bf5c5955cf53daa2e0c889f98b99473767a665e8f5eebb8f0a65/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f6578706f72742e706e67)

An export state it's to export the data from your model between two dates. To use it you have to implement the interface `Distilleries\Expendable\Contracts\ExportStateContract`.

```
     public function getExport();
     public function postExport();
```

- `getExport` it's to display the form to select the dates and the type of export.
- `postExport` proceed the export and return the file.

You can use the trait :

```
use \Distilleries\Expendable\States\ExportStateTrait;
```

On this trait you have a generic implementation to export your data. This trait need to use on attribute of your controller:

1. `model`, it's and instance of `Eloquant` (come from laravel).

Inject them on your constructor:

```
    public function __construct(\Address $model)
    {
        $this->model      = $model;
    }
```

You can change the class provide to export the data. Just add those methods on your service provider and change the class instantiated.

```
    $this->app->singleton('Distilleries\Expendable\Contracts\CsvExporterContract', function ($app)
    {
        return new CsvExporter;
    });
    $this->app->singleton('Distilleries\Expendable\Contracts\ExcelExporterContract', function ($app)
    {
        return new ExcelExporter;
    });
    $this->app->singleton('Distilleries\Expendable\Contracts\PdfExporterContract', function ($app)
    {
        return new PdfExporter;
    });
```

#### 4. Import

[](#4-import)

[![import](https://camo.githubusercontent.com/2152a52113e6b72cbed72a29442c59c05841a350a946169a719c5a6188c59b88/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f696d706f72742e706e67)](https://camo.githubusercontent.com/2152a52113e6b72cbed72a29442c59c05841a350a946169a719c5a6188c59b88/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f696d706f72742e706e67)

An import state it's to import the data from a file to your model. To use it you have to implement the interface `Distilleries\Expendable\Contracts\ImportStateContract`.

```
     public function getImport();
     public function postImport();
```

- `getImport` it's to display the form give the file.
- `postImport` proceed the import and return back.

You can use the trait :

```
use \Distilleries\Expendable\States\ImportStateTrait;
```

On this trait you have a generic implementation to export your data. This trait need to use on attribute of your controller:

1. `model`, it's and instance of `Eloquant` (come from laravel).

Inject them on your constructor:

```
    public function __construct(\Address $model)
    {
        $this->model      = $model;
    }
```

You can change the class provide to import the data. Just add those methods on your service provider and change the class instantiated.

```
    $this->app->singleton('CsvImporterContract', function ($app)
    {
        return new CsvImporter;
    });

    $this->app->singleton('XlsImporterContract', function ($app)
    {
        return new XlsImporter;
    });

    $this->app->singleton('XlsxImporterContract', function ($app)
    {
        return new XlsImporter;
    });
```

#### 5. Form

[](#5-form)

[![form](https://camo.githubusercontent.com/0d9af2267a4a5ecd5ae86115d24b8eb628c95fc1a2c16a130d2c1717e09963ad/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f666f726d2e706e67)](https://camo.githubusercontent.com/0d9af2267a4a5ecd5ae86115d24b8eb628c95fc1a2c16a130d2c1717e09963ad/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f666f726d2e706e67)

The form state give you a part to add or edit an element and a part to view the element without edit.

To use it you have to implement the interface `Distilleries\FormBuilder\Contracts\FormStateContract`.

```
    public function getEdit($id);
    public function postEdit();
    public function getView($id);
```

- `getEdit` it's to display the form to edit or add new item.
- `postEdit` proceed the save or update.
- `getView` Display the form in not editable.

You can use the trait :

```
use \Distilleries\Expendable\States\FormStateTrait;
```

On this trait you have a generic implementation to display form, save and display view. This trait need to use two attributes of your controller:

1. `model`, it's and instance of `Eloquant` (come from laravel).
2. `form`, it's and instance of `Form` (come from [FormBuilder](https://github.com/Distilleries/FormBuilder)).

Inject them on your constructor:

```
     public function __construct(\Address $model, AddressForm $form)
    {
        $this->form      = $form;
        $this->model     = $model;
    }
```

Component
---------

[](#component)

A component is just a composition of controller, form, datatable, model. To create a new component you can go in `/admin/component/edit` and fill the form, or use the command line:

```
php artisan expendable:component.make app/controllers/Admin/TestController

```

You can check the options with the help.

In the backend you have all this options:

FieldDescriptionNameThe name use to generate the controllers and other classes (ex: Address, AddressController, AddressForm, AddressDatatable).StateThe state you want use on your controllerModelThe model inject on your controllerColumnsList of columns display on the datatableFieldsThe field you want in your form (name:type ex: id:hidden, libelle:text...)To know all the types of fields you can [have look the documentation](https://github.com/Distilleries/FormBuilder#list-of-fields).

[![component](https://camo.githubusercontent.com/177b24edfc353213d60ab00e8edc2bc52375b73dc6bfda29b26bf9dce97c5bc3/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f636f6d706f6e656e742e706e67)](https://camo.githubusercontent.com/177b24edfc353213d60ab00e8edc2bc52375b73dc6bfda29b26bf9dce97c5bc3/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f636f6d706f6e656e742e706e67)

### Admin BaseComponent

[](#admin-basecomponent)

By default if you check all the state that generate a controller inheritance from `Distilleries\Expendable\Http\Controllers\Admin\Base\BaseComponent`. This controller implement all the states interfaces.

```
    use Distilleries\DatatableBuilder\Contracts\DatatableStateContract;
    use Distilleries\Expendable\Contracts\ExportStateContract;
    use Distilleries\Expendable\Contracts\ImportStateContract;
    use Distilleries\Expendable\States\DatatableStateTrait;
    use Distilleries\Expendable\States\ExportStateTrait;
    use Distilleries\Expendable\States\FormStateTrait;
    use Distilleries\Expendable\States\ImportStateTrait;
    use Distilleries\FormBuilder\Contracts\FormStateContract;

    class BaseComponent extends ModelBaseController implements FormStateContract, DatatableStateContract, ExportStateContract, ImportStateContract {

        use FormStateTrait;
        use ExportStateTrait;
        use DatatableStateTrait;
        use ImportStateTrait;

        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------

        public function getIndex()
        {
            return $this->getIndexDatatable();
        }
    }
```

### Admin ModelBaseController

[](#admin-modelbasecontroller)

If you don't want use all the state and you use a model just extend `Distilleries\Expendable\Http\Controllers\Admin\Base\ModelBaseController`.

Example:

```
    use Distilleries\Expendable\Contracts\LayoutManagerContract;
    use Distilleries\Expendable\Models\BaseModel;
    use Illuminate\Http\Request;

    class ModelBaseController extends BaseController {

        /**
         * @var \Distilleries\Expendable\Models\BaseModel $model
         * Injected by the constructor
         */
        protected $model;

        // ------------------------------------------------------------------------------------------------

        public function __construct(BaseModel $model, LayoutManagerContract $layoutManager)
        {
            parent::__construct($layoutManager);
            $this->model = $model;
        }

        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------

        public function putDestroy(Request $request)
        {
            $validation = \Validator::make($request->all(), [
                'id' => 'required'
            ]);
            if ($validation->fails())
            {
                return redirect()->back()->withErrors($validation)->withInput($request->all());
            }

            $data = $this->model->find($request->get('id'));
            $data->delete();

            return redirect()->to(action('\\'.get_class($this) . '@getIndex'));
        }
    }
```

### Admin BaseController

[](#admin-basecontroller)

If you don't want use all the state and you don't use a model just extend `Distilleries\Expendable\Http\Controllers\Admin\Base\BaseController`. You just have to inject the `LayoutManagerContract`

Example:

```
    use Distilleries\Expendable\Contracts\LayoutManagerContract;
    use Distilleries\Expendable\Http\Controllers\Controller;

    class BaseController extends Controller {

        protected $layoutManager;

        protected $layout = 'expendable::admin.layout.default';

        // ------------------------------------------------------------------------------------------------

        public function __construct(LayoutManagerContract $layoutManager)
        {
            $this->layoutManager = $layoutManager;
            $this->setupLayout();
        }

        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------

        protected function setupLayout()
        {
            $this->layoutManager->setupLayout($this->layout);
            $this->setupStateProvider();
            $this->initStaticPart();

        }

        // ------------------------------------------------------------------------------------------------

        protected function setupStateProvider()
        {
            $interfaces = class_implements($this);
            $this->layoutManager->initInterfaces($interfaces, get_class($this));

        }

        // ------------------------------------------------------------------------------------------------

        protected function initStaticPart()
        {
            $this->layoutManager->initStaticPart(function ($layoutManager)
            {

                $menu_top  = $layoutManager->getView()->make('expendable::admin.menu.top');
                $menu_left = $layoutManager->getView()->make('expendable::admin.menu.left');

                $layoutManager->add([
                    'state.menu' => $layoutManager->getState()->getRenderStateMenu(),
                    'menu_top'   => $menu_top,
                    'menu_left'  => $menu_left
                ]);
            });
        }
    }
```

Model
-----

[](#model)

By default you can extend `\Distilleries\Expendable\Models\BaseModel`, this one extend `\Illuminate\Database\Eloquent\Model`. On it you have some method you can use:

```
    public static function getChoice();
    public function scopeSearch($query, $searchQuery);
    public function getAllColumnsNames();
    public function scopeBetweenCreate($query, $start, $end);
    public function scopeBetweenupdate($query, $start, $end);
```

MethodDetailgetChoiceReturn a table with in key the id and the value the libellescopeSearchQuery scope to search in all columnsgetAllColumnsNamesGet all the columns of your tablescopeBetweenCreateQuery scope to get all the element between to date by the field created\_atscopeBetweenupdateQuery scope to get all the element between to date by the field created\_atGlobal scope
------------

[](#global-scope)

I provide some global scope usable on the model.

### Status

[](#status)

If you want display an element only if your are connected use this scope. The model check if the user is not connected and if the status equal online (1).

To use it add the trait on your model `use \Distilleries\Expendable\Models\StatusTrait;`

Permissions
-----------

[](#permissions)

The system of permission is base on the public method of all your controller. To generate the list of all services use the `Synchronize all services` (`/admin/service/synchronize`). That use all the controller and get the public actions.

If you go on `Associate Permission` you have the list of controller with all methods:

[![services](https://camo.githubusercontent.com/84bd4edd0359c3e370436226456238134a0a759a60f27bcbef420ac67a4ebda4/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f73657276696365732e706e67)](https://camo.githubusercontent.com/84bd4edd0359c3e370436226456238134a0a759a60f27bcbef420ac67a4ebda4/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f73657276696365732e706e67)

On this page you can allow a role to the method. By default Expendable use `Distilleries\PermissionUtil` package and add the good middleware in his kernel. You don't have to configure something. If the role is not allowed the application dispatch an error 403:

```
    if(!PermissionUtil::hasAccess('Controller@action')){
        App::abort(403, Lang::get('expendable::errors.unthorized'));
    }
```

Views
-----

[](#views)

To override the view publish them with command line:

```
php artisan vendor:publish --provider="Distilleries\Expendable\ExpendableServiceProvider"  --tag="views"

```

Assets (CSS and Javascript)
---------------------------

[](#assets-css-and-javascript)

All the assets are one the folder `resources/assets`.

### Sass

[](#sass)

To use the sass file just add bootstrap and `application.admin.scss` on your admin file scss. If you check the repo [Xyz](https://github.com/Distilleries/Xyz/tree/master/resources/assets) you have a folder assets. I use the same structure.

```
   //
   // Third-parties
   //

   @import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
   @import "../../../../node_modules/font-awesome/scss/font-awesome";

   //
   // Expendable
   //

   @import "../../../../vendor/distilleries/expendable/src/resources/assets/backend/sass/application.admin";
   @import "../../../../vendor/distilleries/expendable/src/resources/assets/backend/sass/admin/layout/themes/grey";
```

### Images

[](#images)

The images are copy by mix script when they are found in sass file

### Javascript

[](#javascript)

The javascript is compiled by the mix

### Composer

[](#composer)

I update my composer json to add the npm install and gulp generation when I update my libraries.

```
    "post-update-cmd": [
      "php artisan clear-compiled",
      "php artisan optimize",
      "php artisan down",
      "npm install",
      "php artisan migrate --force",
      "npm run production",
      "php artisan up"
    ],
```

Create a new backend module
---------------------------

[](#create-a-new-backend-module)

1. Generate your migration.
2. Generate your model.
3. Generate you component.
4. Add your controller in the routes file.

Case studies
------------

[](#case-studies)

Try to create a blog post component. I use a fresh install of [Xyz](https://github.com/Distilleries/Xyz)

### 1. Generate your migration

[](#1-generate-your-migration)

```
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('posts', function(Blueprint $table)
		{
			$table->increments('id');
			$table->string('libelle');
			$table->text('content')->nullable();
			$table->tinyInteger('status');
			$table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('posts');
	}

}
```

```
php artisan migrate

```

### 2. Generate your model

[](#2-generate-your-model)

```
    use Distilleries\Expendable\Models\BaseModel;

    class Post extends BaseModel {

        use \Distilleries\Expendable\Models\StatusTrait;

        protected $fillable = [
            'id',
            'libelle',
            'content',
            'status',
        ];
    }
```

### 3 Generate you component

[](#3-generate-you-component)

I use the backend generator `/admin/component/edit`.

[![studies](https://camo.githubusercontent.com/e9a1f99e55d2abe050fc18f7a58be89122002c81f320186cb9d48636d31de24c/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f737475646965732e706e67)](https://camo.githubusercontent.com/e9a1f99e55d2abe050fc18f7a58be89122002c81f320186cb9d48636d31de24c/687474703a2f2f64697374696c6c6572692e65732f6d61726b646f776e2f657870656e6461626c652f5f696d616765732f737475646965732e706e67)

Datatable:

```
