summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2018-11-14 12:47:16 (GMT)
committerAlex Pott2018-11-14 12:47:23 (GMT)
commit3788f65ad4d2e750efc7fee851efec005dcbba6b (patch)
tree01c925e3f91f2a6e6ea3e8140f1e29b94794244d
parent9c94695902d4a610aa81d593eabfdff10176d471 (diff)
Issue #2189267 by Manuel Garcia, snufkin, alexpott, nuez, maxocub, mirsoft, SiliconMind, blazey, mErilainen, wannesderoy, borisson_, Gábor Hojtsy, stella, spoit, swentel, lauriii, Rob230, Xano, danquah: When content language detection is different from interface language detection, the detected language is not applied to the rendered content
(cherry picked from commit edfebee5393e74a9f8a6bd9bf0b805ba54d0aaa0)
-rw-r--r--core/modules/language/src/ConfigurableLanguageManager.php12
-rw-r--r--core/modules/language/tests/src/Functional/ConfigurableLanguageManagerTest.php189
2 files changed, 195 insertions, 6 deletions
diff --git a/core/modules/language/src/ConfigurableLanguageManager.php b/core/modules/language/src/ConfigurableLanguageManager.php
index 13079f8..25927b5 100644
--- a/core/modules/language/src/ConfigurableLanguageManager.php
+++ b/core/modules/language/src/ConfigurableLanguageManager.php
@@ -90,11 +90,11 @@ class ConfigurableLanguageManager extends LanguageManager implements Configurabl
protected $initialized = FALSE;
/**
- * Whether already in the process of language initialization.
+ * Whether language types are in the process of language initialization.
*
- * @var bool
+ * @var bool[]
*/
- protected $initializing = FALSE;
+ protected $initializing = [];
/**
* {@inheritdoc}
@@ -213,12 +213,12 @@ class ConfigurableLanguageManager extends LanguageManager implements Configurabl
$this->negotiatedLanguages[$type] = $this->getDefaultLanguage();
if ($this->negotiator && $this->isMultilingual()) {
- if (!$this->initializing) {
- $this->initializing = TRUE;
+ if (!isset($this->initializing[$type])) {
+ $this->initializing[$type] = TRUE;
$negotiation = $this->negotiator->initializeType($type);
$this->negotiatedLanguages[$type] = reset($negotiation);
$this->negotiatedMethods[$type] = key($negotiation);
- $this->initializing = FALSE;
+ unset($this->initializing[$type]);
}
// If the current interface language needs to be retrieved during
// initialization we return the system language. This way string
diff --git a/core/modules/language/tests/src/Functional/ConfigurableLanguageManagerTest.php b/core/modules/language/tests/src/Functional/ConfigurableLanguageManagerTest.php
new file mode 100644
index 0000000..d36aee0
--- /dev/null
+++ b/core/modules/language/tests/src/Functional/ConfigurableLanguageManagerTest.php
@@ -0,0 +1,189 @@
+<?php
+
+namespace Drupal\Tests\language\Functional;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\language\Entity\ContentLanguageSettings;
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests Language Negotiation.
+ *
+ * Uses different negotiators for content and interface.
+ *
+ * @group language
+ */
+class ConfigurableLanguageManagerTest extends BrowserTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = [
+ 'language',
+ 'content_translation',
+ 'node',
+ 'locale',
+ 'block',
+ 'system',
+ 'user',
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ /** @var \Drupal\user\UserInterface $user */
+ $user = $this->createUser([], '', TRUE);
+ $this->drupalLogin($user);
+ ConfigurableLanguage::createFromLangcode('es')->save();
+
+ // Create a page node type and make it translatable.
+ NodeType::create([
+ 'type' => 'page',
+ 'name' => t('Page'),
+ ])->save();
+
+ $config = ContentLanguageSettings::loadByEntityTypeBundle('node', 'page');
+ $config->setDefaultLangcode('en')
+ ->setLanguageAlterable(TRUE)
+ ->save();
+
+ // Create a Node with title 'English' and translate it to Spanish.
+ $node = Node::create([
+ 'type' => 'page',
+ 'title' => 'English',
+ ]);
+ $node->save();
+ $node->addTranslation('es', ['title' => 'Español']);
+ $node->save();
+
+ // Enable both language_interface and language_content language negotiation.
+ \Drupal::getContainer()->get('language_negotiator')->updateConfiguration([
+ 'language_interface',
+ 'language_content',
+ ]);
+
+ // Set the preferred language of the user for admin pages to English.
+ $user->set('preferred_admin_langcode', 'en')->save();
+
+ // Make sure node edit pages are administration pages.
+ $this->config('node.settings')->set('use_admin_theme', '1')->save();
+ $this->container->get('router.builder')->rebuild();
+
+ // Place a Block with a translatable string on the page.
+ $this->placeBlock('system_powered_by_block', ['region' => 'content']);
+
+ // Load the Spanish Node page once, to register the translatable string.
+ $this->drupalGet('/es/node/1');
+
+ // Translate the Powered by string.
+ /** @var \Drupal\locale\StringStorageInterface $string_storage */
+ $string_storage = \Drupal::getContainer()->get('locale.storage');
+ $source = $string_storage->findString(['source' => 'Powered by <a href=":poweredby">Drupal</a>']);
+ $string_storage->createTranslation([
+ 'lid' => $source->lid,
+ 'language' => 'es',
+ 'translation' => 'Funciona con ...',
+ ])->save();
+ // Invalidate caches so that the new translation will be used.
+ Cache::invalidateTags(['rendered', 'locale']);
+ }
+
+ /**
+ * Test translation with URL and Preferred Admin Language negotiators.
+ *
+ * The interface language uses the preferred language for admin pages of the
+ * user and after that the URL. The Content uses just the URL.
+ */
+ public function testUrlContentTranslationWithPreferredAdminLanguage() {
+ $assert_session = $this->assertSession();
+ // Set the interface language to use the preferred administration language
+ // and then the URL.
+ /** @var \Drupal\language\LanguageNegotiatorInterface $language_negotiator */
+ $language_negotiator = \Drupal::getContainer()->get('language_negotiator');
+ $language_negotiator->saveConfiguration('language_interface', [
+ 'language-user-admin' => 1,
+ 'language-url' => 2,
+ 'language-selected' => 3,
+ ]);
+ // Set Content Language Negotiator to use just the URL.
+ $language_negotiator->saveConfiguration('language_content', [
+ 'language-url' => 4,
+ 'language-selected' => 5,
+ ]);
+
+ // See if the full view of the node in english is present and the
+ // string in the Powered By Block is in English.
+ $this->drupalGet('/node/1');
+ $assert_session->pageTextContains('English');
+ $assert_session->pageTextContains('Powered by');
+
+ // Load the spanish node page again and see if both the node and the string
+ // are translated.
+ $this->drupalGet('/es/node/1');
+ $assert_session->pageTextContains('Español');
+ $assert_session->pageTextContains('Funciona con');
+ $assert_session->pageTextNotContains('Powered by');
+
+ // Check if the Powered by string is shown in English on an
+ // administration page, and the node content is shown in Spanish.
+ $this->drupalGet('/es/node/1/edit');
+ $assert_session->pageTextContains('Español');
+ $assert_session->pageTextContains('Powered by');
+ $assert_session->pageTextNotContains('Funciona con');
+ }
+
+ /**
+ * Test translation with URL and Session Language Negotiators.
+ */
+ public function testUrlContentTranslationWithSessionLanguage() {
+ $assert_session = $this->assertSession();
+ /** @var \Drupal\language\LanguageNegotiatorInterface $language_negotiator */
+ $language_negotiator = \Drupal::getContainer()->get('language_negotiator');
+ // Set Interface Language Negotiator to Session.
+ $language_negotiator->saveConfiguration('language_interface', [
+ 'language-session' => 1,
+ 'language-url' => 2,
+ 'language-selected' => 3,
+ ]);
+
+ // Set Content Language Negotiator to URL.
+ $language_negotiator->saveConfiguration('language_content', [
+ 'language-url' => 4,
+ 'language-selected' => 5,
+ ]);
+
+ // See if the full view of the node in english is present and the
+ // string in the Powered By Block is in English.
+ $this->drupalGet('/node/1');
+ $assert_session->pageTextContains('English');
+ $assert_session->pageTextContains('Powered by');
+
+ // The language session variable has not been set yet, so
+ // The string should be in Spanish.
+ $this->drupalGet('/es/node/1');
+ $assert_session->pageTextContains('Español');
+ $assert_session->pageTextNotContains('Powered by');
+ $assert_session->pageTextContains('Funciona con');
+
+ // Set the session language to Spanish but load the English node page.
+ $this->drupalGet('/node/1', ['query' => ['language' => 'es']]);
+ $assert_session->pageTextContains('English');
+ $assert_session->pageTextNotContains('Español');
+ $assert_session->pageTextContains('Funciona con');
+ $assert_session->pageTextNotContains('Powered by');
+
+ // Set the session language to English but load the node page in Spanish.
+ $this->drupalGet('/es/node/1', ['query' => ['language' => 'en']]);
+ $assert_session->pageTextNotContains('English');
+ $assert_session->pageTextContains('Español');
+ $assert_session->pageTextNotContains('Funciona con');
+ $assert_session->pageTextContains('Powered by');
+ }
+
+}