diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php index 9f471095680..962ce9fe8a4 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php @@ -144,7 +144,10 @@ class LanguageNegotiationSession extends LanguageNegotiationMethodBase implement foreach ($this->languageManager->getNativeLanguages() as $language) { $langcode = $language->getId(); $links[$langcode] = array( - 'url' => $url, + // We need to clone the $url object to avoid using the same one for all links. + // When the links are rendered, options are set on the $url object, + // so if we use the same one, they would be set for all links. + 'url' => clone $url, 'title' => $language->getName(), 'attributes' => array('class' => array('language-link')), 'query' => $query, diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php index ef6891c9b7b..2a595ab9144 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php @@ -200,7 +200,10 @@ class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements In foreach ($this->languageManager->getNativeLanguages() as $language) { $links[$language->getId()] = array( - 'url' => $url, + // We need to clone the $url object to avoid using the same one for all links. + // When the links are rendered, options are set on the $url object, + // so if we use the same one, they would be set for all links. + 'url' => clone $url, 'title' => $language->getName(), 'language' => $language, 'attributes' => array('class' => array('language-link')), diff --git a/core/modules/language/src/Tests/LanguageSwitchingTest.php b/core/modules/language/src/Tests/LanguageSwitchingTest.php index 3bd64672cc8..1b96203fc90 100644 --- a/core/modules/language/src/Tests/LanguageSwitchingTest.php +++ b/core/modules/language/src/Tests/LanguageSwitchingTest.php @@ -9,6 +9,7 @@ namespace Drupal\language\Tests; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; +use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\Core\Language\LanguageInterface; use Drupal\simpletest\WebTestBase; @@ -24,7 +25,7 @@ class LanguageSwitchingTest extends WebTestBase { * * @var array */ - public static $modules = array('locale', 'language', 'block', 'language_test'); + public static $modules = array('locale', 'language', 'block', 'language_test', 'menu_ui'); protected function setUp() { parent::setUp(); @@ -392,6 +393,58 @@ class LanguageSwitchingTest extends WebTestBase { $this->assertTrue(isset($links[0]), t('A link generated by :function to the current :language page with langcode :langcode is marked active.', array(':function' => $function_name, ':language' => $current_language, ':langcode' => $langcode))); } + /** + * Test language switcher links for session based negotiation. + */ + function testLanguageSessionSwitchLinks() { + // Add language. + $edit = array( + 'predefined_langcode' => 'fr', + ); + $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); + + // Enable session language detection and selection. + $edit = array( + 'language_interface[enabled][language-url]' => FALSE, + 'language_interface[enabled][language-session]' => TRUE, + ); + $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); + + // Enable the language switching block. + $this->drupalPlaceBlock('language_block:' . LanguageInterface::TYPE_INTERFACE, array( + 'id' => 'test_language_block', + )); + + // Enable the main menu block. + $this->drupalPlaceBlock('system_menu_block:main', array( + 'id' => 'test_menu', + )); + + // Add a link to the homepage. + $link = MenuLinkContent::create([ + 'title' => 'Home', + 'menu_name' => 'main', + 'bundle' => 'menu_link_content', + 'link' => [['uri' => 'entity:user/2']], + ]); + $link->save(); + + // Go to the homepage. + $this->drupalGet(''); + // Click on the French link. + $this->clickLink(t('French')); + // There should be a query parameter to set the session language. + $this->assertUrl('user/2', ['query' => ['language' => 'fr']]); + // Click on the 'Home' Link. + $this->clickLink(t('Home')); + // There should be no query parameter. + $this->assertUrl('user/2'); + // Click on the French link. + $this->clickLink(t('French')); + // There should be no query parameter. + $this->assertUrl('user/2'); + } + /** * Saves the native name of a language entity in configuration as a label. *