Commit 45e59c9b authored by webchick's avatar webchick

Issue #2234623 by alexpott, penyaskito: Move language add logic out of language_save() .

parent c9ec67d6
......@@ -431,9 +431,7 @@ function language_save($language) {
$language_entity->direction = isset($language->direction) ? $language->direction : '0';
$language_entity->locked = !empty($language->locked);
$language_entity->weight = isset($language->weight) ? $language->weight : 0;
// Save the record and inform others about the change.
$multilingual = \Drupal::languageManager()->isMultilingual();
$language_entity->setDefault(!empty($language->default));
$language_entity->save();
$t_args = array('%language' => $language->name, '%langcode' => $language->id);
if ($language->is_new) {
......@@ -443,30 +441,6 @@ function language_save($language) {
watchdog('language', 'The %language (%langcode) language has been updated.', $t_args);
}
if (!empty($language->default)) {
// Update the config. Saving the configuration fires and event that causes
// the container to be rebuilt.
\Drupal::config('system.site')->set('langcode', $language->id)->save();
\Drupal::service('language.default')->set($language);
}
$language_manager = \Drupal::languageManager();
$language_manager->reset();
if ($language_manager instanceof ConfigurableLanguageManagerInterface) {
$language_manager->updateLockedLanguageWeights();
}
// Update URL Prefixes for all languages after the new default language is
// propagated and the LanguageManagerInterface::getLanguages() cache is
// flushed.
language_negotiation_url_prefixes_update();
// If after adding this language the site will become multilingual, we need to
// rebuild language services.
if (!$multilingual && $language->is_new) {
ConfigurableLanguageManager::rebuildServices();
}
return $language;
}
......
......@@ -92,7 +92,7 @@ class ConfigurableLanguageManager extends LanguageManager implements Configurabl
protected $initializing = FALSE;
/**
* Rebuild the container to register services needed on multilingual sites.
* {@inheritdoc}
*/
public static function rebuildServices() {
PhpStorageFactory::get('service_container')->deleteAll();
......
......@@ -16,6 +16,11 @@
*/
interface ConfigurableLanguageManagerInterface extends LanguageManagerInterface {
/**
* Rebuild the container to register services needed on multilingual sites.
*/
public static function rebuildServices();
/**
* Injects the request object.
*
......
......@@ -7,8 +7,10 @@
namespace Drupal\language\Entity;
use Drupal\Core\Language\Language as LanguageObject;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\language\ConfigurableLanguageManagerInterface;
use Drupal\language\Exception\DeleteDefaultLanguageException;
use Drupal\language\LanguageInterface;
......@@ -77,28 +79,160 @@ class Language extends ConfigEntityBase implements LanguageInterface {
*/
public $locked = FALSE;
/**
* Flag to indicate if the language entity is the default site language.
*
* This property is not saved to the language entity since there can be only
* one default language. It is saved to system.site:langcode and set on the
* container using the language.default service in when the entity is saved.
* The value is set correctly when a language entity is created or loaded.
*
* @see \Drupal\language\Entity\Language::postSave()
* @see \Drupal\language\Entity\Language::isDefault()
* @see \Drupal\language\Entity\Language::setDefault()
*
* @var bool
*/
protected $default;
/**
* Used during saving to detect when the site becomes multilingual.
*
* This property is not saved to the language entity, but is needed for
* detecting when to rebuild the services.
*
* @see \Drupal\language\Entity\Language::preSave()
* @see \Drupal\language\Entity\Language::postSave()
*
* @var bool
*/
protected $preSaveMultilingual;
/**
* Sets the default flag on the language entity.
*
* @param bool $default
*/
public function setDefault($default) {
$this->default = $default;
}
/**
* Checks if the language entity is the site default language.
*
* @return bool
* TRUE if the language entity is the site default language, FALSE if not.
*/
public function isDefault() {
if (!isset($this->default)) {
return static::getDefaultLangcode() == $this->id();
}
return $this->default;
}
/**
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
// Store whether or not the site is already multilingual so that we can
// rebuild services if necessary during
// \Drupal\language\Entity\Language::postSave().
$this->preSaveMultilingual = \Drupal::languageManager()->isMultilingual();
// Languages are picked from a predefined list which is given in English.
// For the uncommon case of custom languages the label should be given in
// English.
$this->langcode = 'en';
}
/**
* {@inheritdoc}
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
// Only set the default language and save it to system.site configuration if
// it needs to updated.
if ($this->isDefault() && static::getDefaultLangcode() != $this->id()) {
// Update the config. Saving the configuration fires and event that causes
// the container to be rebuilt.
\Drupal::config('system.site')->set('langcode', $this->id())->save();
\Drupal::service('language.default')->set($this->toLanguageObject());
}
$language_manager = \Drupal::languageManager();
$language_manager->reset();
if ($language_manager instanceof ConfigurableLanguageManagerInterface) {
$language_manager->updateLockedLanguageWeights();
}
// Update URL Prefixes for all languages after the new default language is
// propagated and the LanguageManagerInterface::getLanguages() cache is
// flushed.
language_negotiation_url_prefixes_update();
// If after adding this language the site will become multilingual, we need
// to rebuild language services.
if (!$this->preSaveMultilingual && !$update && $language_manager instanceof ConfigurableLanguageManagerInterface) {
$language_manager::rebuildServices();
}
}
/**
* Converts the Language entity to a Language value object.
*
* @todo fix return type hint after https://drupal.org/node/2246665 and
* https://drupal.org/node/2246679.
*
* @return \Drupal\Core\Language\Language
* The language configuration entity expressed as a Language value object.
*/
protected function toLanguageObject() {
return new LanguageObject(array(
'id' => $this->id(),
'name' => $this->label(),
'direction' => $this->direction,
'weight' => $this->weight,
'locked' => $this->locked,
'default' => $this->default,
));
}
/**
* {@inheritdoc}
*
* @throws \RuntimeException
*/
public static function preDelete(EntityStorageInterface $storage, array $entities) {
$default_language = \Drupal::service('language.default')->get();
$default_langcode = static::getDefaultLangcode();
foreach ($entities as $entity) {
if ($entity->id() == $default_language->id && !$entity->isUninstalling()) {
if ($entity->id() == $default_langcode && !$entity->isUninstalling()) {
throw new DeleteDefaultLanguageException('Can not delete the default language');
}
}
}
/**
* {@inheritdoc}
*/
public function get($property_name) {
if ($property_name == 'default') {
return $this->isDefault();
}
else {
return parent::get($property_name);
}
}
/**
* Gets the default langcode.
*
* @return string
* The current default langcode.
*/
protected static function getDefaultLangcode() {
$language = \Drupal::service('language.default')->get();
return $language->getId();
}
}
......@@ -88,6 +88,9 @@ public function testDefaultLangcode() {
// Site's default.
$old_default = \Drupal::languageManager()->getDefaultLanguage();
// Ensure the language entity default value is correct.
$language_entity = entity_load('language_entity', $old_default->getId());
$this->assertTrue($language_entity->get('default'), 'The en language entity is flagged as the default language.');
$old_default->default = FALSE;
language_save($old_default);
$new_default = \Drupal::languageManager()->getLanguage('cc');
......@@ -97,6 +100,14 @@ public function testDefaultLangcode() {
$langcode = language_get_default_langcode('custom_type', 'custom_bundle');
$this->assertEqual($langcode, 'cc');
// Ensure the language entity default value is correct.
$language_entity = entity_load('language_entity', $old_default->getId());
$this->assertFalse($language_entity->get('default'), 'The en language entity is not flagged as the default language.');
$language_entity = entity_load('language_entity', 'cc');
// Check calling the Drupal\language\Entity\Language::isDefault() method
// directly.
$this->assertTrue($language_entity->isDefault(), 'The cc language entity is flagged as the default language.');
// Check the default value of a language field when authors preferred option
// is selected.
// Create first an user and assign a preferred langcode to him.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment