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

src/Strategy/ThemeAwareStrategyManager.php
<?php

namespace Drupal\toolshed\Strategy;

/**
 * The base strategy manager for theme aware strategy types.
 *
 * The theme aware manager can change the strategy definitions based on the
 * requested theme context. Normally this will be the "default" theme or the
 * currently active theme, can be any theme passed in the $context parameter
 * of the this::getDefinitions(), this::getDefinition() or this::hasDefinition()
 * methods.
 *
 * The theme is set by the "theme" key of the $context parameter, as follows:
 * @code
 * $context = ['theme' => <theme_name>];
 * @endcode
 *
 * Module definitions are always available, but theme provided definitions are
 * only available for the theme context that defines the strategy. Theme
 * strategies can override module defined strategies of the same name when that
 * theme context is active.
 */
abstract class ThemeAwareStrategyManager extends StrategyManager {

  use ThemeStrategyDiscoveryTrait;

  /**
   * Currently discovered theme strategy definitions by theme name.
   *
   * Definitions are grouped by the providing theme and has the following
   * structure:
   *
   * $this->themeDefinitions = [
   *   "<theme_name>" => [
   *     "<strategy_id>" => StrategyDefinition,
   *     "<strategy_id>" => StrategyDefinition,
   *     ...
   *   ],
   * ];
   *
   * This is different from how module definitions are stored because the same
   * strategy identifier can be used by different themes or other modules. The
   * theme definitions also need to be grouped by theme, so they can be easily
   * found and applied for the active, or requested theme contexts.
   *
   * @var \Drupal\toolshed\Strategy\StrategyDefinitionInterface[][]|null
   */
  protected ?array $themeDefinitions;

  /**
   * Definitions grouped by theme name.
   *
   * These are definitions after the theme overrides have been applied, and can
   * be used for the theme context they are grouped for.
   *
   * @var \Drupal\toolshed\Strategy\StrategyDefinitionInterface[][]
   */
  protected array $definitionsByTheme = [];

  /**
   * {@inheritdoc}
   */
  public function clearCachedDefinitions(): void {
    parent::clearCachedDefinitions();

    if ($this->cacheBackend) {
      $cid = $this->getCacheId() . ':theme';
      $this->cacheBackend->delete($cid);
    }
    $this->definitionsByTheme = [];
  }

  /**
   * {@inheritdoc}
   */
  public function getDefinitions(array $context = []): array {
    $themeId = $context['theme'] ?? $this->getDefaultTheme();

    // Have we generated the definitions available for this theme yet?
    if (!isset($this->definitionsByTheme[$themeId])) {
      $themeDefinitions = $this->getThemeDefinitions();

      // Theme definitions also need to include definitions provided by their
      // base themes as well. We apply the definitions by current theme first
      // and earilest ancestor last.
      $enabledThemes = $this->themeHandler->listInfo();

      $themes = array_keys($this->themeHandler->getBaseThemes($enabledThemes, $themeId));
      $themes[] = $themeId;

      $this->definitionsByTheme[$themeId] = [];
      foreach (array_reverse($themes) as $themeName) {
        if (!empty($themeDefinitions[$themeName])) {
          $this->definitionsByTheme[$themeId] += $themeDefinitions[$themeName];
        }
      }

      // Apply the module defined definitions last. This allows the theme
      // defined strategies to override the module definitions.
      $this->definitionsByTheme[$themeId] += parent::getDefinitions($context);
    }

    return $this->definitionsByTheme[$themeId];
  }

  /**
   * {@inheritdoc}
   */
  public function getInstance(string $id, array $context = []): StrategyInterface {
    $definition = $this->getDefinition($id, $context);

    $key = $id;
    if ($definition->getProviderType() === 'theme') {
      // It is possible due to theme switching that the a strategy with the
      // same ID is available for a module or a different theme, so we can't
      // rely on the ID alone for theme strategies.
      $key = $definition->getProvider() . ':' . $key;
    }

    if (!isset($this->instances[$key])) {
      $instance = $this->getFactory()->create($id, $definition);
      $this->initInstance($id, $instance);
      $this->instances[$key] = $instance;
    }

    return $this->instances[$key];
  }

  /**
   * Get definitions provided by themes, grouped by their providers.
   *
   * The definitions are returned in the same format as described by the
   * ThemeStrategyDiscoveryTrait::findThemeDefinitions().
   *
   * @return \Drupal\toolshed\Strategy\StrategyDefinitionInterface[][]
   *   Get theme provided strategy definitions grouped by the providing theme.
   *
   * @see \Drupal\toolshed\Strategy\ThemeStrategyDiscoveryTrait::findThemeDefinitions()
   */
  protected function getThemeDefinitions(): array {
    if (!isset($this->themeDefinitions)) {
      $cid = $this->getCacheId() . ':theme';

      if ($cached = $this->cacheGet($cid)) {
        $this->themeDefinitions = $cached->data;
      }
      else {
        $this->themeDefinitions = $this->findThemeDefinitions();
        $this->cacheSet($cid, $this->themeDefinitions);
      }
    }

    return $this->themeDefinitions;
  }

}

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

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