Установка и первые шаги с Laravel Backpack

Итак, допустим вы хотите запилить админку или бэк-офис для своего сайта или приложения и всенепременно хотите реализовать свою идею на PHP-фреймворке Laravel. Одним из неплохих решений будет воспользоваться пакетом Backpack для быстрой разработки CRUD приложений. Кстати, у меня уже было несколько обзоров этой админки для Laravel. Но как быть? С чего начать своё знакомство с Backpack?

Вам нравится Laravel? Чтобы использовать Backpack, нужно иметь хорошее представление о структуре Laravel. Backpack помогает Laravel-программистам создавать панели администрирования — защищённые области, в которых администраторы регистрируются и создают, считывают, обновляют и удаляют информацию о приложении. Это не CMS, это больше среда, которая позволяет вам создавать собственную CMS. Вы можете установить его в своём существующем проекте или в совершенно новом проекте.

Backpack  разработан, чтобы быть достаточно гибким, чтобы вы могли создавать панели администратора для всего: от простых презентационных веб-сайтов до CRM, ERP, электронной коммерции, электронного обучения и т. д.

Установка Backpack

Для начала нужно установить сам Laravel или использовать уже имеющееся приложение. Теперь можно перейти к установке пакетов Backpack:

composer require backpack/crud

А затем:

php artisan backpack:base:install
php artisan backpack:crud:install

Во время установки будет задан вопрос с предложением установить дополнительно файловый менеджер.По умолчанию он позволяет пользователям управлять каталогом public/uploads, который можно изменить в файле конфигурации elfinder.php. На этом установка завершена. Всё, можно пользоваться готовой админкой!

Перейдите на страницу /admin/ своего сайта, если вы не авторизованы, то произойдёт редирект на форму авторизации: /admin/login. Если у вас нет аккаунта, то перейдите по ссылке «Register» (/admin/register) в правом верхнем углу.

На данном этапе админка достаточно аскетична. Есть главная страница с сообщением что вы авторизованы, есть раздел с настройками профиля, страница изменения пароля, файловый менеджер (если вы выбрали его во время установки) и кнопка лог-аута. Всё.

Маловато будет!

Как использовать Backpack

Backpack состоит из двух базовых пакетов:

Backpack\Base — обеспечивает дизайн области администрирования на основе AdminLTE
Рюкзак\CRUD — позволяет очень быстро создавать CRUD

CRUD — это то, что мы называем разделом в панели администратора, которая позволяет пользователям создавать, просматривать, обновлять или удалять записи определенного объекта (или модели). Таким образом, вы можете иметь CRUD для продуктов, CRUD для статей, CRUD для категорий или что-то ещё, что вы захотите создать, прочитать, обновить или удалить.

Backpack\Base

Backpack\Base — это пакет, который будет обрабатывать аутентификацию и предоставляет минимальный функционал для администратора. Пользователь сможет войти в систему и изменить свой пароль или адрес электронной почты.

Благодаря Base, после установки Backpack, вы сможете войти в свою панель администратора по адресу http://yourapp/admin. Вы можете изменить префикс URL для админки в файле config/backpack/base.php, а также множество других параметров конфигурации.

Backpack\Base использует бесплатную тему AdminLTE, что позволяет использовать любой элемент входящий в состав AdminLTE. Он также включает систему всплывающих уведомлений, которую вы можете использовать в панели администратора. Вы можете легко отправлять уведомления для пользователя в PHP или JavaScript.

Backpack\CRUD

Как только вы установите Backpack в проект, вы можете создавать CRUD, чтобы легко манипулировать информацией БД. Давайте рассмотрим простой пример создания панели администрирования CRUD для объекта Tag. Для начала создайте и выполните миграцию:

php artisan make:migration:schema create_tags_table --model=0 --schema="name:string:unique"
php artisan migrate

Затем сгенерируйте модель, класс для запроса и контроллер для админки, используйте имя в единственном числе

php artisan backpack:crud tag

Сгенерируйте маршрутизацию routes/backpack/custom.php

php artisan backpack:base:add-custom-route "CRUD::resource('tag', 'TagCrudController');"

