diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 906a7c1..4a16e24 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1488,8 +1488,9 @@ function t($string, array $args = array(), array $options = array()) { if (isset($custom_strings[$options['langcode']][$options['context']][$string])) { $string = $custom_strings[$options['langcode']][$options['context']][$string]; } - // Translate with locale module if enabled. - elseif ($options['langcode'] != LANGUAGE_SYSTEM && ($options['langcode'] != 'en' || variable_get('locale_translate_english', FALSE)) && function_exists('locale')) { + // Translate with locale module if enabled anf Drupal\locale\LocaleLookup is + // available. + elseif ($options['langcode'] != LANGUAGE_SYSTEM && ($options['langcode'] != 'en' || variable_get('locale_translate_english', FALSE)) && function_exists('locale') && class_exists('Drupal\locale\LocaleLookup')) { $string = locale($string, $options['context'], $options['langcode']); } if (empty($args)) { @@ -2772,14 +2773,21 @@ function language_list($flags = LANGUAGE_CONFIGURABLE) { // Fill in master language list based on current configuration. $default = language_default(); if (language_multilingual() || module_exists('language')) { - // Use language module configuration if available. - $languages = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode', PDO::FETCH_ASSOC); - + // Use language module configuration if available. Always reset the entity + // cache as the language objects are statically cached. + $language_entities = entity_load_multiple('language', NULL, TRUE); + uasort($language_entities, 'language_entity_sort'); // Initialize default property so callers have an easy reference and can // save the same object without data loss. - foreach ($languages as $langcode => $info) { - $info['default'] = ($langcode == $default->langcode); - $languages[$langcode] = new Language($info); + foreach ($language_entities as $langcode => $info) { + $languages[$langcode] = new Language(array( + 'default' => ($langcode == $default->langcode), + 'name' => $info->name, + 'langcode' => $langcode, + 'direction' => $info->direction, + 'locked' => $info->locked, + 'weight' => $info->weight, + )); } } else { diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module index 8bd2fc1..630796c 100644 --- a/core/modules/entity/entity.module +++ b/core/modules/entity/entity.module @@ -10,6 +10,7 @@ use Drupal\entity\EntityFieldQuery; use Drupal\entity\EntityMalformedException; use Drupal\entity\EntityStorageException; use Drupal\entity\EntityInterface; +use \stdClass; /** * Implements hook_help(). @@ -49,8 +50,15 @@ function entity_modules_disabled() { * @see hook_entity_info_alter() */ function entity_get_info($entity_type = NULL) { - $language_interface = language(LANGUAGE_TYPE_INTERFACE); - + // We need a special exception for the language config entity as this call to + // language will lead to the turtles gettings language negotiaiton wrong. + if ($entity_type != 'language') { + $language_interface = language(LANGUAGE_TYPE_INTERFACE); + } + else { + $language_interface = new stdClass; + $language_interface->langcode = LANGUAGE_NOT_SPECIFIED; + } // Use the advanced drupal_static() pattern, since this is called very often. static $drupal_static_fast; if (!isset($drupal_static_fast)) { diff --git a/core/modules/language/language.info b/core/modules/language/language.info index 309704f..fa6ef5d 100644 --- a/core/modules/language/language.info +++ b/core/modules/language/language.info @@ -4,3 +4,7 @@ package = Core version = VERSION core = 8.x configure = admin/config/regional/language +; @todo D8: Config module is required for all modules that implement +; ConfigEntityBase. Move the entity system and ConfigEntity* into a +; Drupal\Core component to remove this required dependency. +dependencies[] = config diff --git a/core/modules/language/language.install b/core/modules/language/language.install index 2884d4b..fce7521 100644 --- a/core/modules/language/language.install +++ b/core/modules/language/language.install @@ -55,55 +55,6 @@ function language_uninstall() { } /** - * Implements hook_schema(). - */ -function language_schema() { - $schema['language'] = array( - 'description' => 'List of all available languages in the system.', - 'fields' => array( - 'langcode' => array( - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - 'description' => "Language code, e.g. 'de' or 'en-US'.", - ), - 'name' => array( - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Language name.', - ), - 'direction' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Direction of language (Left-to-Right = 0, Right-to-Left = 1).', - ), - 'weight' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Weight, used in lists of languages.', - ), - 'locked' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'A boolean indicating whether the administrator can edit or delete the language.', - ), - ), - 'primary key' => array('langcode'), - 'indexes' => array( - 'list' => array('weight', 'name'), - ), - ); - return $schema; -} - -/** * Implements hook_enable(). */ function language_enable() { @@ -121,3 +72,12 @@ function language_disable() { // will be FALSE, because the language module is disabled. variable_set('language_count', 1); } + +/* + * Remove the language table. + */ +function language_update_8000() { + // system_update_8000 will have already run and create the language config + // entities. + db_drop_table('language'); +} diff --git a/core/modules/language/language.module b/core/modules/language/language.module index 5b62382..15f4a96 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -229,20 +229,33 @@ function language_process_language_select($element) { * Language object with properties corresponding to 'language' table columns. */ function language_save($language) { - $language->is_new = !(bool) db_query_range('SELECT 1 FROM {language} WHERE langcode = :langcode', 0, 1, array(':langcode' => $language->langcode))->fetchField(); + $language_entity = entity_load('language', $language->langcode); + if ($language_entity === FALSE) { + $language->is_new = TRUE; + $language_entity = entity_create('language', array( + 'id' => $language->langcode, + )); + } + else { + $language->is_new = FALSE; + } // Let other modules modify $language before saved. module_invoke_all('language_presave', $language); + $language_entity->name = isset($language->name) ? $language->name : ''; + $language_entity->direction = isset($language->direction) ? $language->direction : '0'; + $language_entity->locked = isset($language->locked) ? $language->locked : '0'; + $language_entity->weight = isset($language->weight) ? $language->weight : '0'; + // Save the record and inform others about the change. + $language_entity->save(); $t_args = array('%language' => $language->name, '%langcode' => $language->langcode); if ($language->is_new) { - drupal_write_record('language', $language); module_invoke_all('language_insert', $language); watchdog('language', 'The %language (%langcode) language has been created.', $t_args); } else { - drupal_write_record('language', $language, array('langcode')); module_invoke_all('language_update', $language); watchdog('language', 'The %language (%langcode) language has been updated.', $t_args); } @@ -274,7 +287,14 @@ function language_save($language) { * @see language_multilingual() */ function language_update_count() { - variable_set('language_count', db_query('SELECT COUNT(langcode) FROM {language} WHERE locked = 0')->fetchField()); + $count = 0; + $languages = entity_load_multiple('language', NULL, TRUE); + foreach ($languages as $language) { + if (!$language->locked) { + $count++; + } + } + variable_set('language_count', $count); } /** @@ -293,9 +313,7 @@ function language_delete($langcode) { module_invoke_all('language_delete', $language); // Remove the language. - db_delete('language') - ->condition('langcode', $language->langcode) - ->execute(); + entity_delete_multiple('language', array($language->langcode)); language_update_count(); @@ -633,3 +651,33 @@ function language_set_browser_drupal_langcode_mappings($mappings) { $config->setData($mappings); $config->save(); } + +/** + * Implements hook_entity_info(). + */ +function language_entity_info() { + $types['language'] = array( + 'label' => 'Language', + 'controller class' => 'Drupal\config\ConfigStorageController', + 'entity class' => 'Drupal\language\LanguageEntity', + 'config prefix' => 'language.entity', + 'entity keys' => array( + 'id' => 'id', + 'label' => 'name', + 'uuid' => 'uuid', + ), + ); + return $types; +} + +/** + * Helper callback for uasort() to sort configuration entities by weight and label. + */ +function language_entity_sort($a, $b) { + $a_weight = isset($a->weight) ? $a->weight : 0; + $b_weight = isset($b->weight) ? $b->weight : 0; + if ($a_weight == $b_weight) { + return strnatcasecmp($a->name, $b->name); + } + return ($a_weight < $b_weight) ? -1 : 1; +} diff --git a/core/modules/language/lib/Drupal/language/LanguageEntity.php b/core/modules/language/lib/Drupal/language/LanguageEntity.php new file mode 100644 index 0000000..e0c40bc --- /dev/null +++ b/core/modules/language/lib/Drupal/language/LanguageEntity.php @@ -0,0 +1,57 @@ +assertModules(array('translation', 'language'), TRUE); - // Assert that the language tables were enabled. - $this->assertTableCount('language', TRUE); + // Assert that the language YAML files were created. + $storage = drupal_container()->get('config.storage'); + $this->assertTrue(count($storage->listAll('language.entity.')) > 0, 'Language config entity files exist.'); } /** diff --git a/core/modules/system/system.install b/core/modules/system/system.install index ac983aa..d782b82 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1,6 +1,7 @@ langcode) + ->set('id', $language->langcode) + ->set('name', $language->name) + ->set('direction', $language->direction) + ->set('weight', $language->weight) + ->set('locked', $language->locked) + ->set('langcode', LANGUAGE_NOT_SPECIFIED) + ->set('uuid', $uuid->generate()) + ->save(); + } + } + else { + update_module_enable(array('entity')); + } } /**