You are here

LanguageConfigFactoryOverride.php in Drupal 9

File

core/modules/language/src/Config/LanguageConfigFactoryOverride.php
View source
<?php

namespace Drupal\language\Config;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigCollectionInfo;
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigFactoryOverrideBase;
use Drupal\Core\Config\ConfigRenameEvent;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Language\LanguageDefault;
use Drupal\Core\Language\LanguageInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Provides language overrides for the configuration factory.
 */
class LanguageConfigFactoryOverride extends ConfigFactoryOverrideBase implements LanguageConfigFactoryOverrideInterface, EventSubscriberInterface {
  use LanguageConfigCollectionNameTrait;

  /**
   * The configuration storage.
   *
   * Do not access this directly. Should be accessed through self::getStorage()
   * so that the cache of storages per langcode is used.
   *
   * @var \Drupal\Core\Config\StorageInterface
   */
  protected $baseStorage;

  /**
   * An array of configuration storages keyed by langcode.
   *
   * @var \Drupal\Core\Config\StorageInterface[]
   */
  protected $storages;

  /**
   * The typed config manager.
   *
   * @var \Drupal\Core\Config\TypedConfigManagerInterface
   */
  protected $typedConfigManager;

  /**
   * An event dispatcher instance to use for configuration events.
   *
   * @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * The language object used to override configuration data.
   *
   * @var \Drupal\Core\Language\LanguageInterface
   */
  protected $language;

  /**
   * Constructs the LanguageConfigFactoryOverride object.
   *
   * @param \Drupal\Core\Config\StorageInterface $storage
   *   The configuration storage engine.
   * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher
   *   An event dispatcher instance to use for configuration events.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
   *   The typed configuration manager.
   * @param \Drupal\Core\Language\LanguageDefault $default_language
   *   The default language.
   */
  public function __construct(StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config, LanguageDefault $default_language) {
    $this->baseStorage = $storage;
    $this->eventDispatcher = $event_dispatcher;
    $this->typedConfigManager = $typed_config;

    // Prior to negotiation the override language should be the default
    // language.
    $this->language = $default_language
      ->get();
  }

  /**
   * {@inheritdoc}
   */
  public function loadOverrides($names) {
    if ($this->language) {
      $storage = $this
        ->getStorage($this->language
        ->getId());
      return $storage
        ->readMultiple($names);
    }
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getOverride($langcode, $name) {
    $storage = $this
      ->getStorage($langcode);
    $data = $storage
      ->read($name);
    $override = new LanguageConfigOverride($name, $storage, $this->typedConfigManager, $this->eventDispatcher);
    if (!empty($data)) {
      $override
        ->initWithData($data);
    }
    return $override;
  }

  /**
   * {@inheritdoc}
   */
  public function getStorage($langcode) {
    if (!isset($this->storages[$langcode])) {
      $this->storages[$langcode] = $this->baseStorage
        ->createCollection($this
        ->createConfigCollectionName($langcode));
    }
    return $this->storages[$langcode];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheSuffix() {
    return $this->language ? $this->language
      ->getId() : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getLanguage() {
    return $this->language;
  }

  /**
   * {@inheritdoc}
   */
  public function setLanguage(LanguageInterface $language = NULL) {
    $this->language = $language;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function installLanguageOverrides($langcode) {

    /** @var \Drupal\Core\Config\ConfigInstallerInterface $config_installer */
    $config_installer = \Drupal::service('config.installer');
    $config_installer
      ->installCollectionDefaultConfig($this
      ->createConfigCollectionName($langcode));
  }

  /**
   * {@inheritdoc}
   */
  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
    $langcode = $this
      ->getLangcodeFromCollectionName($collection);
    return $this
      ->getOverride($langcode, $name);
  }

  /**
   * {@inheritdoc}
   */
  public function addCollections(ConfigCollectionInfo $collection_info) {
    foreach (\Drupal::languageManager()
      ->getLanguages() as $language) {
      $collection_info
        ->addCollection($this
        ->createConfigCollectionName($language
        ->getId()), $this);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function onConfigSave(ConfigCrudEvent $event) {
    $config = $event
      ->getConfig();
    $name = $config
      ->getName();
    foreach (\Drupal::languageManager()
      ->getLanguages() as $language) {
      $config_translation = $this
        ->getOverride($language
        ->getId(), $name);
      if (!$config_translation
        ->isNew()) {
        $this
          ->filterOverride($config, $config_translation);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function onConfigRename(ConfigRenameEvent $event) {
    $config = $event
      ->getConfig();
    $name = $config
      ->getName();
    $old_name = $event
      ->getOldName();
    foreach (\Drupal::languageManager()
      ->getLanguages() as $language) {
      $config_translation = $this
        ->getOverride($language
        ->getId(), $old_name);
      if (!$config_translation
        ->isNew()) {
        $saved_config = $config_translation
          ->get();
        $storage = $this
          ->getStorage($language
          ->getId());
        $storage
          ->write($name, $saved_config);
        $config_translation
          ->delete();
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function onConfigDelete(ConfigCrudEvent $event) {
    $config = $event
      ->getConfig();
    $name = $config
      ->getName();
    foreach (\Drupal::languageManager()
      ->getLanguages() as $language) {
      $config_translation = $this
        ->getOverride($language
        ->getId(), $name);
      if (!$config_translation
        ->isNew()) {
        $config_translation
          ->delete();
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata($name) {
    $metadata = new CacheableMetadata();
    if ($this->language) {
      $metadata
        ->setCacheContexts([
        'languages:language_interface',
      ]);
    }
    return $metadata;
  }

}

Classes

Namesort descending Description
LanguageConfigFactoryOverride Provides language overrides for the configuration factory.