Добавьте пункт в меню

php artisan backpack:base:add-sidebar-content "<li><a href='{{ backpack_url('tag') }}'><i class='fa fa-tag'></i> <span>Tags</span></a></li>"

После выполнения этих команд будут сгенерированы:

  • файл миграции
  • модель app\Models\Tag.php
  • request-класс для валидации app\Http\Requests\TagCrudRequest.php
  • контроллер-класс app\Http\Controllers\Admin\TagCrudController.php
  • добавлен маршрут в файл routes/backpack/custom.php

Это создаст простую панель CRUD, которую можно увидеть на боковой панели. Для простой записи, подобной этой, созданная панель CRUD будет работать даже «как есть», нет необходимости в настройках. Но не ожидайте этого для более сложных объектов. Они обычно требуют наличия особенностей и нуждаются в настройке. Вот где Backpack сияет — изменение чего-либо в панели CRUD легко и интуитивно понятно, как только вы поймете, как это работает.

Единственное, что вам нужно, это убедиться, что модель настроена правильно (таблица в БД, отношения, $fillable или $guarded свойства и т. д.) И что она использует CrudTrait. Как видите, в данном случае во время сохранения возникла ошибка, так как в классе модели не указаны поля, которые можно сохранять. Исправим это, отредактировав файл app/Models/Tag.php:

protected $fillable = ['name'];

В TagCrudController находится основная часть логики. Давайте разберём детально этот класс и немного его видоизменим. Начнём с метода setup(), в котором как правило сосредоточена настройка CRUD.

$this->crud->setModel('App\Models\Tag');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/tag');
$this->crud->setEntityNameStrings('tag', 'tags');

Этот фрагмент кода предельно понятен без комментариев. Только не понятно почему это не вынесено в свойства класса.

// TODO: remove setFromDb() and manually define Fields and Columns
$this->crud->setFromDb();

Этот фрагмент конфигурирует набор и свойства полей на основе структуры таблицы в базе данных. Это поведение можно изменить, задав структуру вручную:

$this->crud->setColumns(['name', 'slug']);
      $this->crud->addField([
        'name' => 'name',
        'type' => 'text',
        'label' => "Tag name"
      ]);
      $this->crud->addField([
        'name' => 'slug',
        'type' => 'text',
        'label' => "URL Segment (slug)"
      ]);

Следующий фрагмент также понятен без комментариев:

// VALIDATION: change the requests to match your own file names if you need form validation
use App\Http\Requests\TagRequest as StoreRequest;
use App\Http\Requests\TagRequest as UpdateRequest;
// add asterisk for fields that are required in TagRequest
$this->crud->setRequiredFields(StoreRequest::class, 'create');
$this->crud->setRequiredFields(UpdateRequest::class, 'edit');

Однако, чтобы от этого кода был толк, нужно отредактировать файл app/Http/Requests/TagRequest.php:

public function rules() {
        return [
            'name' => 'required|min:5|max:255'
        ];
    }

Далее идут методы store() и  update(). Можно сделать минималистичный вариант:

public function store(StoreRequest $request) {
    return parent::storeCrud();
  }
  public function update(UpdateRequest $request) {
    return parent::updateCrud();
  }

Либо более детальный:

    public function store(StoreRequest $request) {
        // your additional operations before save here
        $redirect_location = parent::storeCrud($request);
        // your additional operations after save here
        // use $this->data['entry'] or $this->crud->entry
        return $redirect_location;
    }
    public function update(UpdateRequest $request) {
        // your additional operations before save here
        $redirect_location = parent::updateCrud($request);
        // your additional operations after save here
        // use $this->data['entry'] or $this->crud->entry
        return $redirect_location;
    }

Класс TagCrudController использует наследование и расширяет CrudController. Если вы хотите изменить поведение (сохранить, обновить, переупорядочить и т. д.), вы можете легко сделать это, перезаписав соответствующий метод в TagCrudController.

Класс request использует typehinting для методов store() и update(). В случае, если проверка формы не удалась, информация даже не дойдет до этих методов;