Unverified Commit a5d3407d authored by Alex Pott's avatar Alex Pott
Browse files

fix: #3600904 Shipped configuration entities that do not have translatable...

fix: #3600904 Shipped configuration entities that do not have translatable elements are not set to the site default langcode

By: gábor hojtsy
By: roderik
(cherry picked from commit 73847ce0)
parent 83a5f2b4
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ class LangcodeRequiredIfTranslatableValuesConstraint extends SymfonyConstraint {
  public function __construct(
    mixed $options = NULL,
    public string $missingMessage = "The @name config object must specify a language code, because it contains translatable values.",
    public string $entityMessage = "The @name config object must specify a language code, because it is a configuration entity.",
    public string $superfluousMessage = "The @name config object does not contain any translatable values, so it should not specify a language code.",
    ?array $groups = NULL,
    mixed $payload = NULL,
+9 −3
Original line number Diff line number Diff line
@@ -33,9 +33,15 @@ public function validate(mixed $value, Constraint $constraint): void {
    assert(in_array('langcode', $mapping->getValidKeys(), TRUE));

    $is_translatable = $mapping->hasTranslatableElements();

    if ($is_translatable && !array_key_exists('langcode', $value)) {
      $this->context->buildViolation($constraint->missingMessage)
    $is_config_entity = \Drupal::service('config.manager')->getEntityTypeIdByName($mapping->getName()) !== NULL;

    // Require a langcode for translatable configuration and for config
    // entities. Configuration entities that currently do not have translatable
    // elements but do not have a langcode key are not valid because they may
    // receive translatable elements later outside of the entity's control,
    // eg. third party settings.
    if (($is_translatable || $is_config_entity) && !array_key_exists('langcode', $value)) {
      $this->context->buildViolation($is_config_entity ? $constraint->entityMessage : $constraint->missingMessage)
        ->setParameter('@name', $mapping->getName())
        ->addViolation();
      return;
+5 −5
Original line number Diff line number Diff line
@@ -682,12 +682,12 @@ public function updateDefaultConfigLangcodes() {
        // module is enabled later, then some configuration may not exist
        // anymore.
        if (!$config->isNew()) {
          $typed_config = $this->typedConfigManager->createFromNameAndData($config->getName(), $config->getRawData());
          $langcode = $config->get('langcode');
          // Only set a `langcode` if this config actually contains translatable
          // data.
          // @see \Drupal\Core\Config\Plugin\Validation\Constraint\LangcodeRequiredIfTranslatableValuesConstraint
          if (!empty($this->getTranslatableData($typed_config)) && (empty($langcode) || $langcode == 'en')) {
          $typed_config = $this->typedConfigManager->createFromNameAndData($config->getName(), $config->getRawData());
          // Translatable simple configuration and any configuration entity
          // should get the site language code even when they do not currently
          // have translatable data.
          if (($this->configManager->getEntityTypeIdByName($config->getName()) || !empty($this->getTranslatableData($typed_config))) && (empty($langcode) || $langcode == 'en')) {
            $config->set('langcode', $default_langcode)->save();
          }
        }
+25 −0
Original line number Diff line number Diff line
@@ -165,6 +165,8 @@ public function testTranslationsLoaded(): void {
    // Spanish is always an override (never used as installation language).
    $this->assertEquals('Anonymous es', $override_es->get('anonymous'));

    // Verify that config entities get the correct language assumptions.
    $this->verifyConfigLanguageAssumptions();
  }

  /**
@@ -187,4 +189,27 @@ protected function verifyImportedStringsTranslated(): void {
    }
  }

  /**
   * Verifies config entity and simple config langcode assumptions.
   */
  protected function verifyConfigLanguageAssumptions(): void {
    if ($this->langcode === 'en') {
      return;
    }

    $config_factory = \Drupal::configFactory();
    foreach (['language.entity.de', 'language.entity.es'] as $config_name) {
      $this->assertEquals(
        $this->langcode,
        $config_factory->get($config_name)->get('langcode'),
        "Config entity '$config_name' should use the installation language langcode."
      );
    }

    $this->assertNull(
      $config_factory->get('system.performance')->get('langcode'),
      'Non-entity config without translatable data should not be rewritten to the installation language.'
    );
  }

}