Yii2 Bridge

Yii2 Bridge

naffiq



Bridge — это модуль админки, содержащий в себе генераторы кода для CRUD операций (CRUD — это Create, Read, Update, Delete; то есть все, что делает админ с контентом).

Интерфейс админки


Интерфейс написан с помощью Bootstrap 3, тема кастомная, дизайн и верстка — мои.

Вместо того, чтобы выпускать кучу неподдерживаемых модулей, я решил использовать зарекомендовавшие себя в боевых проектах готовые решения, в том числе:

  • Janisto/Environments (GitHub)
  • Yii2Tech/Admin (GitHub, обязателен к ознакомлению)
  • Yii2Tech/Position (GitHub)
  • Yii2Tech/Active Record Soft Delete (GitHub)
  • 2amigos/Usuario (GitHub, обязателен к ознакомлению)
  • 2amigos/GridView (GitHub)
  • MongoSoft/UploadBehavior (GitHub)

На самом деле пакетов под коробкой больше, о них я потихоньку рассказываю на wiki странице проекта.

Начало работы

Чтобы создать новый проект с yii2-bridge, можно воспользоваться стандартной composer командой:

composer create-project naffiq/yii2-app-bridge PROJECT_NAME

И все, проект у вас завелся в своей папке со всеми последними зависимостями. После этого нужно настроить базу данных в папке конфигураций /config/local.php (можно скопировать /config/example.local.php для примера).

Bridge содержит в себе несколько миграций, которые можно запустить одной командой (из папки проекта):

./vendor/bin/bridge-install

После этого ваш проект готов к запуску на орбиту. По ссылке http://localhost:8080/admin теперь должна красоваться такая страница входа:



Однако пользователей в системе еще нет (чтобы не создавать админов с паролями 123456 по умолчанию). Сгенерировать его можно командой:

php yii user/create admin@email.com admin PASSWORD admin

Эта команда кочует в bridge из ususario и имеет довольно простой синтаксис:

  • Первый аргумент — почтовый ящик
  • Второй — логин
  • Ваш пароль
  • И роль пользователя. 

Нам нужен админ, поэтому создаем первого пользователя с ролью admin. Остальные параметры необязательно называть так, поэтому здесь все ок.



После авторизации нам представляется панель администратора с базовым функционалом:



На первой странице пользователь видит состояние админки, ее последнюю версию и краткий список обновлений, который берется напрямую из GitHub API.

Эту страницу можно изменить — достаточно переназначить dashboardAction в модуле админки.

Настройки

Bridge предоставляет систему настроек, которую можно использовать для обертки статичных текстов, номеров и email для обратной связи, изображений и чекбоксов.



Саму настройку можно создать и использовать из любого места в вашем коде. Например, добавим на домашнюю страничку проекта картинки и кастомный текст:

<?php
// @app/views/site/index.php

use naffiq\bridge\models\Settings;

/* @var $this yii\web\View */

$this->title = 'Bridge Tutorial';
?>
<div class="site-index">

    <div class="jumbotron">
        <h1><?= Settings::getOrCreate('main_title', [
                'title' => 'Заголовок на главной',
                'type' => Settings::TYPE_TEXT,
                'value' => 'Привет!'
            ]) ?></h1>

        <?= Settings::getOrCreate('main_text', [
            'title' => 'Текст на главной',
            'type' => Settings::TYPE_TEXT,
            'value' => 'Этот текст выставлен по умолчанию, пожалуйста перебейте меня в админке!'
        ]) ?>
    </div>

    <div class="body-content">

        <div class="row">
            <div class="col-lg-4">
                <h2>Картинка 1</h2>
                <img src="<?= Settings::getOrCreate("main_image_1", [
                    'title' => 'Картинка на главной 1',
                    'type' => Settings::TYPE_IMAGE,
                ]); ?>" alt="" class="img-responsive">
            </div>
            <div class="col-lg-4">
                <h2>Картинка 2</h2>
                <img src="<?= Settings::getOrCreate("main_image_2", [
                    'title' => 'Картинка на главной 2',
                    'type' => Settings::TYPE_IMAGE,
                ]); ?>" alt="" class="img-responsive">
            </div>
            <div class="col-lg-4">
                <h2>Картинка 3</h2>
                <img src="<?= Settings::getOrCreate("main_image_3", [
                    'title' => 'Картинка на главной 3',
                    'type' => Settings::TYPE_IMAGE,
                ]); ?>" alt="" class="img-responsive">
            </div>
        </div>

    </div>
</div>

