Commit 4c357934 authored by alexpott's avatar alexpott

Issue #1754246 by webflo, swentel, penyaskito, andypost, alexpott, YesCT,...

Issue #1754246 by webflo, swentel, penyaskito, andypost, alexpott, YesCT, dagmar: Languages should be configuration entities.
parent 0c957d31
...@@ -2395,7 +2395,7 @@ function drupal_installation_attempted() { ...@@ -2395,7 +2395,7 @@ function drupal_installation_attempted() {
function drupal_language_initialize() { function drupal_language_initialize() {
$language_manager = Drupal::languageManager(); $language_manager = Drupal::languageManager();
$language_manager->init(); $language_manager->init();
Drupal::translation()->setDefaultLangcode($language_manager->getLanguage(Language::TYPE_INTERFACE)->langcode); Drupal::translation()->setDefaultLangcode($language_manager->getLanguage(Language::TYPE_INTERFACE)->id);
} }
/** /**
...@@ -2476,18 +2476,27 @@ function language_list($flags = Language::STATE_CONFIGURABLE) { ...@@ -2476,18 +2476,27 @@ function language_list($flags = Language::STATE_CONFIGURABLE) {
$default = language_default(); $default = language_default();
if (language_multilingual() || module_exists('language')) { if (language_multilingual() || module_exists('language')) {
// Use language module configuration if available. // Use language module configuration if available.
$languages = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode', PDO::FETCH_ASSOC); $language_entities = config_get_storage_names_with_prefix('language.entity');
// Initialize default property so callers have an easy reference and can // Initialize default property so callers have an easy reference and can
// save the same object without data loss. // save the same object without data loss.
foreach ($languages as $langcode => $info) { foreach ($language_entities as $langcode_config_name) {
$info['default'] = ($langcode == $default->langcode); $langcode = substr($langcode_config_name, strlen('language.entity.'));
$languages[$langcode] = new Language($info); $info = config($langcode_config_name)->get();
$languages[$langcode] = new Language(array(
'default' => ($info['id'] == $default->id),
'name' => $info['label'],
'id' => $info['id'],
'direction' => $info['direction'],
'locked' => $info['locked'],
'weight' => $info['weight'],
));
} }
Language::sort($languages);
} }
else { else {
// No language module, so use the default language only. // No language module, so use the default language only.
$languages = array($default->langcode => $default); $languages = array($default->id => $default);
// Add the special languages, they will be filtered later if needed. // Add the special languages, they will be filtered later if needed.
$languages += language_default_locked_languages($default->weight); $languages += language_default_locked_languages($default->weight);
} }
...@@ -2535,12 +2544,12 @@ function language_default_locked_languages($weight = 0) { ...@@ -2535,12 +2544,12 @@ function language_default_locked_languages($weight = 0) {
$languages = array(); $languages = array();
$languages[Language::LANGCODE_NOT_SPECIFIED] = new Language(array( $languages[Language::LANGCODE_NOT_SPECIFIED] = new Language(array(
'langcode' => Language::LANGCODE_NOT_SPECIFIED, 'id' => Language::LANGCODE_NOT_SPECIFIED,
'name' => t('Not specified'), 'name' => t('Not specified'),
'weight' => ++$weight, 'weight' => ++$weight,
) + $locked_language); ) + $locked_language);
$languages[Language::LANGCODE_NOT_APPLICABLE] = new Language(array( $languages[Language::LANGCODE_NOT_APPLICABLE] = new Language(array(
'langcode' => Language::LANGCODE_NOT_APPLICABLE, 'id' => Language::LANGCODE_NOT_APPLICABLE,
'name' => t('Not applicable'), 'name' => t('Not applicable'),
'weight' => ++$weight, 'weight' => ++$weight,
) + $locked_language); ) + $locked_language);
...@@ -2606,7 +2615,7 @@ function language_is_locked($langcode) { ...@@ -2606,7 +2615,7 @@ function language_is_locked($langcode) {
*/ */
function language_default() { function language_default() {
$info = variable_get('language_default', array( $info = variable_get('language_default', array(
'langcode' => 'en', 'id' => 'en',
'name' => 'English', 'name' => 'English',
'direction' => 0, 'direction' => 0,
'weight' => 0, 'weight' => 0,
......
...@@ -904,7 +904,7 @@ function filter_xss_bad_protocol($string) { ...@@ -904,7 +904,7 @@ function filter_xss_bad_protocol($string) {
* Arbitrary elements may be added using the $args associative array. * Arbitrary elements may be added using the $args associative array.
*/ */
function format_rss_channel($title, $link, $description, $items, $langcode = NULL, $args = array()) { function format_rss_channel($title, $link, $description, $items, $langcode = NULL, $args = array()) {
$langcode = $langcode ? $langcode : language(Language::TYPE_CONTENT)->langcode; $langcode = $langcode ? $langcode : language(Language::TYPE_CONTENT)->id;
$output = "<channel>\n"; $output = "<channel>\n";
$output .= ' <title>' . check_plain($title) . "</title>\n"; $output .= ' <title>' . check_plain($title) . "</title>\n";
...@@ -1417,7 +1417,7 @@ function l($text, $path, array $options = array()) { ...@@ -1417,7 +1417,7 @@ function l($text, $path, array $options = array()) {
$active = array( $active = array(
'path' => current_path(), 'path' => current_path(),
'front_page' => drupal_is_front_page(), 'front_page' => drupal_is_front_page(),
'language' => language(Language::TYPE_URL)->langcode, 'language' => language(Language::TYPE_URL)->id,
'query' => Drupal::service('request')->query->all(), 'query' => Drupal::service('request')->query->all(),
); );
} }
...@@ -1428,7 +1428,7 @@ function l($text, $path, array $options = array()) { ...@@ -1428,7 +1428,7 @@ function l($text, $path, array $options = array()) {
// An active link's path is equal to the current path. // An active link's path is equal to the current path.
$variables['url_is_active'] = ($path == $active['path'] || ($path == '<front>' && $active['front_page'])) $variables['url_is_active'] = ($path == $active['path'] || ($path == '<front>' && $active['front_page']))
// The language of an active link is equal to the current language. // The language of an active link is equal to the current language.
&& (empty($variables['options']['language']) || $variables['options']['language']->langcode == $active['language']) && (empty($variables['options']['language']) || $variables['options']['language']->id == $active['language'])
// The query parameters of an active link are equal to the current parameters. // The query parameters of an active link are equal to the current parameters.
&& ($variables['options']['query'] == $active['query']); && ($variables['options']['query'] == $active['query']);
...@@ -5041,7 +5041,7 @@ function drupal_render_cid_parts($granularity = NULL) { ...@@ -5041,7 +5041,7 @@ function drupal_render_cid_parts($granularity = NULL) {
// part. // part.
if (language_multilingual()) { if (language_multilingual()) {
foreach (language_types_get_configurable() as $language_type) { foreach (language_types_get_configurable() as $language_type) {
$cid_parts[] = language($language_type)->langcode; $cid_parts[] = language($language_type)->id;
} }
} }
......
...@@ -60,7 +60,7 @@ function entity_info_cache_clear() { ...@@ -60,7 +60,7 @@ function entity_info_cache_clear() {
function entity_get_bundles($entity_type = NULL) { function entity_get_bundles($entity_type = NULL) {
$bundles = &drupal_static(__FUNCTION__); $bundles = &drupal_static(__FUNCTION__);
if (!$bundles) { if (!$bundles) {
$langcode = language(Language::TYPE_INTERFACE)->langcode; $langcode = language(Language::TYPE_INTERFACE)->id;
if ($cache = cache()->get("entity_bundle_info:$langcode")) { if ($cache = cache()->get("entity_bundle_info:$langcode")) {
$bundles = $cache->data; $bundles = $cache->data;
} }
...@@ -118,7 +118,7 @@ function entity_invoke_bundle_hook($hook, $entity_type, $bundle, $bundle_new = N ...@@ -118,7 +118,7 @@ function entity_invoke_bundle_hook($hook, $entity_type, $bundle, $bundle_new = N
function entity_get_form_modes($entity_type = NULL) { function entity_get_form_modes($entity_type = NULL) {
$form_modes = &drupal_static(__FUNCTION__); $form_modes = &drupal_static(__FUNCTION__);
if (!$form_modes) { if (!$form_modes) {
$langcode = language(Language::TYPE_INTERFACE)->langcode; $langcode = language(Language::TYPE_INTERFACE)->id;
if ($cache = cache()->get("entity_form_mode_info:$langcode")) { if ($cache = cache()->get("entity_form_mode_info:$langcode")) {
$form_modes = $cache->data; $form_modes = $cache->data;
} }
...@@ -156,7 +156,7 @@ function entity_get_form_modes($entity_type = NULL) { ...@@ -156,7 +156,7 @@ function entity_get_form_modes($entity_type = NULL) {
function entity_get_view_modes($entity_type = NULL) { function entity_get_view_modes($entity_type = NULL) {
$view_modes = &drupal_static(__FUNCTION__); $view_modes = &drupal_static(__FUNCTION__);
if (!$view_modes) { if (!$view_modes) {
$langcode = language(Language::TYPE_INTERFACE)->langcode; $langcode = language(Language::TYPE_INTERFACE)->id;
if ($cache = cache()->get("entity_view_mode_info:$langcode")) { if ($cache = cache()->get("entity_view_mode_info:$langcode")) {
$view_modes = $cache->data; $view_modes = $cache->data;
} }
......
...@@ -3854,7 +3854,7 @@ function form_process_machine_name($element, &$form_state) { ...@@ -3854,7 +3854,7 @@ function form_process_machine_name($element, &$form_state) {
'machineName' => array( 'machineName' => array(
'#' . $source['#id'] => $element['#machine_name'], '#' . $source['#id'] => $element['#machine_name'],
), ),
'langcode' => $language->langcode, 'langcode' => $language->id,
), ),
); );
$element['#attached']['library'][] = array('system', 'drupal.machine-name'); $element['#attached']['library'][] = array('system', 'drupal.machine-name');
......
...@@ -298,8 +298,14 @@ function install_begin_request(&$install_state) { ...@@ -298,8 +298,14 @@ function install_begin_request(&$install_state) {
// (eg. pre-database data screens we are unable to persistently store // (eg. pre-database data screens we are unable to persistently store
// the default language), we should set language_default so the proper // the default language), we should set language_default so the proper
// language is used to display installer pages as early as possible. // language is used to display installer pages as early as possible.
if (!empty($install_state['parameters']['langcode']) && language_default()->langcode != $install_state['parameters']['langcode']) { // The language list is stored in configuration and cannot be saved either
$GLOBALS['conf']['language_default'] = array('langcode' => $install_state['parameters']['langcode']); // until later in the process. Language negotiation bootstrapping needs
// the new default language to be in the list though, so inject it in.
if (!empty($install_state['parameters']['langcode']) && language_default()->id != $install_state['parameters']['langcode']) {
$GLOBALS['conf']['language_default'] = array('id' => $install_state['parameters']['langcode']);
$languages = &drupal_static('language_list');
$languages[$install_state['parameters']['langcode']] = new Language($GLOBALS['conf']['language_default']);
} }
require_once __DIR__ . '/../modules/system/system.install'; require_once __DIR__ . '/../modules/system/system.install';
...@@ -1547,7 +1553,7 @@ function install_select_language_form($form, &$form_state, $files = array()) { ...@@ -1547,7 +1553,7 @@ function install_select_language_form($form, &$form_state, $files = array()) {
foreach ($files as $langcode => $uri) { foreach ($files as $langcode => $uri) {
$select_options[$langcode] = isset($standard_languages[$langcode]) ? $standard_languages[$langcode][1] : $langcode; $select_options[$langcode] = isset($standard_languages[$langcode]) ? $standard_languages[$langcode][1] : $langcode;
$browser_options[$langcode] = new Language(array( $browser_options[$langcode] = new Language(array(
'langcode' => $langcode, 'id' => $langcode,
)); ));
} }
} }
...@@ -1556,7 +1562,7 @@ function install_select_language_form($form, &$form_state, $files = array()) { ...@@ -1556,7 +1562,7 @@ function install_select_language_form($form, &$form_state, $files = array()) {
foreach ($standard_languages as $langcode => $language_names) { foreach ($standard_languages as $langcode => $language_names) {
$select_options[$langcode] = $language_names[1]; $select_options[$langcode] = $language_names[1];
$browser_options[$langcode] = new Language(array( $browser_options[$langcode] = new Language(array(
'langcode' => $langcode, 'id' => $langcode,
)); ));
} }
} }
...@@ -1819,7 +1825,7 @@ function install_import_translations(&$install_state) { ...@@ -1819,7 +1825,7 @@ function install_import_translations(&$install_state) {
// Drupal does not know about this language, so we prefill its values with // Drupal does not know about this language, so we prefill its values with
// our best guess. The user will be able to edit afterwards. // our best guess. The user will be able to edit afterwards.
$language = new Language(array( $language = new Language(array(
'langcode' => $langcode, 'id' => $langcode,
'name' => $langcode, 'name' => $langcode,
'default' => TRUE, 'default' => TRUE,
)); ));
...@@ -1828,7 +1834,7 @@ function install_import_translations(&$install_state) { ...@@ -1828,7 +1834,7 @@ function install_import_translations(&$install_state) {
else { else {
// A known predefined language, details will be filled in properly. // A known predefined language, details will be filled in properly.
$language = new Language(array( $language = new Language(array(
'langcode' => $langcode, 'id' => $langcode,
'default' => TRUE, 'default' => TRUE,
)); ));
language_save($language); language_save($language);
...@@ -2497,7 +2503,7 @@ function install_configure_form_submit($form, &$form_state) { ...@@ -2497,7 +2503,7 @@ function install_configure_form_submit($form, &$form_state) {
config('system.site') config('system.site')
->set('name', $form_state['values']['site_name']) ->set('name', $form_state['values']['site_name'])
->set('mail', $form_state['values']['site_mail']) ->set('mail', $form_state['values']['site_mail'])
->set('langcode', language_default()->langcode) ->set('langcode', language_default()->id)
->save(); ->save();
config('system.timezone') config('system.timezone')
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
* *
* // If we are on an administrative path, override with the default language. * // If we are on an administrative path, override with the default language.
* if (isset($_GET['q']) && strtok($_GET['q'], '/') == 'admin') { * if (isset($_GET['q']) && strtok($_GET['q'], '/') == 'admin') {
* return language_default()->langcode; * return language_default()->id;
* } * }
* return $langcode; * return $langcode;
* } * }
...@@ -409,7 +409,7 @@ function language_negotiation_info() { ...@@ -409,7 +409,7 @@ function language_negotiation_info() {
$languages = language_list(); $languages = language_list();
$selected_language = $languages[language_from_selected($languages)]; $selected_language = $languages[language_from_selected($languages)];
$description = 'Language based on a selected language. '; $description = 'Language based on a selected language. ';
$description .= ($selected_language->langcode == language_default()->langcode) ? "(Site's default language (@language_name))" : '(@language_name)'; $description .= ($selected_language->id == language_default()->id) ? "(Site's default language (@language_name))" : '(@language_name)';
// Add the default language negotiation method. // Add the default language negotiation method.
$negotiation_info[LANGUAGE_NEGOTIATION_SELECTED] = array( $negotiation_info[LANGUAGE_NEGOTIATION_SELECTED] = array(
'callbacks' => array( 'callbacks' => array(
...@@ -488,9 +488,9 @@ function language_from_selected($languages) { ...@@ -488,9 +488,9 @@ function language_from_selected($languages) {
$langcode = (string) config('language.negotiation')->get('selected_langcode'); $langcode = (string) config('language.negotiation')->get('selected_langcode');
// Replace the site's default langcode by its real value. // Replace the site's default langcode by its real value.
if ($langcode == 'site_default') { if ($langcode == 'site_default') {
$langcode = language_default()->langcode; $langcode = language_default()->id;
} }
return isset($languages[$langcode]) ? $langcode : language_default()->langcode; return isset($languages[$langcode]) ? $langcode : language_default()->id;
} }
/** /**
...@@ -517,7 +517,7 @@ function language_url_split_prefix($path, $languages) { ...@@ -517,7 +517,7 @@ function language_url_split_prefix($path, $languages) {
// Search prefix within enabled languages. // Search prefix within enabled languages.
$prefixes = language_negotiation_url_prefixes(); $prefixes = language_negotiation_url_prefixes();
foreach ($languages as $language) { foreach ($languages as $language) {
if (isset($prefixes[$language->langcode]) && $prefixes[$language->langcode] == $prefix) { if (isset($prefixes[$language->id]) && $prefixes[$language->id] == $prefix) {
// Rebuild $path with the language removed. // Rebuild $path with the language removed.
return array($language, implode('/', $args)); return array($language, implode('/', $args));
} }
......
...@@ -1161,7 +1161,7 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) { ...@@ -1161,7 +1161,7 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
// Use $mlid as a flag for whether the data being loaded is for the whole tree. // Use $mlid as a flag for whether the data being loaded is for the whole tree.
$mlid = isset($link['mlid']) ? $link['mlid'] : 0; $mlid = isset($link['mlid']) ? $link['mlid'] : 0;
// Generate a cache ID (cid) specific for this $menu_name, $link, $language, and depth. // Generate a cache ID (cid) specific for this $menu_name, $link, $language, and depth.
$cid = 'links:' . $menu_name . ':all:' . $mlid . ':' . $language_interface->langcode . ':' . (int) $max_depth; $cid = 'links:' . $menu_name . ':all:' . $mlid . ':' . $language_interface->id . ':' . (int) $max_depth;
if (!isset($tree[$cid])) { if (!isset($tree[$cid])) {
// If the static variable doesn't have the data, check {cache_menu}. // If the static variable doesn't have the data, check {cache_menu}.
...@@ -1277,7 +1277,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail = ...@@ -1277,7 +1277,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
$max_depth = min($max_depth, MENU_MAX_DEPTH); $max_depth = min($max_depth, MENU_MAX_DEPTH);
} }
// Generate a cache ID (cid) specific for this page. // Generate a cache ID (cid) specific for this page.
$cid = 'links:' . $menu_name . ':page:' . $item['href'] . ':' . $language_interface->langcode . ':' . (int) $item['access'] . ':' . (int) $max_depth; $cid = 'links:' . $menu_name . ':page:' . $item['href'] . ':' . $language_interface->id . ':' . (int) $item['access'] . ':' . (int) $max_depth;
// If we are asked for the active trail only, and $menu_name has not been // If we are asked for the active trail only, and $menu_name has not been
// built and cached for this page yet, then this likely means that it // built and cached for this page yet, then this likely means that it
// won't be built anymore, as this function is invoked from // won't be built anymore, as this function is invoked from
...@@ -1425,7 +1425,7 @@ function _menu_build_tree($menu_name, array $parameters = array()) { ...@@ -1425,7 +1425,7 @@ function _menu_build_tree($menu_name, array $parameters = array()) {
if (isset($parameters['expanded'])) { if (isset($parameters['expanded'])) {
sort($parameters['expanded']); sort($parameters['expanded']);
} }
$tree_cid = 'links:' . $menu_name . ':tree-data:' . $language_interface->langcode . ':' . hash('sha256', serialize($parameters)); $tree_cid = 'links:' . $menu_name . ':tree-data:' . $language_interface->id . ':' . hash('sha256', serialize($parameters));
// If we do not have this tree in the static cache, check {cache_menu}. // If we do not have this tree in the static cache, check {cache_menu}.
if (!isset($trees[$tree_cid])) { if (!isset($trees[$tree_cid])) {
......
...@@ -1731,7 +1731,7 @@ function theme_links($variables) { ...@@ -1731,7 +1731,7 @@ function theme_links($variables) {
// Handle links. // Handle links.
if (isset($link['href'])) { if (isset($link['href'])) {
$is_current_path = ($link['href'] == current_path() || ($link['href'] == '<front>' && drupal_is_front_page())); $is_current_path = ($link['href'] == current_path() || ($link['href'] == '<front>' && drupal_is_front_page()));
$is_current_language = (empty($link['language']) || $link['language']->langcode == $language_url->langcode); $is_current_language = (empty($link['language']) || $link['language']->id == $language_url->id);
if ($is_current_path && $is_current_language) { if ($is_current_path && $is_current_language) {
$class[] = 'active'; $class[] = 'active';
} }
...@@ -2590,7 +2590,7 @@ function template_preprocess_html(&$variables) { ...@@ -2590,7 +2590,7 @@ function template_preprocess_html(&$variables) {
$variables['html_attributes'] = new Attribute; $variables['html_attributes'] = new Attribute;
// HTML element attributes. // HTML element attributes.
$variables['html_attributes']['lang'] = $language_interface->langcode; $variables['html_attributes']['lang'] = $language_interface->id;
$variables['html_attributes']['dir'] = $language_interface->direction ? 'rtl' : 'ltr'; $variables['html_attributes']['dir'] = $language_interface->direction ? 'rtl' : 'ltr';
// Add favicon. // Add favicon.
......
...@@ -319,9 +319,9 @@ function update_prepare_d8_bootstrap() { ...@@ -319,9 +319,9 @@ function update_prepare_d8_bootstrap() {
// triggers a call into system_stream_wrappers(), which calls t(), which // triggers a call into system_stream_wrappers(), which calls t(), which
// calls into language_default(). // calls into language_default().
$language_default = variable_get('language_default'); $language_default = variable_get('language_default');
if (!empty($language_default) && (isset($language_default->langcode) || isset($language_default->language))) { if (!empty($language_default) && (isset($language_default->id) || isset($language_default->language))) {
if (!isset($language_default->langcode)) { if (!isset($language_default->id)) {
$language_default->langcode = $language_default->language; $language_default->id = $language_default->language;
} }
unset($language_default->language); unset($language_default->language);
// In D8, the 'language_default' is not anymore an object, but an array, // In D8, the 'language_default' is not anymore an object, but an array,
...@@ -534,7 +534,7 @@ function update_prepare_d8_language() { ...@@ -534,7 +534,7 @@ function update_prepare_d8_language() {
foreach ($languages as $language) { foreach ($languages as $language) {
db_insert('language') db_insert('language')
->fields(array( ->fields(array(
'langcode' => $language->langcode, 'langcode' => $language->id,
'name' => $language->name, 'name' => $language->name,
'weight' => $language->weight, 'weight' => $language->weight,
// These languages are locked, default to enabled. // These languages are locked, default to enabled.
...@@ -548,14 +548,31 @@ function update_prepare_d8_language() { ...@@ -548,14 +548,31 @@ function update_prepare_d8_language() {
$language_default = variable_get('language_default'); $language_default = variable_get('language_default');
if (!empty($language_default)) { if (!empty($language_default)) {
if (isset($language_default->language)) { if (isset($language_default->language)) {
$language_default->langcode = $language_default->language; $language_default->id = $language_default->language;
unset($language_default->language); unset($language_default->language);
} }
unset($language_default->enabled); unset($language_default->enabled);
// In D8, the 'language_default' is not anymore an object, but an array, // In D8, the 'language_default' is not anymore an object, but an array,
// so make sure that the new value that is saved into this variable is an // so make sure that the new value that is saved into this variable is an
// array. // array.
variable_set('language_default', (array) $language_default); $language_default = (array) $language_default;
$language_default['langcode'] = 'en';
variable_set('language_default', $language_default);
}
// Convert languages to config entities.
$result = db_query('SELECT * FROM {language}');
$uuid = new Uuid();
foreach ($result as $language) {
config('language.entity.' . $language->langcode)
->set('id', $language->langcode)
->set('uuid', $uuid->generate())
->set('label', $language->name)
->set('direction', $language->direction)
->set('weight', $language->weight)
->set('locked', $language->locked)
->set('langcode', 'en')
->save();
} }
// Add column to track customized string status to locales_target. // Add column to track customized string status to locales_target.
...@@ -1572,3 +1589,78 @@ function update_replace_permissions($replace) { ...@@ -1572,3 +1589,78 @@ function update_replace_permissions($replace) {
->save(); ->save();
} }
} }
/**
* Returns a list of languages set up on the site during upgrades.
*
* @param $flags
* (optional) Specifies the state of the languages that have to be returned.
* It can be: Language::STATE_CONFIGURABLE, Language::STATE_LOCKED,
* Language::STATE_ALL.
*
* @return array
* An associative array of languages, keyed by the language code, ordered by
* weight ascending and name ascending.
*/
function update_language_list($flags = Language::STATE_CONFIGURABLE) {
$languages = &drupal_static(__FUNCTION__);
// Initialize master language list.
if (!isset($languages)) {
// Initialize local language list cache.
$languages = array();
// Fill in master language list based on current configuration.
$default = language_default();
if (language_multilingual() || module_exists('language')) {
// Use language module configuration if available. We can not use
// entity_load_multiple() because this breaks during updates.
$language_entities = config_get_storage_names_with_prefix('language.entity');
// Initialize default property so callers have an easy reference and can
// save the same object without data loss.
foreach ($language_entities as $langcode_config_name) {
$langcode = substr($langcode_config_name, strlen('language.entity.'));
$info = config($langcode_config_name)->get();
$languages[$langcode] = new Language(array(
'default' => ($info['id'] == $default->id),
'name' => $info['label'],
'id' => $info['id'],
'direction' => $info['direction'],
'locked' => $info['locked'],
'weight' => $info['weight'],
));
}
Language::sort($languages);
}
else {
// No language module, so use the default language only.
$languages = array($default->id => $default);
// Add the special languages, they will be filtered later if needed.
$languages += language_default_locked_languages($default->weight);
}
}
// Filter the full list of languages based on the value of the $all flag. By
// default we remove the locked languages, but the caller may request for