From 67c8a34c07e3b41d155a4630cc6793dc37f2471d Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 10 Sep 2014 12:02:58 +0100
Subject: [PATCH] =?UTF-8?q?Issue=20#2107427=20by=20penyaskito,=20dclavain,?=
 =?UTF-8?q?=20G=C3=A1bor=20Hojtsy,=20mashermike,=20Aron=20Novak,=20YesCT,?=
 =?UTF-8?q?=20szato,=20Wim=20Leers,=20mikispeed,=20vijaycs85:=20Fixed=20Re?=
 =?UTF-8?q?gression:=20Language=20names=20should=20display=20in=20their=20?=
 =?UTF-8?q?native=20names=20in=20the=20language=20switcher=20block.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Drupal/Core/Language/LanguageManager.php  |  8 ++++
 .../Language/LanguageManagerInterface.php     |  9 +++++
 .../src/ConfigurableLanguageManager.php       | 21 +++++++++-
 .../LanguageNegotiationSession.php            |  4 +-
 .../LanguageNegotiationUrl.php                |  4 +-
 .../src/Tests/LanguageSwitchingTest.php       | 38 +++++++++++++++----
 6 files changed, 71 insertions(+), 13 deletions(-)

diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php
index 2b8153343dbf..35a3fad82348 100644
--- a/core/lib/Drupal/Core/Language/LanguageManager.php
+++ b/core/lib/Drupal/Core/Language/LanguageManager.php
@@ -162,6 +162,14 @@ public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) {
     return $filtered_languages;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getNativeLanguages() {
+    // In a language unaware site we don't have translated languages.
+    return $this->getLanguages();
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php
index 0bbf453651cc..8f1993620ec5 100644
--- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php
+++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php
@@ -97,6 +97,15 @@ public function getDefaultLanguage();
    */
   public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE);
 
+  /**
+   * Returns a list of languages set up on the site in their native form.
+   *
+   * @return \Drupal\Core\Language\LanguageInterface[]
+   *   An associative array of languages, keyed by the language code, ordered
+   *   by weight ascending and name ascending.
+   */
+  public function getNativeLanguages();
+
   /**
    * Returns a language object from the given language code.
    *
diff --git a/core/modules/language/src/ConfigurableLanguageManager.php b/core/modules/language/src/ConfigurableLanguageManager.php
index 4594547311e9..64c88ac9e338 100644
--- a/core/modules/language/src/ConfigurableLanguageManager.php
+++ b/core/modules/language/src/ConfigurableLanguageManager.php
@@ -15,6 +15,7 @@
 use Drupal\Core\Language\LanguageDefault;
 use Drupal\Core\Language\LanguageManager;
 use Drupal\language\Config\LanguageConfigFactoryOverrideInterface;
+use Drupal\language\Entity\ConfigurableLanguage;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
 
@@ -272,7 +273,7 @@ public function getLanguages($flags = BaseLanguageInterface::STATE_CONFIGURABLE)
       $default = $this->getDefaultLanguage();
       $this->languages = array($default->id => $default);
 
-      // Retrieve the config storage to list available languages.
+      // Retrieve the list of languages defined in configuration.
       $prefix = 'language.entity.';
       $config_ids = $this->configFactory->listAll($prefix);
 
@@ -299,6 +300,24 @@ public function getLanguages($flags = BaseLanguageInterface::STATE_CONFIGURABLE)
     return parent::getLanguages($flags);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getNativeLanguages() {
+    $languages = $this->getLanguages(BaseLanguageInterface::STATE_CONFIGURABLE);
+    $natives = array();
+
+    $original_language = $this->getConfigOverrideLanguage();
+
+    foreach ($languages as $langcode => $language) {
+      $this->setConfigOverrideLanguage($language);
+      $natives[$langcode] = ConfigurableLanguage::load($langcode);
+    }
+    $this->setConfigOverrideLanguage($original_language);
+    Language::sort($natives);
+    return $natives;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php
index 8cf294af6da1..384e7655ac47 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php
@@ -131,11 +131,11 @@ function getLanguageSwitchLinks(Request $request, $type, $path) {
     $query = array();
     parse_str($request->getQueryString(), $query);
 
-    foreach ($this->languageManager->getLanguages() as $language) {
+    foreach ($this->languageManager->getNativeLanguages() as $language) {
       $langcode = $language->id;
       $links[$langcode] = array(
         'href' => $path,
-        'title' => $language->name,
+        '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 f2c3330b4301..be9f91561b98 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
@@ -190,10 +190,10 @@ public function processOutbound($path, &$options = array(), Request $request = N
   function getLanguageSwitchLinks(Request $request, $type, $path) {
     $links = array();
 
-    foreach ($this->languageManager->getLanguages() as $language) {
+    foreach ($this->languageManager->getNativeLanguages() as $language) {
       $links[$language->id] = array(
         'href' => $path,
-        'title' => $language->name,
+        '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 4f803dfa23b2..d6ed5ef379a9 100644
--- a/core/modules/language/src/Tests/LanguageSwitchingTest.php
+++ b/core/modules/language/src/Tests/LanguageSwitchingTest.php
@@ -22,7 +22,7 @@ class LanguageSwitchingTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('language', 'block', 'language_test');
+  public static $modules = array('locale', 'language', 'block', 'language_test');
 
   protected function setUp() {
     parent::setUp();
@@ -36,23 +36,26 @@ protected function setUp() {
    * Functional tests for the language switcher block.
    */
   function testLanguageBlock() {
-    // Enable the language switching block..
-    $block = $this->drupalPlaceBlock('language_block:' . LanguageInterface::TYPE_INTERFACE, array(
-      'id' => 'test_language_block',
-      // Ensure a 2-byte UTF-8 sequence is in the tested output.
-      'label' => $this->randomMachineName(8) . '×',
-    ));
-
     // Add language.
     $edit = array(
       'predefined_langcode' => 'fr',
     );
     $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
 
+    // Set the native language name.
+    $this->saveNativeLanguageName('fr', 'français');
+
     // Enable URL language detection and selection.
     $edit = array('language_interface[enabled][language-url]' => '1');
     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
 
+    // Enable the language switching block.
+    $block = $this->drupalPlaceBlock('language_block:' . LanguageInterface::TYPE_INTERFACE, array(
+      'id' => 'test_language_block',
+      // Ensure a 2-byte UTF-8 sequence is in the tested output.
+      'label' => $this->randomMachineName(8) . '×',
+    ));
+
     $this->doTestLanguageBlockAuthenticated($block->label());
     $this->doTestLanguageBlockAnonymous($block->label());
   }
@@ -75,6 +78,7 @@ protected function doTestLanguageBlockAuthenticated($block_label) {
     list($language_switcher) = $this->xpath('//div[@id=:id]/div[contains(@class, "content")]', array(':id' => 'block-test-language-block'));
     $list_items = array();
     $anchors = array();
+    $labels = array();
     foreach ($language_switcher->ul->li as $list_item) {
       $classes = explode(" ", (string) $list_item['class']);
       list($langcode) = array_intersect($classes, array('en', 'fr'));
@@ -86,6 +90,7 @@ protected function doTestLanguageBlockAuthenticated($block_label) {
         'hreflang' => (string) $list_item->a['hreflang'],
         'data-drupal-link-system-path' => (string) $list_item->a['data-drupal-link-system-path'],
       );
+      $labels[] = (string) $list_item->a;
     }
     $expected_list_items = array(
       0 => array('langcode_class' => 'en', 'data-drupal-link-system-path' => 'user/2'),
@@ -101,6 +106,7 @@ protected function doTestLanguageBlockAuthenticated($block_label) {
     $this->assertIdentical($settings['path']['currentPath'], 'user/2', 'drupalSettings.path.currentPath is set correctly to allow drupal.active-link to mark the correct links as active.');
     $this->assertIdentical($settings['path']['isFront'], FALSE, 'drupalSettings.path.isFront is set correctly to allow drupal.active-link to mark the correct links as active.');
     $this->assertIdentical($settings['path']['currentLanguage'], 'en', 'drupalSettings.path.currentLanguage is set correctly to allow drupal.active-link to mark the correct links as active.');
+    $this->assertIdentical($labels, array('English', 'français'), 'The language links labels are in their own language on the language switcher block.');
   }
 
   /**
@@ -128,6 +134,7 @@ protected function doTestLanguageBlockAnonymous($block_label) {
       'active' => array(),
       'inactive' => array(),
     );
+    $labels = array();
     foreach ($language_switcher->ul->li as $link) {
       $classes = explode(" ", (string) $link['class']);
       list($langcode) = array_intersect($classes, array('en', 'fr'));
@@ -144,9 +151,11 @@ protected function doTestLanguageBlockAnonymous($block_label) {
       else {
         $anchors['inactive'][] = $langcode;
       }
+      $labels[] = (string) $link->a;
     }
     $this->assertIdentical($links, array('active' => array('en'), 'inactive' => array('fr')), 'Only the current language list item is marked as active on the language switcher block.');
     $this->assertIdentical($anchors, array('active' => array('en'), 'inactive' => array('fr')), 'Only the current language anchor is marked as active on the language switcher block.');
+    $this->assertIdentical($labels, array('English', 'français'), 'The language links labels are in their own language on the language switcher block.');
   }
 
   /**
@@ -276,4 +285,17 @@ protected function doTestLanguageLinkActiveClassAnonymous() {
     $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)));
   }
 
+  /**
+   * Saves the native name of a language entity in configuration as a label.
+   *
+   * @param string $langcode
+   *   The language code of the language.
+   * @param string $label
+   *   The native name of the language.
+   */
+  protected function saveNativeLanguageName($langcode, $label) {
+    \Drupal::service('language.config_factory_override')
+      ->getOverride($langcode, 'language.entity.' . $langcode)->set('label', $label)->save();
+  }
+
 }
-- 
GitLab