В коде выше мы заменили стандартную страницу yii2 на свои тексты, которые подгружаются с модуля настроек админки. Можно заметить, что используется функция Settings::getOrCreate, у которой первый аргумент — ключ для использования, а второй — массив со значениями по умолчанию. Сама модель Settings имеет несколько констант, с доступными типами данных настроек. Кол-во типов будет постоянно пополнятся, но они всегда будут вида Settings::TYPE_ANYTHING_HERE. 

Теперь наша главная страница сайта (на фронте) будет выглядеть так:



Путь до картинки с котиком подставляется по умолчанию, если вы еще не успели загрузить свою картинку. К сожалению, пока не получается настроить изображение по умолчанию, однако вы всегда можете подключиться к разработке модуля, или хотя бы создать issue в гитхаб, если вам понадобится эта фича.

Теперь на странице модуля настроек появятся новые данные, которые мы вывели выше:



Если попытаться отредактировать настройку, то вам выйдет необходимое поле, под ваш тип данных.

Для картинок выйдет виджет для загрузки файлов, естественно


Таким образом можно быстро создавать и редактировать данные без особых усилий. В планах добавить красивый интерфейс на страницу со всеми настройками и разделение их по группам (Контакты, Главная и т.д.).


Пользователи

Система предлагает разработчикам готовый модуль от 2amigos — usuario. Документацию о модуле можно прочитать тут.



Если вкратце, то функциональность пакета выходит за рамки стандартного CRUD пользователей:

  • RBAC из под коробки
  • Авторизация/Регистрация
  • Отправка подтверждения и прочих уведомлений по почте
  • Блокировка

Ожидается добавление загрузки аватарки из под коробки и еще плюхи (это можно посмотреть в гитхабе проекта).


Файловый менеджер



Тут в принципе нечего сказать — это обычный файл менеджер (ElFinder). Используется сторонний модуль для подключения его к yii2, который разрешает и запрещает разным ролям доступ к файловому хранилищу.


Генераторы

С встроенным функционалом разобрались. Что еще есть в админке? В админке есть генераторы кода, которые создают нужные behaviors и адаптируют CRUD.

Генерируем модель

Таблицу генерируем этой миграцией (чтобы сэкономить время на написание статьи, не приписал null'ы и комменты к колонкам, простите):

<?php
// @app/migrations/m180216_112042_create_page_table.php

use yii\db\Migration;

/**
 * Handles the creation of table `page`.
 */
class m180216_112042_create_page_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('page', [
            'id' => $this->primaryKey(),
            'title' => $this->string(),
            'text' => $this->text(),
            'image' => $this->string(),
            'position' => $this->integer(),
            'is_deleted' => $this->boolean(),
            'is_something' => $this->boolean(),
        ]);
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('page');
    }
}

После этого заходим в интерфейс Gii и генерируем модель с помощью Bridge Model Generator:



Помимо стандартного кода модели, генератор моделей от Bridge, добавит рекомендованные behaviors, в зависимости от имени колонки (это можно отключить в самом генераторе, или используйте стандартный):

/**
 * @inheritdoc
 */
public function behaviors()
{
    return [
        'imageUpload' => [
            'class' => 'mongosoft\file\UploadImageBehavior',
            'attribute' => 'image',
            'path' => '@webroot/media/page/{id}',
            'url' => '@web/media/page/{id}',
            'scenarios' => ['create', 'update'],
            'thumbs' => ['thumb' => ['width' => 200, 'height' => 200, 'quality' => 90], 'preview' => ['width' => 50, 'height' => 50, 'quality' => 90]],
        ],
        'positionSort' => [
            'class' => 'yii2tech\ar\position\PositionBehavior',
            'positionAttribute' => 'position',
        ],
        'softDeleteBehavior' => [
            'class' => 'yii2tech\ar\softdelete\SoftDeleteBehavior',
            'softDeleteAttributeValues' => ['is_deleted' => 1],
            'invokeDeleteEvents' => false,
        ],
    ];
}

Вот возможные поведения, которые Bridge может сгенерировать:

  • Если колонка кончается на image или _image, то добавится поведение загрузки изображения, с кропом и ресайзом
  • Если колонка кончается на file или _file, то добавится поведение загрузки файлов
  • Если колонка называется postition, то генерируется поведение для сортировки (однако сортировать для вывода на фронте нужно будет самим)
  • Если колонка называется is_deleted, то генерируется поведения для «мягкого удаления»

Поведения будут дополняться. Например сейчас я работаю над поведениям для колонок slug и created_at, updated_at.

