Commit 4b928417 authored by Dries's avatar Dries

- Patch #1387608 by Gábor Hojtsy, tstoeckler: Unify language_list() and locale_language_list().

parent adbebba6
......@@ -2652,53 +2652,45 @@ function language_types() {
}
/**
* Returns a list of installed languages, indexed by the specified key.
* Returns a list of configured languages.
*
* @param $field
* (optional) The field to index the list with.
* @param $only_enabled
* (optional) Whether to return only enabled languages.
*
* @return
* An associative array, keyed on the values of $field.
* - If $field is 'weight' or 'enabled', the array is nested, with the outer
* array's values each being associative arrays with language codes as
* keys and language objects as values.
* - For all other values of $field, the array is only one level deep, and
* the array's values are language objects.
*/
function language_list($field = 'langcode') {
* An associative array of languages, keyed by the language code, ordered by
* weight ascending and name ascending.
*/
function language_list($only_enabled = FALSE) {
$languages = &drupal_static(__FUNCTION__);
// Init language list
// Initialize master language list.
if (!isset($languages)) {
// Initialize local language list caches.
$languages = array('all' => array(), 'enabled' => array());
// Fill in master language list based on current configuration.
$default = language_default();
if (language_multilingual() || module_exists('language')) {
$languages['langcode'] = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode');
// Use language module configuration if available.
$languages['all'] = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode');
}
else {
// No locale module, so use the default language only.
$languages['langcode'][$default->langcode] = $default;
// No language module, so use the default language only.
$languages['all'][$default->langcode] = $default;
}
// Initialize default property so callers have an easy reference and
// can save the same object without data loss.
foreach ($languages['langcode'] as $langcode => $language) {
$languages['langcode'][$langcode]->default = ($langcode == $default->langcode);
}
}
// Return the array indexed by the right field
if (!isset($languages[$field])) {
$languages[$field] = array();
foreach ($languages['langcode'] as $lang) {
// Some values should be collected into an array
if (in_array($field, array('enabled', 'weight'))) {
$languages[$field][$lang->$field][$lang->langcode] = $lang;
}
else {
$languages[$field][$lang->$field] = $lang;
// Initialize default property so callers have an easy reference and can
// save the same object without data loss. Also fill in the filtered list
// of enabled languages only.
foreach ($languages['all'] as $langcode => $language) {
$languages['all'][$langcode]->default = ($langcode == $default->langcode);
if ($language->enabled) {
$languages['enabled'][$langcode] = $languages['all'][$langcode];
}
}
}
return $languages[$field];
return $only_enabled ? $languages['enabled'] : $languages['all'];
}
/**
......@@ -3204,29 +3196,29 @@ function registry_update() {
*
* Example:
* @code
* function language_list($field = 'langcode') {
* $languages = &drupal_static(__FUNCTION__);
* if (!isset($languages)) {
* function example_list($field = 'default') {
* $examples = &drupal_static(__FUNCTION__);
* if (!isset($examples)) {
* // If this function is being called for the first time after a reset,
* // query the database and execute any other code needed to retrieve
* // information about the supported languages.
* // information.
* ...
* }
* if (!isset($languages[$field])) {
* if (!isset($examples[$field])) {
* // If this function is being called for the first time for a particular
* // index field, then execute code needed to index the information already
* // available in $languages by the desired field.
* // available in $examples by the desired field.
* ...
* }
* // Subsequent invocations of this function for a particular index field
* // skip the above two code blocks and quickly return the already indexed
* // information.
* return $languages[$field];
* return $examples[$field];
* }
* function locale_translate_overview_screen() {
* // When building the content for the translations overview page, make
* // sure to get completely fresh information about the supported languages.
* drupal_static_reset('language_list');
* function examples_admin_overview() {
* // When building the content for the overview page, make sure to get
* // completely fresh information.
* drupal_static_reset('example_list');
* ...
* }
* @endcode
......
......@@ -329,9 +329,8 @@ function language_provider_invoke($provider_id, $provider = NULL) {
if (!isset($results[$provider_id])) {
global $user;
// Get languages grouped by status and select only the enabled ones.
$languages = language_list('enabled');
$languages = $languages[1];
// Get the enabled languages only.
$languages = language_list(TRUE);
if (!isset($provider)) {
$providers = language_negotiation_info();
......@@ -454,17 +453,8 @@ function language_fallback_get_candidates($type = LANGUAGE_TYPE_CONTENT) {
$fallback_candidates = &drupal_static(__FUNCTION__);
if (!isset($fallback_candidates)) {
$fallback_candidates = array();
// Get languages ordered by weight.
// Use array keys to avoid duplicated entries.
foreach (language_list('weight') as $languages) {
foreach ($languages as $language) {
$fallback_candidates[$language->langcode] = NULL;
}
}
$fallback_candidates = array_keys($fallback_candidates);
// Get languages ordered by weight, add LANGUAGE_NONE as the last one.
$fallback_candidates = array_keys(language_list());
$fallback_candidates[] = LANGUAGE_NONE;
// Let other modules hook in and add/change candidates.
......
......@@ -349,14 +349,16 @@ function locale_language_url_fallback($language = NULL, $language_type = LANGUAG
}
/**
* Return the URL language switcher block. Translation links may be provided by
* other modules.
* Return links for the URL language switcher block.
*
* Translation links may be provided by other modules.
*/
function locale_language_switcher_url($type, $path) {
$languages = language_list('enabled');
// Get the enabled languages only.
$languages = language_list(TRUE);
$links = array();
foreach ($languages[1] as $language) {
foreach ($languages as $language) {
$links[$language->langcode] = array(
'href' => $path,
'title' => $language->name,
......@@ -377,13 +379,14 @@ function locale_language_switcher_session($type, $path) {
$param = variable_get('locale_language_negotiation_session_param', 'language');
$language_query = isset($_SESSION[$param]) ? $_SESSION[$param] : $GLOBALS[$type]->langcode;
$languages = language_list('enabled');
// Get the enabled languages only.
$languages = language_list(TRUE);
$links = array();
$query = $_GET;
unset($query['q']);
foreach ($languages[1] as $language) {
foreach ($languages as $language) {
$langcode = $language->langcode;
$links[$langcode] = array(
'href' => $path,
......@@ -413,8 +416,9 @@ function locale_language_url_rewrite_url(&$path, &$options) {
$languages = &$drupal_static_fast['languages'];
if (!isset($languages)) {
$languages = language_list('enabled');
$languages = array_flip(array_keys($languages[1]));
// Get the enabled languages only.
$languages = language_list(TRUE);
$languages = array_flip(array_keys($languages));
}
// Language can be passed as an option, or we go for current URL language.
......@@ -488,8 +492,8 @@ function locale_language_url_rewrite_session(&$path, &$options) {
if (!isset($query_rewrite)) {
global $user;
if (!$user->uid) {
$languages = language_list('enabled');
$languages = $languages[1];
// Get the enabled languages only.
$languages = language_list(TRUE);
$query_param = check_plain(variable_get('locale_language_negotiation_session_param', 'language'));
$query_value = isset($_GET[$query_param]) ? check_plain($_GET[$query_param]) : NULL;
$query_rewrite = isset($languages[$query_value]) && language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_SESSION);
......
......@@ -122,8 +122,8 @@ class LanguageListTest extends DrupalWebTestCase {
$this->assertResponse(404, t('Language no longer found.'));
// Make sure the "language_count" variable has been updated correctly.
drupal_static_reset('language_list');
$enabled = language_list('enabled');
$this->assertEqual(variable_get('language_count', 1), count($enabled[1]), t('Language count is correct.'));
$enabled_languages = language_list(TRUE);
$this->assertEqual(variable_get('language_count', 1), count($enabled_languages), t('Language count is correct.'));
// Delete a disabled language.
// Disable an enabled language.
$edit = array(
......@@ -133,7 +133,7 @@ class LanguageListTest extends DrupalWebTestCase {
$this->assertNoFieldChecked('edit-languages-fr-enabled', t('French language disabled.'));
// Get the count of enabled languages.
drupal_static_reset('language_list');
$enabled = language_list('enabled');
$enabled_languages = language_list(TRUE);
// Delete the disabled language.
$this->drupalPost('admin/config/regional/language/delete/fr', array(), t('Delete'));
// We need raw here because %language and %langcode will add HTML.
......@@ -144,7 +144,7 @@ class LanguageListTest extends DrupalWebTestCase {
$this->drupalGet('admin/config/regional/language/delete/fr');
$this->assertResponse(404, t('Language no longer found.'));
// Make sure the "language_count" variable has not changed.
$this->assertEqual(variable_get('language_count', 1), count($enabled[1]), t('Language count is correct.'));
$this->assertEqual(variable_get('language_count', 1), count($enabled_languages), t('Language count is correct.'));
// Ensure we can delete the English language. Right now English is the only
// language so we must add a new language and make it the default before
......
......@@ -256,10 +256,11 @@ function locale_language_providers_url_form($form, &$form_state) {
),
);
$languages = language_list('enabled');
// Get the enabled languages only.
$languages = language_list(TRUE);
$prefixes = locale_language_negotiation_url_prefixes();
$domains = locale_language_negotiation_url_domains();
foreach ($languages[1] as $langcode => $language) {
foreach ($languages as $langcode => $language) {
$form['prefix'][$langcode] = array(
'#type' => 'textfield',
'#title' => t('%language (%langcode) path prefix', array('%language' => $language->name, '%langcode' => $language->langcode)),
......@@ -292,40 +293,41 @@ function locale_language_providers_url_form($form, &$form_state) {
* the prefix and domain are only blank for the default.
*/
function locale_language_providers_url_form_validate($form, &$form_state) {
$languages = locale_language_list();
// Get the enabled languages only.
$languages = language_list(TRUE);
$default = language_default();
// Count repeated values for uniqueness check.
$count = array_count_values($form_state['values']['prefix']);
foreach ($languages as $langcode => $name) {
foreach ($languages as $langcode => $language) {
$value = $form_state['values']['prefix'][$langcode];
if ($value === '') {
if ($default->langcode != $langcode && $form_state['values']['locale_language_negotiation_url_part'] == LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX) {
if (!$language->default && $form_state['values']['locale_language_negotiation_url_part'] == LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX) {
// Validation error if the prefix is blank for a non-default language, and value is for selected negotiation type.
form_error($form['prefix'][$langcode], t('The prefix may only be left blank for the default language.'));
}
}
else if (isset($count[$value]) && $count[$value] > 1) {
// Validation error if there are two languages with the same domain/prefix.
form_error($form['prefix'][$langcode], t('The prefix for %language, %value, is not unique.', array( '%language' => $name, '%value' => $value )));
form_error($form['prefix'][$langcode], t('The prefix for %language, %value, is not unique.', array('%language' => $language->name, '%value' => $value)));
}
}
// Count repeated values for uniqueness check.
$count = array_count_values($form_state['values']['domain']);
foreach ($languages as $langcode => $name) {
foreach ($languages as $langcode => $language) {
$value = $form_state['values']['domain'][$langcode];
if ($value === '') {
if ($default->langcode != $langcode && $form_state['values']['locale_language_negotiation_url_part'] == LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN) {
if (!$language->default && $form_state['values']['locale_language_negotiation_url_part'] == LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN) {
// Validation error if the domain is blank for a non-default language, and value is for selected negotiation type.
form_error($form['domain'][$langcode], t('The domain may only be left blank for the default language.'));
}
}
else if (isset($count[$value]) && $count[$value] > 1) {
// Validation error if there are two languages with the same domain/domain.
form_error($form['domain'][$langcode], t('The domain for %language, %value, is not unique.', array( '%language' => $name, '%value' => $value )));
form_error($form['domain'][$langcode], t('The domain for %language, %value, is not unique.', array('%language' => $language->name, '%value' => $value)));
}
}
}
......@@ -405,12 +407,12 @@ function locale_date_format_language_overview_page() {
array('data' => t('Operations'), 'colspan' => '2'),
);
// Get list of languages.
$languages = locale_language_list();
// Get the enabled languages only.
$languages = language_list(TRUE);
foreach ($languages as $langcode => $info) {
foreach ($languages as $langcode => $language) {
$row = array();
$row[] = $languages[$langcode];
$row[] = $language->name;
$row[] = l(t('edit'), 'admin/config/regional/date-time/locale/' . $langcode . '/edit');
$row[] = l(t('reset'), 'admin/config/regional/date-time/locale/' . $langcode . '/reset');
$rows[] = $row;
......@@ -423,14 +425,11 @@ function locale_date_format_language_overview_page() {
* Provide date localization configuration options to users.
*/
function locale_date_format_form($form, &$form_state, $langcode) {
$languages = locale_language_list();
$language_name = $languages[$langcode];
// Display the current language name.
$form['language'] = array(
'#type' => 'item',
'#title' => t('Language'),
'#markup' => check_plain($language_name),
'#markup' => language_load($langcode)->name,
'#weight' => -10,
);
$form['langcode'] = array(
......@@ -509,9 +508,8 @@ function locale_date_format_form_submit($form, &$form_state) {
*/
function locale_date_format_reset_form($form, &$form_state, $langcode) {
$form['langcode'] = array('#type' => 'value', '#value' => $langcode);
$languages = language_list();
return confirm_form($form,
t('Are you sure you want to reset the date formats for %language to the global defaults?', array('%language' => $languages[$langcode]->name)),
t('Are you sure you want to reset the date formats for %language to the global defaults?', array('%language' => language_load($langcode)->name)),
'admin/config/regional/date-time/locale',
t('Resetting will remove all localized date formats for this language. This action cannot be undone.'),
t('Reset'), t('Cancel'));
......
......@@ -11,24 +11,32 @@
* User interface for the translation import screen.
*/
function locale_translate_import_form($form, &$form_state) {
// Get all languages, except English
drupal_static_reset('language_list');
$names = locale_language_list('name');
if (!locale_translate_english()) {
unset($names['en']);
$languages = language_list(TRUE);
// Initialize a language list to the ones available, including English if we
// are to translate Drupal to English as well.
$existing_languages = array();
foreach ($languages as $langcode => $language) {
if ($langcode != 'en' || locale_translate_english()) {
$existing_languages[$langcode] = $language->name;
}
}
// If we have no languages available, present the list of predefined languages
// only. If we do have already added languages, set up two option groups with
// the list of existing and then predefined languages.
form_load_include($form_state, 'inc', 'language', 'language.admin');
if (!count($names)) {
$languages = language_admin_predefined_list();
$default = key($languages);
if (empty($existing_languages)) {
$language_options = language_admin_predefined_list();
$default = key($language_options);
}
else {
$languages = array(
t('Already added languages') => $names,
$default = key($existing_languages);
$language_options = array(
t('Already added languages') => $existing_languages,
t('Languages not yet added') => language_admin_predefined_list()
);
$default = key($names);
}
$form['import'] = array('#type' => 'fieldset',
......@@ -41,7 +49,7 @@ function locale_translate_import_form($form, &$form_state) {
);
$form['import']['langcode'] = array('#type' => 'select',
'#title' => t('Import into'),
'#options' => $languages,
'#options' => $language_options,
'#default_value' => $default,
'#description' => t('Choose the language you want to add strings into. If you choose a language which is not yet set up, it will be added.'),
);
......@@ -101,16 +109,20 @@ function locale_translate_import_form_submit($form, &$form_state) {
* User interface for the translation export screen.
*/
function locale_translate_export_screen() {
// Get all languages, except English
// Get all enabled languages, except English, if we should not translate that.
drupal_static_reset('language_list');
$names = locale_language_list('name');
if (!locale_translate_english()) {
unset($names['en']);
$languages = language_list(TRUE);
$language_options = array();
foreach ($languages as $langcode => $language) {
if ($langcode != 'en' || locale_translate_english()) {
$language_options[$langcode] = $language->name;
}
}
$output = '';
// Offer translation export if any language is set up.
if (count($names)) {
$elements = drupal_get_form('locale_translate_export_po_form', $names);
if (!empty($language_options)) {
$elements = drupal_get_form('locale_translate_export_po_form', $language_options);
$output = drupal_render($elements);
}
$elements = drupal_get_form('locale_translate_export_pot_form');
......
......@@ -219,8 +219,8 @@ function locale_permission() {
*/
function locale_language_selector_form($user) {
global $language;
$languages = language_list('enabled');
$languages = $languages[1];
// Get list of enabled languages only.
$languages = language_list(TRUE);
// If the user is being created, we set the user language to the page language.
$user_preferred_language = $user->uid ? user_preferred_language($user) : $language;
......@@ -296,11 +296,16 @@ function locale_form_alter(&$form, &$form_state, $form_id) {
*/
function locale_form_node_form_alter(&$form, &$form_state) {
if (isset($form['#node']->type) && locale_multilingual_node_type($form['#node']->type)) {
$languages = language_list(TRUE);
$language_options = array(LANGUAGE_NONE => t('Language neutral'));
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
$form['language'] = array(
'#type' => 'select',
'#title' => t('Language'),
'#default_value' => (isset($form['#node']->language) ? $form['#node']->language : ''),
'#options' => array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name'),
'#options' => $language_options,
);
}
// Node type without language selector: assign the default for new nodes
......@@ -764,37 +769,12 @@ function locale_get_plural($count, $langcode = NULL) {
/**
* Returns a language name
* Returns a language name.
*/
function locale_language_name($lang) {
$list = &drupal_static(__FUNCTION__);
if (!isset($list)) {
$list = locale_language_list();
}
return ($lang && isset($list[$lang])) ? $list[$lang] : t('All');
}
/**
* Returns array of language names
*
* @param $field
* Name of language object field.
* @param $all
* Boolean to return all languages or only enabled ones
*/
function locale_language_list($field = 'name', $all = FALSE) {
if ($all) {
$languages = language_list();
}
else {
$languages = language_list('enabled');
$languages = $languages[1];
}
$list = array();
foreach ($languages as $language) {
$list[$language->langcode] = $language->$field;
}
return $list;
function locale_language_name($langcode) {
// Consider enabled languages only.
$languages = language_list(TRUE);
return ($langcode && isset($languages[$langcode])) ? $languages[$langcode]->name : t('All');
}
/**
......
......@@ -152,9 +152,12 @@ function locale_translation_filters() {
// Get all languages, except English
drupal_static_reset('language_list');
$languages = locale_language_list('name');
if (!locale_translate_english()) {
unset($languages['en']);
$languages = language_list(TRUE);
$language_options = array();
foreach ($languages as $langcode => $language) {
if ($langcode != 'en' || locale_translate_english()) {
$language_options[$langcode] = $language->name;
}
}
$filters['string'] = array(
......@@ -164,7 +167,7 @@ function locale_translation_filters() {
$filters['language'] = array(
'title' => t('Language'),
'options' => array_merge(array('all' => t('All languages'), LANGUAGE_SYSTEM => t('System (English)')), $languages),
'options' => array_merge(array('all' => t('All languages'), LANGUAGE_SYSTEM => t('System (English)')), $language_options),
);
$filters['translation'] = array(
......
......@@ -2032,8 +2032,8 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
// is for some reason not found when doing translate search. This might
// be some bug.
drupal_static_reset('language_list');
$languages = language_list('enabled');
variable_set('language_default', $languages[1]['vi']);
$languages = language_list(TRUE);
variable_set('language_default', $languages['vi']);
// First visit this page to make sure our target string is searchable.
$this->drupalGet('admin/config');
// Now the t()'ed string is in db so switch the language back to default.
......
......@@ -104,14 +104,18 @@ function node_filters() {
) + node_type_get_names(),
);
// Language filter if there is a list of languages
if ($languages = module_invoke('locale', 'language_list')) {
$languages = array(LANGUAGE_NONE => t('Language neutral')) + $languages;
// Language filter if the site is multilingual.
if (language_multilingual()) {
$languages = language_list(TRUE);
$language_options = array(LANGUAGE_NONE => t('Language neutral'));
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
$filters['language'] = array(
'title' => t('language'),
'options' => array(
'[any]' => t('any'),
) + $languages,
) + $language_options,
);
}
return $filters;
......
......@@ -258,8 +258,7 @@ function openid_form_user_register_form_alter(&$form, &$form_state) {
$candidate_languages[] = $parts[0] . '-' . $parts[2];
$candidate_languages[] = $parts[0] . '-' . $parts[1] . '-' . $parts[2];
}
$all_languages = language_list('enabled');
$enabled_languages = $all_languages[1];
$enabled_languages = language_list(TRUE);
// Iterate over the generated permutations starting with the longest (most
// specific) strings.
foreach (array_reverse($candidate_languages) as $candidate_language) {
......
......@@ -132,10 +132,16 @@ function path_admin_form($form, &$form_state, $path = array('source' => '', 'ali
// A hidden value unless locale module is enabled.
if (module_exists('locale')) {
$languages = language_list(TRUE);
$language_options = array(LANGUAGE_NONE => t('All languages'));
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
$form['langcode'] = array(
'#type' => 'select',
'#title' => t('Language'),
'#options' => array(LANGUAGE_NONE => t('All languages')) + locale_language_list('name'),
'#options' => $language_options,
'#default_value' => $path['langcode'],
'#weight' => -10,
'#description' => t('A path alias set for a specific language will always be used when displaying this page in that language, and takes precedence over path aliases set for <em>All languages</em>.'),
......
......@@ -3908,10 +3908,7 @@ function system_date_format_save($date_format, $dfid = 0) {
}
// Retrieve an array of language objects for enabled languages.
$languages = language_list('enabled');
// This list is keyed off the value of $language->enabled; we want the ones
// that are enabled (value of 1).
$languages = $languages[1];
$languages = language_list(TRUE);
$locale_format = array();
$locale_format['type'] = $date_format['type'];
......
......@@ -125,20 +125,25 @@ function translation_form_node_type_form_alter(&$form, &$form_state) {
function translation_form_node_form_alter(&$form, &$form_state) {
if (translation_supported_type($form['#node']->type)) {
$node = $form['#node'];
$languages = language_list('enabled');
$disabled_languages = isset($languages[0]) ? $languages[0] : FALSE;
$translator_widget = $disabled_languages && user_access('translate content');
// Build two lists with the disabled and enabled languages.
$languages = language_list();
$grouped_languages = array();
foreach ($languages as $langcode => $language) {
$grouped_languages[(int) $language->enabled][$langcode] = $language;
}
$translator_widget = !empty($grouped_languages[0]) && user_access('translate content');
$groups = array(t('Disabled'), t('Enabled'));
// Allow translators to enter content in disabled languages. Translators
// might need to distinguish between enabled and disabled languages, hence
// we divide them in two option groups.
if ($translator_widget) {
$options = array($groups[1] => array(LANGUAGE_NONE => t('Language neutral')));
$language_list = locale_language_list('name', TRUE);
foreach (array(1, 0) as $status) {
$group = $groups[$status];
foreach ($languages[$status] as $langcode => $language) {
$options[$group][$langcode] = $language_list[$langcode];
foreach ($grouped_languages[$status] as $langcode => $language) {
$options[$group][$langcode] = $language->name;
}
}
$form['language']['#options'] = $options;
......@@ -208,8 +213,7 @@ function translation_node_view($node, $view_mode) {
// If the site has no translations or is not multilingual we have no content
// translation links to display.
if (isset($node->tnid) && language_multilingual() && $translations = translation_node_get_translations($node->tnid)) {
$languages = language_list('enabled');
$languages = $languages[1];
$languages = language_list(TRUE);
// There might be a language provider enabled defining custom language
// switch links which need to be taken into account while generating the
......
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