diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index 22c5289..c38fc10 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -188,6 +188,8 @@ public function getLanguageName($langcode) { */ public function getDefaultLockedLanguages($weight = 0) { $languages = array(); + // By default set a high weight. + $weight = max($weight, 97); $locked_language = array( 'default' => FALSE, diff --git a/core/modules/ckeditor/src/Tests/CKEditorTest.php b/core/modules/ckeditor/src/Tests/CKEditorTest.php index caf0345..b0bdce8 100644 --- a/core/modules/ckeditor/src/Tests/CKEditorTest.php +++ b/core/modules/ckeditor/src/Tests/CKEditorTest.php @@ -382,7 +382,8 @@ function testLanguages() { * Tests that CKEditor plugins participate in JS translation. */ function testJSTranslation() { - $this->enableModules(array('language', 'locale')); + $this->enableModules(array('locale')); + $this->installConfig(['language']); $this->installSchema('locale', 'locales_source'); $this->installSchema('locale', 'locales_location'); $this->installSchema('locale', 'locales_target'); diff --git a/core/modules/language/config/install/language.entity.und.yml b/core/modules/language/config/install/language.entity.und.yml index 67caf48..9db876b 100644 --- a/core/modules/language/config/install/language.entity.und.yml +++ b/core/modules/language/config/install/language.entity.und.yml @@ -1,7 +1,7 @@ id: und label: 'Not specified' direction: 'ltr' -weight: 1 +weight: 98 locked: true status: true langcode: en diff --git a/core/modules/language/config/install/language.entity.zxx.yml b/core/modules/language/config/install/language.entity.zxx.yml index 7f02cf7..9c88e04 100644 --- a/core/modules/language/config/install/language.entity.zxx.yml +++ b/core/modules/language/config/install/language.entity.zxx.yml @@ -1,7 +1,7 @@ id: zxx label: 'Not applicable' direction: 'ltr' -weight: 2 +weight: 99 locked: true status: true langcode: en diff --git a/core/modules/language/src/Entity/ConfigurableLanguage.php b/core/modules/language/src/Entity/ConfigurableLanguage.php index a754654..44b96fd 100644 --- a/core/modules/language/src/Entity/ConfigurableLanguage.php +++ b/core/modules/language/src/Entity/ConfigurableLanguage.php @@ -72,7 +72,7 @@ class ConfigurableLanguage extends ConfigEntityBase implements ConfigurableLangu * * @var integer */ - protected $weight = 0; + protected $weight = NULL; /** * Locked languages cannot be edited. @@ -121,6 +121,16 @@ public function preSave(EntityStorageInterface $storage) { // For the uncommon case of custom languages the label should be given in // English. $this->langcode = 'en'; + + // When adding a new language the weight shouldn't be zero to avoid a + // reordering of the languages list when their names change i.e. interface + // translation. + if (is_null($this->getWeight())) { + // Fetch all configurable languages ordered by weight. + $languages = \Drupal::languageManager()->getLanguages($this::STATE_CONFIGURABLE); + $last_language = end($languages); + $this->setWeight($last_language->getWeight() + 1); + } } /** @@ -131,7 +141,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { $language_manager = \Drupal::languageManager(); $language_manager->reset(); - if (!$this->isLocked() && $language_manager instanceof ConfigurableLanguageManagerInterface) { + if (!$this->isLocked() && $language_manager instanceof ConfigurableLanguageManagerInterface && !$this->isSyncing()) { $language_manager->updateLockedLanguageWeights(); } @@ -173,7 +183,8 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti parent::postDelete($storage, $entities); $language_manager = \Drupal::languageManager(); $language_manager->reset(); - if ($language_manager instanceof ConfigurableLanguageManagerInterface) { + $entity = reset($entities); + if ($language_manager instanceof ConfigurableLanguageManagerInterface && !$entity->isUninstalling() && !$entity->isSyncing()) { $language_manager->updateLockedLanguageWeights(); } // If after deleting this language the site will become monolingual, we need diff --git a/core/modules/language/src/Tests/LanguageConfigurationTest.php b/core/modules/language/src/Tests/LanguageConfigurationTest.php index a5efb2f..d94fcf4 100644 --- a/core/modules/language/src/Tests/LanguageConfigurationTest.php +++ b/core/modules/language/src/Tests/LanguageConfigurationTest.php @@ -8,6 +8,7 @@ namespace Drupal\language\Tests; use Drupal\Core\Language\LanguageInterface; +use Drupal\language\Entity\ConfigurableLanguage; use Drupal\simpletest\WebTestBase; /** @@ -28,6 +29,9 @@ class LanguageConfigurationTest extends WebTestBase { * Functional tests for adding, editing and deleting languages. */ function testLanguageConfiguration() { + // Ensure the after installing the language module the weight of the english + // language is still 0. + $this->assertEqual(ConfigurableLanguage::load('en')->getWeight(), 0, 'The english language has a weight of 0.'); // User to add and remove language. $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages')); @@ -103,6 +107,24 @@ function testLanguageConfiguration() { $this->drupalPostForm('admin/config/regional/language/delete/en', array(), t('Delete')); $this->rebuildContainer(); $this->assertRaw(t('The %language (%langcode) language has been removed.', array('%language' => 'English', '%langcode' => 'en'))); + + // Ensure that french language has a weight of 1 after being created through the UI. + $french = ConfigurableLanguage::load('fr'); + $this->assertEqual($french->getWeight(), 1, 'The French language has a weight of 1.'); + // Ensure that french language can now have a weight of 0. + $french->setWeight(0)->save(); + $this->assertEqual($french->getWeight(), 0, 'The French language has a weight of 0.'); + // Ensure that new languages get the last weight by default. + $afrikaans = ConfigurableLanguage::createFromLangcode('af'); + $afrikaans->save(); + $this->assertEqual($afrikaans->getWeight(), 1, 'The Afrikaans language has a weight of 1.'); + $afrikaans->setWeight(0)->save(); + $this->assertEqual($afrikaans->getWeight(), 0, 'The Afrikaans language has a weight of 0.'); + // Ensure that a new language can be created with a weight of 0. + $arabic = ConfigurableLanguage::createFromLangcode('ar'); + $arabic->setWeight(0)->save(); + $this->assertEqual($arabic->getWeight(), 0, 'The Arabic language has a weight of 0.'); + $edit = array( 'predefined_langcode' => 'de', ); diff --git a/core/modules/language/src/Tests/LanguageListTest.php b/core/modules/language/src/Tests/LanguageListTest.php index 8ec846c..608485e 100644 --- a/core/modules/language/src/Tests/LanguageListTest.php +++ b/core/modules/language/src/Tests/LanguageListTest.php @@ -35,6 +35,10 @@ function testLanguageList() { $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages')); $this->drupalLogin($admin_user); + // Get the weight of the last language. + $languages = \Drupal::service('language_manager')->getLanguages(); + $last_language_weight = end($languages)->getWeight(); + // Add predefined language. $edit = array( 'predefined_langcode' => 'fr', @@ -43,6 +47,14 @@ function testLanguageList() { $this->assertText('French', 'Language added successfully.'); $this->assertUrl(\Drupal::url('entity.configurable_language.collection', [], ['absolute' => TRUE])); + // Get the weight of the last language and check that the weight is one unit + // heavier than the last configurable language. + $this->rebuildContainer(); + $languages = \Drupal::service('language_manager')->getLanguages(); + $last_language = end($languages); + $this->assertEqual($last_language->getWeight(), $last_language_weight + 1); + $this->assertEqual($last_language->getId(), $edit['predefined_langcode']); + // Add custom language. $langcode = 'xx'; $name = $this->randomMachineName(16); diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php index 2e8a3b3..98362a7 100644 --- a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php @@ -504,7 +504,8 @@ protected function doTestLanguageFallback($entity_type) { $langcode_key = $this->entityManager->getDefinition($entity_type)->getKey('langcode'); $languages = $this->languageManager->getLanguages(); $language = ConfigurableLanguage::load($languages[$langcode]->getId()); - $language->set('weight', 1); + // Make $language the last. + $language->set('weight', 4); $language->save(); $this->languageManager->reset();