altcolor-1.0.0-beta1/src/Plugin/AltColorPluginManager.php

src/Plugin/AltColorPluginManager.php
<?php

namespace Drupal\altcolor\Plugin;

use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
use Drupal\Core\Plugin\Discovery\YamlDiscovery;
use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\Core\Theme\ThemeInitializationInterface;
use Drupal\Core\Theme\ThemeManagerInterface;

/**
 * Provides an alternative color manager.
 */
class AltColorPluginManager extends DefaultPluginManager implements AltColorPluginManagerInterface {

  /**
   * Provides default values for ThemeColors plugins.
   *
   * @var array
   */
  protected $defaults = [
    'colors' => [],
    'schemes' => [],
    'class' => 'Drupal\altcolor\Plugin\ThemeColors',
  ];

  /**
   * {@inheritdoc}
   */
  protected $pluginInterface = 'Drupal\altcolor\Plugin\ThemeColorsInterface';

  /**
   * Static cache of color definitions by theme.
   *
   * @var array
   */
  protected $colorDefinitionsByTheme;

  /**
   * Constructs a new AlternativeColorManager instance.
   */
  public function __construct(
    protected ThemeHandlerInterface $themeHandler,
    protected ThemeManagerInterface $themeManager,
    protected ThemeInitializationInterface $themeInitialization,
    CacheBackendInterface $cache_backend,
  ) {
    $this->factory = new ContainerFactory($this, $this->pluginInterface);
    $this->setCacheBackend($cache_backend, 'altcolor');
  }

  /**
   * {@inheritdoc}
   */
  protected function getDiscovery() {
    if (!isset($this->discovery)) {
      $this->discovery = new YamlDiscovery('colors', $this->themeHandler->getThemeDirectories());
      $this->discovery->addTranslatableProperty('label', 'label_context');
      $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
    }
    return $this->discovery;
  }

  /**
   * {@inheritdoc}
   */
  public function processDefinition(&$definition, $plugin_id): void {
    parent::processDefinition($definition, $plugin_id);

    // Check if the *.colors.yml file contains at least one configurable color.
    if (empty($definition['colors'])) {
      throw new PluginException('At least one configurable color is required.');
    }
    // Check if all scheme colors have the corresponding configurable colors.
    foreach ($definition['schemes'] as $scheme => $content) {
      if (!empty(array_diff_key($definition['colors'], $content['colors']))) {
        throw new PluginException(sprintf('The colors in scheme (%s) do not match with the configurable colors.', $scheme));
      }
      // Check if all scheme colors have a correct color format.
      foreach ($content['colors'] as $color_field => $color_value) {
        if (!preg_match('/^#[a-fA-F0-9]{6}$/', $color_value)) {
          throw new PluginException(sprintf('The colors in scheme (%s) must be 7-character string specifying a color hexadecimal format.', $scheme));
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function providerExists($provider): bool {
    return $this->themeHandler->themeExists($provider);
  }

  /**
   * {@inheritdoc}
   */
  public function getColorDefinitionsForActiveTheme(): ThemeColorsInterface|NULL {
    $active_theme = $this->themeManager->getActiveTheme();
    return $this->getColorDefinitionsByTheme($active_theme->getName());
  }

  /**
   * {@inheritdoc}
   */
  public function getColorDefinitionsByTheme($theme): ThemeColorsInterface|NULL {
    if (!isset($this->colorDefinitionsByTheme[$theme])) {
      foreach ($this->getDefinitions() as $plugin_id => $plugin_definition) {
        // Store the color definitions per theme.
        $this->colorDefinitionsByTheme[$plugin_definition['provider']] = $plugin_definition;
      }

      // Initialize an active theme by name.
      $active_theme = $this->themeInitialization->getActiveThemeByName($theme);
      // Resolve all the parent themes and get the color definitions in reversed
      // order. This ensures that the color definitions from the top-most base
      // theme are processed first, and each subtheme can override its parent
      // theme.
      $theme_chain = array_reverse(array_keys($active_theme->getBaseThemeExtensions()));
      $theme_chain[] = $active_theme->getName();

      // Use an empty definition and override it with the first theme in the
      // chain that provides a color definition. Keep updating the override for
      // every encountered theme with a color definition. Every extending theme
      // without its own definition will inherit the definition from the parent.
      $definition = NULL;
      foreach ($theme_chain as $extension) {
        $color_definition = $this->colorDefinitionsByTheme[$extension] ?? NULL;
        if (!empty($color_definition)) {
          $definition = $color_definition;
        }
        $this->colorDefinitionsByTheme[$extension] = $definition;
      }
    }

    // Make sure to use the provider that is defined in the color definition. An
    // extending theme might not define a plugin but use its parent plugin
    // instead.
    return !empty($this->colorDefinitionsByTheme[$theme])
      ? $this->createInstance($this->colorDefinitionsByTheme[$theme]['provider'], $this->colorDefinitionsByTheme[$theme])
      : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function clearCachedDefinitions() {
    parent::clearCachedDefinitions();
    $this->colorDefinitionsByTheme = [];
  }

}

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

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