Verified Commit a735e53c authored by Dave Long's avatar Dave Long
Browse files

fix: #3518992 Config overrides are loaded for English even when translate_english is false

By: catch
By: berdir
By: alexpott
By: dcam
(cherry picked from commit bd24c65d)
parent e2465298
Loading
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
parameters:
  language.skip_procedural_hook_scan: true
  language.translate_english: true

services:
  _defaults:
@@ -18,7 +19,7 @@ services:
    arguments: ['@language_manager', '@language.default', '@config.factory', '@language_negotiator']
  language.config_factory_override:
    class: Drupal\language\Config\LanguageConfigFactoryOverride
    arguments: ['@config.storage', '@event_dispatcher', '@config.typed', '@language.default']
    arguments: ['@config.storage', '@event_dispatcher', '@config.typed', '@language.default', '%language.default_values%', '%language.translate_english%']
    tags:
      - { name: config.factory.override, priority: -254 }
  Drupal\language\Config\LanguageConfigFactoryOverrideInterface: '@language.config_factory_override'
+28 −41
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigFactoryOverrideBase;
use Drupal\Core\Config\ConfigRenameEvent;
use Drupal\Core\Config\NullStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Language\LanguageDefault;
@@ -21,16 +22,6 @@ class LanguageConfigFactoryOverride extends ConfigFactoryOverrideBase implements

  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.
   *
@@ -38,20 +29,6 @@ class LanguageConfigFactoryOverride extends ConfigFactoryOverrideBase implements
   */
  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.
   *
@@ -59,25 +36,28 @@ class LanguageConfigFactoryOverride extends ConfigFactoryOverrideBase implements
   */
  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;
  public function __construct(protected StorageInterface $baseStorage, protected EventDispatcherInterface $eventDispatcher, protected TypedConfigManagerInterface $typedConfigManager, LanguageDefault $default_language, protected ?array $defaultLanguageValues, protected ?bool $translateEnglish = TRUE) {
    // Prior to negotiation the override language should be the default
    // language.
    $this->language = $default_language->get();
    if ($this->defaultLanguageValues === NULL) {
      @trigger_error('Not passing the language.default_values parameter to LanguageConfigFactoryOverride::__construct() is deprecated in drupal:11.3.0 and will be removed in drupal::12.0.0. See https://www.drupal.org/project/drupal/issues/3518992');
      $this->defaultLanguageValues = \Drupal::getContainer()->getParameter('language.default_values');
    }
    if ($this->translateEnglish === NULL) {
      @trigger_error('Not passing the language.translate_english parameter to LanguageConfigFactoryOverride::__construct() is deprecated in drupal:11.3.0 and will be removed in drupal::12.0.0. See https://www.drupal.org/project/drupal/issues/3518992');
      $this->translateEnglish = \Drupal::getContainer()->getParameter('language.translate_english');
    }
  }

  /**
   * Checks whether overrides should be loaded.
   */
  protected function shouldSkipOverrides(): bool {
    return $this->language
      && $this->language->getId() === 'en'
      && $this->defaultLanguageValues['id'] === 'en'
      && !$this->translateEnglish;
  }

  /**
@@ -115,9 +95,16 @@ public function getOverride($langcode, $name) {
   * {@inheritdoc}
   */
  public function getStorage($langcode) {
    // Skip loading overrides when English is the default language and the
    // passed in langcode is English.
    if (!isset($this->storages[$langcode])) {
      if ($langcode === 'en' && $this->shouldSkipOverrides()) {
        $this->storages[$langcode] = new NullStorage($this->createConfigCollectionName($langcode));
      }
      else {
        $this->storages[$langcode] = $this->baseStorage->createCollection($this->createConfigCollectionName($langcode));
      }
    }
    return $this->storages[$langcode];
  }

+2 −0
Original line number Diff line number Diff line
@@ -43,3 +43,5 @@ services:
  locale.locale_translation_cache_tag:
    class: Drupal\locale\EventSubscriber\LocaleTranslationCacheTag
    arguments: ['@cache_tags.invalidator']
  Drupal\locale\EventSubscriber\ConfigSubscriber:
    autowire: true
+41 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\locale\EventSubscriber;

use Drupal\Core\DrupalKernel;
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Rebuilds the container when locale config is changed.
 */
class ConfigSubscriber implements EventSubscriberInterface {

  public function __construct(#[Autowire(service: 'kernel')] private DrupalKernel $kernel) {
  }

  /**
   * Causes the container to be rebuilt on the next request if necessary.
   *
   * @param \Drupal\Core\Config\ConfigCrudEvent $event
   *   The configuration event.
   */
  public function onConfigSave(ConfigCrudEvent $event): void {
    $saved_config = $event->getConfig();
    if (!$saved_config->isNew() && $saved_config->getName() == 'locale.settings' && $event->isChanged('translate_english')) {
      // Trigger a container rebuild on the next request by invalidating it.
      $this->kernel->invalidateContainer();
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    $events[ConfigEvents::SAVE][] = ['onConfigSave', 0];
    return $events;
  }

}
+27 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\locale;

use Drupal\Core\Config\BootstrapConfigStorageFactory;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;

/**
 * Overrides the language_manager service to point to language's module one.
 */
class LocaleServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container): void {
    if ($container->hasParameter('language.translate_english')) {
      $config_storage = BootstrapConfigStorageFactory::get();
      $config = $config_storage->read('locale.settings');
      if ($config) {
        $container->setParameter('language.translate_english', $config['translate_english'] ?? TRUE);
      }
    }
  }

}
Loading