xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Использование Plugin API в своём модуле

Опубликовано в

Система плагинов (plugins) в Drupal 8 это ООП замена инфо-хуков из Drupal 7. Сам плагин это простой класс, лежащий по определённому адресу, имеющий аннотацию и необходимые методы.

Ниже пример модуля Calculator, который производит арифметические операции над двумя числами. Каждая операция (сложение, умножение и т.д.) будет реализована в виде плагина.

1. Создание Plugin manager-а

Plugin manager это класс, отвечающий за поиск плагинов определённого типа и создание их экземпляров.

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

// modules/calculator/src/CalculatorOperationManager.php
 
namespace Drupal\calculator;
 
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
 
class CalculatorOperationManager extends DefaultPluginManager {
  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
    parent::__construct('Plugin/calculator/operation', $namespaces, $module_handler);
    $this->alterInfo('calculator_operations_info');
    $this->setCacheBackend($cache_backend, 'calculator_plugins');
  }
}

Plugin/calculator/operation — поддиректория, в которой будут располагаться плагины этого типа.
calculator_operations_info — имя альтер хука, по которому можно изменять плагины этого типа.
calculator_plugins — префикс для кэша, в котором будет храниться информация о найденных плагинах этого типа.

Подробнее про plugin managers.

2. Создание сервиса из плагин-менеджера

Все плагин-менеджеры являются сервисами. Для превращения класса в сервис нужно создать в корне модуля файл MODULENAME.services.yml и описать в нём параметры сервиса:

services:
  plugin.manager.calculator_operation:
    class: Drupal\calculator\CalculatorOperationManager
    parent: default_plugin_manager

Подробнее про сервисы.

3. Создание плагина

В поддиректории, указанной в первом шаге (Plugin/calculator/operation), создаём класс, унаследованный от PluginBase и реализуем в нём логику работы плагина:

// modules/calculator/src/Plugin/calculator/operation/Plus.php
 
namespace Drupal\calculator\Plugin\calculator\operation;
 
use Drupal\Component\Annotation\Plugin;
use Drupal\Component\Plugin\PluginBase;
 
/**
 * @Plugin(
 *   id = "plus",
 *   operator = "+"
 * )
 */
class Plus extends PluginBase {
  public function calculate($num1, $num2) {
    return $num1 + $num2;
  }
}

В аннотациях к классу указывается id плагина (обязательно) и различные опции (опционально).

Подробнее про аннотации.

4. Поиск плагинов

Список всех плагинов получаем вызовом метода DefaultPluginManager::getDefinitions(). Пример из формы калькулятора:

$options = array();
foreach ($this->calculatorOperationManager->getDefinitions() as $definition) {
  $options[$definition['id']] = $definition['operator'];
}
$form['operation'] = array(
  '#type' => 'select',
  '#title' => $this->t('Operation'),
  '#options' => $options,
);

Как получать сервисы вроде $this->calculatorOperationManager в формах и контроллерах писал здесь.

5. Создание экземпляра плагина и вызов его методов

Инстанcы плагина создаются вызовом DefaultPluginManager::createInstance($plugin_id) и используются как обычные классы.

Пример из формы калькулятора:

public function submitForm(array &$form, array &$form_state) {
  $operator_plugin = $this->calculatorOperationManager->createInstance($form_state['values']['operation']);
  $result = $operator_plugin->calculate($form_state['values']['num1'], $form_state['values']['num2']);
  drupal_set_message($result);
}

Исходники модуля Calculator с двумя плагинами. Форма калькулятора находится по адресу /calculator.

Статьи про Plugin API:
Drupal 8 Print Module Port: The Plugin API (1/5)
Unravelling the Drupal 8 Plugin System

Видео:
Введение в Drupal 8 Plugin System

Написанное актуально для Drupal 8
Похожие записи

Комментарии RSS

Глядя на первый блок кода, хочется многое сказать ярко в красках, не сдерживая эмоций.
Но вот не знаю, можно ли у тебя в блоге материться…

ну да, не очень наглядно, di в действии. я бы конечно это лучше в аннотации загнал

Ну по сути must read здесь только пункт 3, остальное уже для «элиты».

Попробовал установить модуль на версии 8.2.3 - выдает ошибку.

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании