Научимся расширять сторонние плагины в OctoberCMS: контроллеры, модели, импорт и экспорт
Все действия осуществляются в boot() своего plugin.php.
Для начала необходимо создать плагин, назовём его Extender.
php artisan create:plugin Site21.Extender
и подключить контроллеры и модели плагинов которые Вы хотите расширить.
За пример возьмем плагин Rainlab.User. У него есть все что нам нужно расширить: модели, котроллеры, импорт и экспорт.
use RainLab\Blog\Controllers\Posts;
use RainLab\Blog\Models\Post;
Теперь к контроллеру мы можем обращаться через Posts, а к модели через Post.
Наши данные где-то должны храниться, поэтому мы должны расширить БД через миграциию. Можем это сделать:
В этом уроке мы научимся обоим вариантам.
Для первого варианта нам нужна будет своя модель (к примеру для тегов). Создадим её и назовём Tag. Также мы хотим управлять нашими тегами через админку, поэтому сразу создадим свой контроллер Tags
php artisan create:model Site21.Extender Tag
php artisan create:controller Site21.Extender Tags
Теперь в нашу новую таблицу необходимо добавить некоторые поля. После создания модели у нас создался новый файл create_tags_table.php в папке updates плагина. Добавим туда колонки name и description для примера. Файл получится таким:
<?php namespace Site21\Extender\Updates;
use Schema;
use October\Rain\Database\Schema\Blueprint;
use October\Rain\Database\Updates\Migration;
class CreateTagsTable extends Migration
{
public function up()
{
Schema::create('site21_extender_tags', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name');
$table->text('description')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('site21_extender_tags');
}
}
В этом варианте предполагается что мы не будем затрагивать таблицу rainlab_blog_posts, поэтому создадим еще одну новую таблицу в БД для линковки постов и тегов. Создадим новый файл с миграцией в папке updates create_tags_posts_table.php с содержимым:
<?php namespace Site21\Extender\Updates;
use Schema;
use October\Rain\Database\Schema\Blueprint;
use October\Rain\Database\Updates\Migration;
class CreateTagsPostsTable extends Migration
{
public function up()
{
Schema::create('site21_extender_tags_posts', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('tag_id');
$table->integer('post_id');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('site21_extender_tags_posts');
}
}
В этой же папке updates есть файл version.yaml, дописываем туда наши новые миграции:
1.0.1: First version of Extender
1.0.2:
- Create tags table
- create_tags_table.php
1.0.3:
- Create tags posts table
- create_tags_posts_table.php
и запускаем:
php artisan october:up
Закончим создание контроллера добавлением в подменю Блог новой ссылки Теги для удобства управления. Для этого в boot() пишем:
// добавляем ссылку тегов в контекст блога
\Event::listen('backend.menu.extendItems', function($manager) {
$manager->addSideMenuItems('RainLab.Blog', 'blog', [
'tags' => [
'code' => 'tags',
'label' => 'Теги',
'icon' => 'icon-tags',
'url' => Backend::url('site21/extender/tags'),
'order' => 550,
],
]);
});
Пункт меня добавился в подменю блога, но для того чтобы показать контроллеру Tags его новое место редактируем его и заменяем строчку BackendMenu::setContext на
BackendMenu::setContext('RainLab.Blog', 'blog', 'posts');
Напоследок оформляем в папке модели tag fields.yaml:
fields:
id:
label: ID
disabled: true
hidden: true
name:
label: Название
type: text
span: auto
required: 1
description:
label: Описание
type: textarea
span: auto
и columns.yaml
columns:
id:
label: ID
searchable: true
width: 50px
name:
label: Название
searchable: true
Теперь мы можем добавлять/редактировать и удалять теги. К постам подключим новое поле с выбором тегов на следующем шаге.
Для этого варианта нам не нужно создать ни контроллер, ни модель, расширим существующие от Блога. Но миграцию создать все равно нужно. Создадим файл add_column_to_post.php со следующим содержимым в папке updates:
<?php namespace Site21\Extender\Updates;
use Schema;
use Illuminate\Database\Schema\Blueprint;
use October\Rain\Database\Updates\Migration;
class AddColumnToPost extends Migration
{
const TABLE_NAME = 'rainlab_blog_posts';
public function up()
{
if (!Schema::hasTable(self::TABLE_NAME) || Schema::hasColumn(self::TABLE_NAME, 'featured')) {
return;
}
Schema::table(self::TABLE_NAME, function (Blueprint $obTable)
{
$obTable->integer('featured')->default(0);
});
}
public function down()
{
if (!Schema::hasTable(self::TABLE_NAME) || !Schema::hasColumn(self::TABLE_NAME, 'featured')) {
return;
}
Schema::table(self::TABLE_NAME, function (Blueprint $obTable)
{
$obTable->dropColumn(['featured']);
});
}
}
Названите файла класса, таблицы может быть любым. Показываю поэтапность.
В данном примере мы добавили integer колонку в таблицу с постами. С помощью этой колонки будем отбирать избранные посты в дальнейшем. Подробнее о том как работать с БД через миграции описано в документации OctoberCMS.
Далее в version.yaml пишем о новой версии:
1.0.4:
- Add column featured to post
- add_column_to_post.php
и запускаем:
php artisan october:up
Самое время добавить новые поля в админку. Добавим новую колонку featured с типом Switch и выбор тегов с типом . Обо всех типах формы написано в документации OctoberCMS.
В блоге используются secondaryTabs, поэтому добавляем в них. В большинстве случаев используются обычные табы, поэтому можете писать addTabFields.
В boot() пишем:
\Event::listen('backend.form.extendFields', function($widget) {
if (!$widget->getController() instanceof Posts || $widget->isNested || $widget->alias != 'form') {
return;
}
if (!$widget->model instanceof Post) {
return;
}
// Добавляем необходимые колонки
$widget->addSecondaryTabFields([
'featured' => [
'label' => 'Избранное',
'type' => 'switch',
'span' => 'auto'
],
'tags' => [
'label' => 'Теги',
'type' => 'taglist',
'mode' => 'relation',
'span' => 'auto'
]
]);
});
// Расширяем модель добавив связь для первого варианта
Post::extend(function ($model) {
$model->belongsToMany = array_merge(
$model->belongsToMany,
['tags' => [
'Site21\Extender\Models\Tag',
'table' => 'site21_extender_tags_posts',
'key' => 'post_id',
'otherKey' => 'tag_id'
]]
);
});
Отлично! Поля сохраняются, все хорошо.
Если не указана настрйока "tab", то всегда будет публиковаться во вкладку "Разное". Если Вы хотите разместить поле в существующую таблицу, то написать на русском "Управление" будет неверно, система создаст новую вкладку. Чтобы добавить поле в существующую вкладку Вам нужно перейти в fields.yaml необходимого модуля и посмотреть как назвается влкадка там. На примере блога это:
tab: 'rainlab.blog::lang.post.tab_edit'
Для расширения импорт и экспорта у нас есть несколько шагов:
Действие расширяется через $controller->importExportConfig
Со вторым вариантом (поле featured) все просто:
// Расширяем импорт и экспорт необходимого контроллера
Posts::extend(function($controller) {
// Получаем конфиг $importExportConfig у нашего контроллера
$config = $controller->makeConfig($controller->importExportConfig);
// Добавляем колонки в Экспорт
$export = $controller->makeConfig($config->export['list']);
$export->columns['featured'] = 'Избранное';
// Добавляем колонки в Импорт
$import = $controller->makeConfig($config->import['list']);
$import->columns['featured'] = 'Избранное';
// Переназначаем конфиг
$config->export['list'] = $export;
$config->import['list'] = $import;
$controller->importExportConfig = (array) $config;
});
В случае если колонки импорта и экспорта уже указаны в importExportConfig, например как в Shopaholic, то добавлять еще проще (пример):
// Получаем конфиг $importExportConfig у нашего контроллера
$config = $controller->makeConfig($controller->importExportConfig);
// Добиваем колонку с фильтрами
$config->import['list']['columns']['filters'] = ['label' => 'Фильтры'];
// Переназначаем конфиг
$controller->importExportConfig = (array) $config;
Пишите dd($config) и смотрите как реализовано в расшряемом плагине.
Для простых полей (2-ой вариант) уже все реализовано, но вот для тегов (1-ый вариант) еще нужно доработать чтобы при импорте создавалась новая запись в нужную таблицу.
Об этом мы поговорим в следующем уроке.
Опубликовано 15 июня 2021 г. в категориях: October CMS Winter CMS
Если Вам необходимо внедрить данную разработку на свой проект, свяжитесь со мной, обсудим цену и срок.