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

29.01.2014

Система плагинов (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 {

  /**
   * Constructs a new class instance.
   */
  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(). Пример из формы калькулятора:

$calculator_operation_manager = \Drupal::service('plugin.manager.calculator_operation');

$options = array();
foreach ($calculator_operation_manager->getDefinitions() as $definition) {
  $options[$definition['id']] = $definition['operator'];
}

$form['operation'] = array(
  '#type' => 'select',
  '#title' => $this->t('Operation'),
  '#options' => $options,
);

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

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

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

public function submitForm(array &$form, array &$form_state) {
  $calculator_operation_manager = \Drupal::service('plugin.manager.calculator_operation');
  $operator_plugin = $calculator_operation_manager->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
Похожие записи

Комментарии

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

Роман
02.12.2016, 17:42

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

Добавить комментарий