crocheteer-8.x-1.0/src/Plugin/Hook/HookPluginManager.php

src/Plugin/Hook/HookPluginManager.php
<?php

namespace Drupal\crocheteer\Plugin\Hook;

use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\hook_event_dispatcher\Event\EventInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Traversable;

/**
 * Base class for all Hook Plugin Managers.
 */
abstract class HookPluginManager extends DefaultPluginManager implements HookPluginManagerInterface, ContainerInjectionInterface {

  /**
   * Array of relevant Hook Plugin IDs.
   *
   * @var string[]
   */
  private array $hookPlugins;

  /**
   * The Drupal Logger Channel.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected LoggerChannelInterface $loggerChannel;

  /**
   * The Event object containing all Hook parameters.
   *
   * @var \Drupal\hook_event_dispatcher\Event\EventInterface
   */
  protected EventInterface $event;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) : HookPluginManagerInterface {
    return new static(
      $container->get('container.namespaces'),
      $container->get('cache.discovery'),
      $container->get('module_handler'),
      $container->get('logger.factory')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function __construct(
    Traversable $namespaces,
    CacheBackendInterface $cacheBackend,
    ModuleHandlerInterface $moduleHandler,
    LoggerChannelFactoryInterface $loggerChannelFactory,
    ?string $pluginInterface = NULL,
    ?string $pluginDefinitionAnnotationName = NULL,
    $pluginBaseId = 'crocheteer',
    array $additionalAnnotationNamespaces = []
  ) {
    parent::__construct(
      'Plugin/crocheteer/Hook',
      $namespaces,
      $moduleHandler,
      $pluginInterface,
      $pluginDefinitionAnnotationName,
      $additionalAnnotationNamespaces
    );
    $this->alterInfo($pluginBaseId . '_info');
    $this->setCacheBackend($cacheBackend, $pluginBaseId . '_plugins');
    $this->loggerChannel = $loggerChannelFactory->get($pluginBaseId);
  }

  /**
   * {@inheritdoc}
   */
  public function setup(EventInterface $event) : void {
    $this->event = $event;
    $this->definitions = $this->getDefinitions();
    $this->retrieveHookPlugins();
  }

  /**
   * {@inheritdoc}
   */
  public function executeHooks() : void {
    foreach ($this->hookPlugins as $hookPlugin) {
      try {
        /* @var \Drupal\crocheteer\Plugin\Hook\HookPluginInterface $hook */
        $hook = $this->createInstance($hookPlugin);
        $hook->setup($this->event);
        $hook->hook();
      }
      catch (PluginException $exception) {
        $error = $exception->getMessage() . 'Backtrace:<br><br><pre>' . $exception->getTraceAsString() . '</pre>';
        $this->loggerChannel->error($error);
      }
    }
  }

  /**
   * Retrieves a keyed array of Hook Plugin definition properties.
   *
   * This method should be overridden by child classes in need of hook-related
   * relevancy properties.
   *
   * These properties keys are to be evaluated against their respective provided
   * values. The keys name must match their Annotation properties, since it is
   * ultimately the Annotations that will pass relevancy values to this method.
   *
   * Different Hook types necessitate different relevancy properties, while some
   * might not need any at all. This is why this base method is returning an
   * empty array.
   *
   * @return array
   *   Keyed array of Plugin definition properties to be evaluated with their
   *   respective provided values.
   */
  protected function getRelevancyProperties() : array {
    return [];
  }

  /**
   * Determines whether a Hook Plugin definition is context-relevant or not.
   *
   * This is done by ensuring that specified definition properties match the
   * current Hook Plugin being processed by the Hook Plugin Manager.
   *
   * @param array $definition
   *   The Hook Plugin definition to be evaluated.
   * @param array $properties
   *   Keyed array of Hook Plugin definition properties to be evaluated with
   *   their respective provided values.
   *
   * @return bool
   *   Whether the Hook Plugin definition is relevant or not.
   */
  protected function isRelevantDefinition(array $definition, array $properties) : bool {
    $isRelevant = TRUE;
    foreach ($properties as $property => $value) {
      if (!empty($definition[$property])) {
        if (!is_array($value)) {
          $value = [$value];
        }
        $isRelevant = !empty(array_intersect($value, $definition[$property]));
      }
      if ($isRelevant === FALSE) {
        break;
      }
    }
    return $isRelevant;
  }

  /**
   * Retrieves Hook Plugin Definition IDs relevant to the current context.
   */
  private function retrieveHookPlugins() : void {
    $this->hookPlugins = [];
    foreach ($this->definitions as $id => $definition) {
      $properties = $this->getRelevancyProperties();
      $isRelevant = $this->isRelevantDefinition($definition, $properties);
      if ($isRelevant) {
        $this->hookPlugins[] = $id;
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc