toolshed-8.x-1.x-dev/src/Strategy/ThemeStrategyDiscoveryTrait.php

src/Strategy/ThemeStrategyDiscoveryTrait.php
<?php

namespace Drupal\toolshed\Strategy;

use Drupal\Component\Discovery\DiscoverableInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\toolshed\Discovery\YamlDiscovery;
use Drupal\toolshed\Event\StrategyDefinitionAlterEvent;

/**
 * Trait to add theme provide strategy discovery methods to a strategy manager.
 */
trait ThemeStrategyDiscoveryTrait {

  /**
   * The theme handler.
   *
   * @var \Drupal\Core\Extension\ThemeHandlerInterface|null
   */
  protected ?ThemeHandlerInterface $themeHandler;

  /**
   * The theme manager.
   *
   * @var \Drupal\Core\Theme\ThemeManagerInterface|null
   */
  protected ?ThemeManagerInterface $themeManager;

  /**
   * The discovery name to use when searching for definitions in themes.
   *
   * Generally this will be implemented by the strategy manager class.
   *
   * @return string
   *   The discovery name to use when searching for theme provided strategy
   *   definitions.
   *
   * @see \Drupal\toolshed\Strategy\StrategyDefinition::getDiscoveryName()
   */
  abstract public function getDiscoveryName(): string;

  /**
   * Converts discovered array data into a StrategyDefinitionInterface object.
   *
   * Generally this will be implemented by the strategy manager class.
   *
   * @return \Drupal\toolshed\Strategy\StrategyDefinitionInterface
   *   The strategy definition object built from the definition data.
   *
   * @see \Drupal\toolshed\Strategy\StrategyDefinition::processDefinition()
   */
  abstract protected function processDefinition(string $id, array $definition): StrategyDefinitionInterface;

  /**
   * Injects the theme handler and theme manager services.
   *
   * Can be called from an constructor to initialize these services or can be
   * called from the services.yml file when defining services.
   *
   * The following is an example from the services definition:
   *
   * @code
   * strategy.manager.example:
   *   class: Drupal\toolshed\ExampleManager
   *   arguments:
   *     - 'name'
   *     - '@module_handler'
   *     - '@cache.discovery'
   *   calls:
   *     - [setThemeServices, ['@theme_handler', '@theme.manager']]
   * @endcode
   *
   * The latter is preferred, and keeps the constructor simpler. This also
   * makes it easier to apply this trait without having to the need to override
   * constructors.
   *
   * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
   *   The theme handler.
   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
   *   The theme manager.
   */
  public function setThemeServices(ThemeHandlerInterface $theme_handler, ThemeManagerInterface $theme_manager): void {
    $this->themeHandler = $theme_handler;
    $this->themeManager = $theme_manager;
  }

  /**
   * Gets the theme name of the default theme.
   *
   * The machine name of the theme to use when a theme is not specified
   * explicitly. In general this is likely to be the "active" theme, but could
   * be the "default" theme, or even based on context based criteria.
   *
   * Strategy managers (and other uses of this trait) should override this when
   * if they determine the default theme in different ways, or conditionally.
   *
   * @return string
   *   The theme machine name to use as the default theme.
   */
  protected function getDefaultTheme(): string {
    return $this->themeManager->getActiveTheme()->getName();
  }

  /**
   * Get the discovery instance to find theme provided strategy definitions.
   *
   * @return \Drupal\Component\Discovery\DiscoverableInterface
   *   The theme discovery object.
   */
  protected function getThemeDiscovery(): DiscoverableInterface {
    $dirs = $this->themeHandler->getThemeDirectories();

    $discovery = new YamlDiscovery($this->getDiscoveryName(), $dirs);
    $discovery->addTranslatableProperty('label', 'label_context');
    $discovery->addTranslatableProperty('description', 'description_context');
    return $discovery;
  }

  /**
   * Get theme provided strategy definitons grouped by the theme.
   *
   * The definitions are organized by the themes that define them as follows:
   *
   * @code
   * $this->themeDefinitions = [
   *   "<theme_name>" => [
   *     "<strategy_id>" => StrategyDefinition,
   *     "<strategy_id>" => StrategyDefinition,
   *     ...
   *   ],
   * ];
   * @endcode
   *
   * @return \Drupal\toolshed\Strategy\StrategyDefinitionInterface[][]
   *   Get the theme definitions provided by themes. The definitions are
   *   grouped by the providing themes.
   */
  public function findThemeDefinitions(): array {
    $discovery = $this->getThemeDiscovery();
    $byProvider = $discovery->findAll();

    // Ensure that all the definitions have their ID and provider info set.
    foreach ($byProvider as $theme => &$definitions) {
      foreach ($definitions as $id => &$definition) {
        $definition += [
          'id' => $id,
          'provider' => $theme,
          'provider_type' => 'theme',
        ];
      }
    }
    unset($definitions, $definition);

    // Allow other modules to alter the discovered strategy definitions before
    // they are converted to the StrategyDefinitionInterface instances.
    if (!empty($this->alterEventName) && !empty($this->eventDispatcher)) {
      $event = new StrategyDefinitionAlterEvent('theme', $byProvider);
      $this->eventDispatcher->dispatch($event, $this->alterEventName);
    }

    $strategies = [];
    foreach ($byProvider as $theme => $definitions) {
      foreach ($definitions as $id => $def) {
        $strategies[$theme][$id] = $this->processDefinition($id, $def);
      }
    }

    return $strategies;
  }

}

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

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