Все эти поведения прекрасно отображаются с CRUD интерфейсом, сгенерированным Bridge Crud Generator

Генерируем CRUD

Перед генерацией CRUD, надо выбрать создать модуль, который будет содержать в себе контроллеры и вьюшки админки. Например, я назову модуль CMS (модуль adminуже занят 😀) и сгенерирую его стандартным Gii Module.



Когда вы нажмете на кнопку Generate, вам выведется сообщение об успешном создании модуля и кусок кода, который надо вставить, чтобы он заработал. Однако, вам нужно будет вставить этот код в модуль admin. Ваши настройки модуля должны выглядеть так (/config/main.php):

'modules' => [
    'admin' => [
        'class' => \naffiq\bridge\BridgeModule::class,
        'modules' => [
            'cms' => [
                'class' => 'app\modules\cms\Module',
            ],
        ],
        'userClass' => \app\models\User::class,
        'userSettings' => [
            'class' => \Da\User\Module::className(),
            'administratorPermissionName' => 'admin'
        ]
    ],
],

После этого заходим в Bridge CRUD Generator и в namespace своего контроллера и путь до View не забываем указать модуль cms:



Не забудьте отметить чекбоксы, если у вас они по какой-то причине не активны. После генерации, вам станет доступна страница CRUD по URL https://localhost:8080/admin/cms/page/index



Однако в меню она еще появилась. Для того, чтобы добавить ее туда, нужно добавить в конфиг модуля следующее (над автоматическим либо более простым способом добавления в меню я уже работаю, но это сложно):

'modules' => [
    'admin' => [
        'class' => \naffiq\bridge\BridgeModule::class,
        'modules' => [
            'cms' => [
                'class' => 'app\modules\cms\Module',
            ],
        ],
        'menu' => [
            'Content',
            [
                'title' => 'Pages',
                'url' => ['/admin/cms/page/index'],
                'active' => ['module' => 'cms', 'controller' => 'page'],
                'icon' => 'font'
            ]
        ],
        'userClass' => \app\models\User::class,
        'userSettings' => [
            'class' => \Da\User\Module::className(),
            'administratorPermissionName' => 'admin'
        ]
    ],
],

После этого, в нашем меню появится 2 вещи — разделитель (если указываем просто строку, например Content) и сам пункт меню:

Меню, кстати, сворачивается


Давайте попробуем создать страницу. В форме создания/редактирования автоматически генерируются нужные инпуты:



В планах добавить автоматическое распределение инпутов по колонкам внутри формы, но пока это не главный приоритет, вы можете сами отредактировать _form.php и расставить контент (сами колонки уже генерируются).

Как и в случае модели, инпуты генерируются по названию колонки, но так же важен тип колонки в БД:

  • Если тип колонки — text, то генерируется CKEditor
  • Если в конце названия image или _image — то файловый инпут с превью
  • Для колонок, с is_ в начале — чекбоксы (точнее тоглы)
  • Для колонок, с _at в конце — дэйтпикеры со временем
  • Для колонок, с _date в конце — дейтпикеры, но уже без времени

Список виджетов для инпутов будет пополняться, идеи можете писать в issues. В ближайших планах — выбор локации на карте для колонки latlng.

Я создал 2 странички, и теперь на вкладке всех страниц можно увидеть различные колонки, которые сгенерировал нам Bridge.



Тут правила тоже простые:

  • Если у таблицы есть title и image, то сгенерируется общая колонка с предпросмотром картинки (поиск идет по title)
  • Все колонки типа text обрезаются до 100 символов (в планах просмотр полного текста)
  • Если у таблицы есть поле position, то сгенерируется колонка с кнопками, для сортировки (и возможностью отправить элемент в самое начало)
  • Если колонка начинается на is_, то генерируется ToggleColumn

Стоит еще отметить, что если в таблице есть поле is_deleted, то Bridge так же добавляет вкладку с корзиной на страницу. Удаление элементов будет отправлять контент на эту вкладку, откуда можно будет возвратить элемент.



Если у вас криво отображаются колонки, то теперь у вас есть возможность поменять ее ширину мышкой (не идеально, но работает):



Ширина колонок запоминается браузером.

Виджеты

Пока набор виджетов не богат, но я добавил самый основной (на мой взгляд) — отображение тостов:



Таким образом, любое действие с бекенда можно отобразить пользователю («Письмо отправлено!» и прочее). Вот пример вызова (класс naffiq\bridge\widgets\Toastr):

Toastr::error('Ошибка');
Toastr::warning('Предупреждение');
Toastr::success('Успех');
Toastr::info('Информация');