diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 9e2c875..8a7b1c0 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -206,6 +206,13 @@ const LANGUAGE_NOT_APPLICABLE = 'zxx';
const LANGUAGE_MULTIPLE = 'mul';
/**
+ * The language code used when referring to all languages.
+ *
+ * @todo W3C uses this for 'Allar', need to find a better code.
+ */
+const LANGUAGE_ALL = 'all';
+
+/**
* The type of language used to define the content language.
*/
const LANGUAGE_TYPE_CONTENT = 'language_content';
@@ -231,6 +238,16 @@ const LANGUAGE_LTR = 0;
const LANGUAGE_RTL = 1;
/**
+ * Flag for language list extension to add disabled languages.
+ */
+const LANGUAGE_ADD_DISABLED = 1;
+
+/**
+ * Flag for language list extension to add locked languages.
+ */
+const LANGUAGE_ADD_LOCKED = 2;
+
+/**
* Time of the current request in seconds elapsed since the Unix Epoch.
*
* This differs from $_SERVER['REQUEST_TIME'], which is stored as a float
@@ -2502,43 +2519,50 @@ function language_multilingual() {
/**
* Returns a list of configured languages.
*
- * @param $only_enabled
- * (optional) Whether to return only enabled languages.
+ * @param $flags
+ * (optional) A combination of LANGUAGE_ADD_DISABLED and LANGUAGE_ADD_LOCKED
+ * depending on the need for disabled and locked (special) languages in the
+ * returned list.
*
* @return
* An associative array of languages, keyed by the language code, ordered by
* weight ascending and name ascending.
*/
-function language_list($only_enabled = FALSE) {
+function language_list($flags = NULL) {
+
$languages = &drupal_static(__FUNCTION__);
+
// Initialize master language list.
if (!isset($languages)) {
- // Initialize local language list caches.
- $languages = array('all' => array(), 'enabled' => array());
+ // 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.
- $languages['all'] = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode');
+ $languages = db_query('SELECT *, 0 as `default` FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode');
+ $languages[$default->langcode]->default = 1;
}
else {
// No language module, so use the default language only.
- $languages['all'][$default->langcode] = $default;
+ $languages[$default->langcode] = $default;
}
+ }
- // 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];
- }
+ // Filter the full list of languages based on the criteria in $flags. By
+ // default we remove the disabled and locked languages, but the caller may
+ // request for those languages to be added as well.
+ $filtered_languages = array();
+ foreach ($languages as $langcode => $language) {
+ if ((!$language->enabled && !($flags & LANGUAGE_ADD_DISABLED)) ||
+ ($language->locked && !($flags & LANGUAGE_ADD_LOCKED))) {
+ continue;
}
+ $filtered_languages[$langcode] = $language;
}
- return $only_enabled ? $languages['enabled'] : $languages['all'];
+ return $filtered_languages;
}
/**
@@ -2551,7 +2575,7 @@ function language_list($only_enabled = FALSE) {
* A fully-populated language object or FALSE.
*/
function language_load($langcode) {
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
return isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
}
@@ -2591,6 +2615,7 @@ function language_default() {
'direction' => 0,
'enabled' => 1,
'weight' => 0,
+ 'locked' => 0,
));
$default->default = TRUE;
return $default;
diff --git a/core/includes/language.inc b/core/includes/language.inc
index 76c4318..553b0dc 100644
--- a/core/includes/language.inc
+++ b/core/includes/language.inc
@@ -338,8 +338,7 @@ function language_negotiation_method_invoke($method_id, $method = NULL) {
if (!isset($results[$method_id])) {
global $user;
- // Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list();
if (!isset($method)) {
$negotiation_info = language_negotiation_info();
diff --git a/core/includes/locale.inc b/core/includes/locale.inc
index 1f9567b..31602b6 100644
--- a/core/includes/locale.inc
+++ b/core/includes/locale.inc
@@ -354,8 +354,7 @@ function locale_language_url_fallback($language = NULL, $language_type = LANGUAG
* Translation links may be provided by other modules.
*/
function locale_language_switcher_url($type, $path) {
- // Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list();
$links = array();
foreach ($languages as $language) {
@@ -379,8 +378,7 @@ 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;
- // Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list();
$links = array();
$query = $_GET;
@@ -416,18 +414,16 @@ function locale_language_url_rewrite_url(&$path, &$options) {
$languages = &$drupal_static_fast['languages'];
if (!isset($languages)) {
- // Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list();
$languages = array_flip(array_keys($languages));
}
-
// Language can be passed as an option, or we go for current URL language.
if (!isset($options['language'])) {
global $language_url;
$options['language'] = $language_url;
}
// We allow only enabled languages here.
- elseif (!isset($languages[$options['language']->langcode])) {
+ elseif (is_object($options['language']) && !isset($languages[$options['language']->langcode])) {
unset($options['language']);
return;
}
@@ -455,7 +451,7 @@ function locale_language_url_rewrite_url(&$path, &$options) {
case LANGUAGE_NEGOTIATION_URL_PREFIX:
$prefixes = locale_language_negotiation_url_prefixes();
- if (!empty($prefixes[$options['language']->langcode])) {
+ if (is_object($options['language']) && !empty($prefixes[$options['language']->langcode])) {
$options['prefix'] = $prefixes[$options['language']->langcode] . '/';
}
break;
@@ -503,7 +499,7 @@ function locale_language_url_rewrite_session(&$path, &$options) {
global $user;
if (!$user->uid) {
// Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list();
$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_method_enabled(LANGUAGE_NEGOTIATION_SESSION);
@@ -715,7 +711,7 @@ function _locale_rebuild_js($langcode = NULL) {
$language = $language_interface;
}
else {
- // Get information about the locale.
+ // Get information about the language.
$languages = language_list();
$language = $languages[$langcode];
}
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 1660d7d..be27d81 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -193,9 +193,10 @@ function update_prepare_d8_language() {
update_module_add_to_system($modules);
update_module_enable($modules);
- // Rename 'language' column to 'langcode'.
+ // Rename 'language' column to 'langcode', add locked column.
require_once DRUPAL_ROOT . '/core/modules/language/language.install';
language_update_8000();
+ language_update_8001();
}
}
@@ -851,7 +852,7 @@ function update_retrieve_dependencies() {
/**
* Updates config with values set on Drupal 7.x
- *
+ *
* Provide a generalised method to migrate variables from Drupal 7 to Drupal 8's
* configuration management system.
*
@@ -863,8 +864,8 @@ function update_retrieve_dependencies() {
* An array to map new to old configuration naming conventions. Example:
* @code
* array('new_config' => 'old_config')
- * @endcode
- * This would update the value for new_config to the value old_config has in
+ * @endcode
+ * This would update the value for new_config to the value old_config has in
* the variable table.
*/
function update_variables_to_config($config_name, $variable_map = array()) {
diff --git a/core/modules/field/field.multilingual.inc b/core/modules/field/field.multilingual.inc
index a4f5f8f..0a9fd4b 100644
--- a/core/modules/field/field.multilingual.inc
+++ b/core/modules/field/field.multilingual.inc
@@ -164,14 +164,14 @@ function _field_language_suggestion($available_languages, $language_suggestion,
/**
* Returns available content languages.
*
- * The languages that may be associated to fields include
- * LANGUAGE_NOT_SPECIFIED.
+ * The languages that may be associated to fields may include
+ * LANGUAGE_NOT_SPECIFIED, LANGUAGE_NOT_APPLICABLE and LANGUAGE_MULTIPLE.
*
* @return
* An array of language codes.
*/
function field_content_languages() {
- return array_keys(language_list() + array(LANGUAGE_NOT_SPECIFIED => NULL));
+ return array_keys(language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED));
}
/**
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 33bc147..0e2fdd7 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -10,7 +10,7 @@
*/
function language_admin_overview_form($form, &$form_state) {
drupal_static_reset('language_list');
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
$default = language_default();
$form['languages'] = array(
@@ -29,8 +29,24 @@ function language_admin_overview_form($form, &$form_state) {
foreach ($languages as $langcode => $language) {
$form['languages'][$langcode]['#weight'] = $language->weight;
+ $title = check_plain($language->name);
+ $description = '';
+ switch ($langcode) {
+ case LANGUAGE_NOT_APPLICABLE:
+ $description = t('For language independent content.');
+ break;
+ case LANGUAGE_NOT_SPECIFIED:
+ $description = t('Use this when the language is not (yet) known.');
+ break;
+ case LANGUAGE_MULTIPLE:
+ $description = t('Use this when multiple languages can be assigned, such as a multilingual PDF.');
+ break;
+ }
+ if (!empty($description)) {
+ $title .= '
' . $description . '
';
+ }
$form['languages'][$langcode]['name'] = array(
- '#markup' => check_plain($language->name),
+ '#markup' => $title,
);
$form['languages'][$langcode]['enabled'] = array(
'#type' => 'checkbox',
@@ -61,17 +77,22 @@ function language_admin_overview_form($form, &$form_state) {
'#theme_wrappers' => array('language_admin_operations'),
'#weight' => 100,
);
- $form['languages'][$langcode]['operations']['edit'] = array(
- '#type' => 'link',
- '#title' => t('edit'),
- '#href' => 'admin/config/regional/language/edit/' . $langcode,
- );
- $form['languages'][$langcode]['operations']['delete'] = array(
- '#type' => 'link',
- '#title' => t('delete'),
- '#href' => 'admin/config/regional/language/delete/' . $langcode,
- '#access' => $langcode != $default->langcode,
- );
+ if (empty($language->locked)) {
+ $form['languages'][$langcode]['operations']['edit'] = array(
+ '#type' => 'link',
+ '#title' => t('edit'),
+ '#href' => 'admin/config/regional/language/edit/' . $langcode,
+ );
+ $form['languages'][$langcode]['operations']['delete'] = array(
+ '#type' => 'link',
+ '#title' => t('delete'),
+ '#href' => 'admin/config/regional/language/delete/' . $langcode,
+ '#access' => $langcode != $default->langcode,
+ );
+ }
+ else{
+ $form['languages'][$langcode]['default']['#disabled'] = TRUE;
+ }
}
$form['actions'] = array('#type' => 'actions');
@@ -148,7 +169,7 @@ function theme_language_admin_overview_form_table($variables) {
* Process language overview form submissions, updating existing languages.
*/
function language_admin_overview_form_submit($form, &$form_state) {
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
$old_default = language_default();
foreach ($languages as $langcode => $language) {
@@ -308,7 +329,7 @@ function language_admin_add_custom_form_validate($form, &$form_state) {
// Reuse the editing form validation routine if we add a custom language.
language_admin_edit_form_validate($form, $form_state);
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
if (isset($languages[$langcode])) {
form_set_error('langcode', t('The language %language (%langcode) already exists.', array('%language' => $languages[$langcode]->name, '%langcode' => $langcode)));
}
@@ -368,7 +389,7 @@ function language_admin_edit_form_validate($form, &$form_state) {
*/
function language_admin_edit_form_submit($form, &$form_state) {
// Prepare a language object for saving
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$langcode = $form_state['values']['langcode'];
$language = $languages[$langcode];
$language->name = $form_state['values']['name'];
@@ -389,7 +410,7 @@ function language_admin_delete_form($form, &$form_state, $language) {
}
// For other languages, warn user that data loss is ahead.
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
if (!isset($languages[$langcode])) {
drupal_not_found();
@@ -406,7 +427,7 @@ function language_admin_delete_form($form, &$form_state, $language) {
*/
function language_admin_delete_form_submit($form, &$form_state) {
$langcode = $form_state['values']['langcode'];
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$language = $languages[$langcode];
$success = language_delete($langcode);
@@ -424,7 +445,7 @@ function language_admin_delete_form_submit($form, &$form_state) {
*/
function language_admin_predefined_list() {
include_once DRUPAL_ROOT . '/core/includes/standard.inc';
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$predefined = standard_language_list();
foreach ($predefined as $key => $value) {
if (isset($languages[$key])) {
diff --git a/core/modules/language/language.install b/core/modules/language/language.install
index ecf637d..00b4211 100644
--- a/core/modules/language/language.install
+++ b/core/modules/language/language.install
@@ -9,8 +9,51 @@
* Implements hook_install().
*/
function language_install() {
- // Add the default language to the database too.
+
+ // Add the default language at first so that language_list() returns this in
+ // language_special_languages().
language_save(language_default());
+ $languages = language_special_languages();
+ foreach ($languages as $language) {
+ language_save($language);
+ }
+}
+
+/**
+ * List of special languages to install on a site.
+ *
+ * @return
+ * An array of language objects.
+ */
+function language_special_languages() {
+ $locked_language = array(
+ 'default' => FALSE,
+ 'locked' => TRUE,
+ 'enabled' => TRUE,
+ );
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
+
+ // Language list is ordered by weight, get the biggest one.
+ $keys = array_keys($languages);
+ $max_weight = $languages[array_pop($keys)]->weight;
+ $languages = array();
+
+ $languages[LANGUAGE_NOT_SPECIFIED] = (object) (array(
+ 'langcode' => LANGUAGE_NOT_SPECIFIED,
+ 'name' => t('Not specified'),
+ 'weight' => ++$max_weight,
+ ) + $locked_language);
+ $languages[LANGUAGE_NOT_APPLICABLE] = (object) (array(
+ 'langcode' => LANGUAGE_NOT_APPLICABLE,
+ 'name' => t('Not applicable'),
+ 'weight' => ++$max_weight,
+ ) + $locked_language);
+ $languages[LANGUAGE_MULTIPLE] = (object) (array(
+ 'langcode' => LANGUAGE_MULTIPLE,
+ 'name' => t('Multiple'),
+ 'weight' => ++$max_weight,
+ ) + $locked_language);
+ return $languages;
}
/**
@@ -65,6 +108,13 @@ function language_schema() {
'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(
@@ -101,3 +151,49 @@ function language_update_8000() {
variable_set('language_default', $language_default);
}
}
+
+/**
+ * Adds the locked column and saves the special languages.
+ */
+function language_update_8001() {
+ if (!db_field_exists('language', 'locked')) {
+ $locked_spec = array(
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => 'A boolean indicating whether the administrator can edit or delete the language.',
+ );
+ db_add_field('language', 'locked', $locked_spec);
+
+ $max_weight = db_query('SELECT MAX(weight) FROM {language}')->fetchField();
+ $languages = array();
+ $languages[LANGUAGE_NOT_SPECIFIED] = array(
+ 'langcode' => LANGUAGE_NOT_SPECIFIED,
+ 'name' => 'Not specified',
+ 'weight' => ++$max_weight,
+ );
+ $languages[LANGUAGE_NOT_APPLICABLE] = array(
+ 'langcode' => LANGUAGE_NOT_APPLICABLE,
+ 'name' => 'Not applicable',
+ 'weight' => ++$max_weight,
+ );
+ $languages[LANGUAGE_MULTIPLE] = array(
+ 'langcode' => LANGUAGE_MULTIPLE,
+ 'name' => 'Multiple',
+ 'weight' => ++$max_weight,
+ );
+ foreach ($languages as $language) {
+ db_insert('language')
+ ->fields(array(
+ 'langcode' => $language['langcode'],
+ 'name' => $language['name'],
+ 'weight' => $language['weight'],
+ // These languages are locked, default to enabled.
+ 'locked' => 1,
+ 'enabled' => 1,
+ ))
+ ->execute();
+ }
+ }
+}
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 20f7c62..142e633 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -22,7 +22,7 @@ function language_help($path, $arg) {
return $output;
case 'admin/config/regional/language':
- return '' . t('With multiple languages enabled, registered users may select their preferred language and authors can assign a specific language to content.') . '
';
+ return '' . t('With multiple languages enabled, registered users can select their preferred language and authors can assign a specific language to content.') . '
';
case 'admin/config/regional/language/add':
return '' . t('Add a language to be supported by your site. If your desired language is not available, pick Custom language... at the end and provide a language code and other details manually.') . '
';
@@ -60,20 +60,29 @@ function language_menu() {
'title' => 'Edit language',
'page callback' => 'drupal_get_form',
'page arguments' => array('language_admin_edit_form', 5),
- 'access arguments' => array('administer languages'),
+ 'access callback' => 'language_access_language_edit_or_delete',
+ 'access arguments' => array(5),
'file' => 'language.admin.inc',
);
$items['admin/config/regional/language/delete/%language'] = array(
'title' => 'Confirm delete',
'page callback' => 'drupal_get_form',
'page arguments' => array('language_admin_delete_form', 5),
- 'access arguments' => array('administer languages'),
+ 'access callback' => 'language_access_language_edit_or_delete',
+ 'access arguments' => array(5),
'file' => 'language.admin.inc',
);
return $items;
}
/**
+ * Editing or deleting locked languages should not be possible.
+ */
+function language_access_language_edit_or_delete($language) {
+ return !$language->locked && user_access('administer languages');
+}
+
+/**
* Implements hook_permission().
*/
function language_permission() {
@@ -144,11 +153,10 @@ function language_save($language) {
}
// Update language count based on enabled language count.
- variable_set('language_count', db_query('SELECT COUNT(langcode) FROM {language} WHERE enabled = 1')->fetchField());
+ variable_set('language_count', db_query('SELECT COUNT(langcode) FROM {language} WHERE enabled = 1 AND locked = 0')->fetchField());
// Kill the static cache in language_list().
drupal_static_reset('language_list');
-
return $language;
}
@@ -161,8 +169,8 @@ function language_save($language) {
* TRUE if language is successfully deleted. Otherwise FALSE.
*/
function language_delete($langcode) {
- $languages = language_list();
- if (isset($languages[$langcode])) {
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
+ if (isset($languages[$langcode]) && !$languages[$langcode]->locked) {
$language = $languages[$langcode];
module_invoke_all('language_delete', $language);
diff --git a/core/modules/language/language.test b/core/modules/language/language.test
index 0a59937..b288d6b 100644
--- a/core/modules/language/language.test
+++ b/core/modules/language/language.test
@@ -122,7 +122,7 @@ 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_languages = language_list(TRUE);
+ $enabled_languages = language_list();
$this->assertEqual(variable_get('language_count', 1), count($enabled_languages), t('Language count is correct.'));
// Delete a disabled language.
// Disable an enabled language.
@@ -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_languages = language_list(TRUE);
+ $enabled_languages = language_list();
// 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.
diff --git a/core/modules/locale/locale.admin.inc b/core/modules/locale/locale.admin.inc
index 321b8ce..9527d9b 100644
--- a/core/modules/locale/locale.admin.inc
+++ b/core/modules/locale/locale.admin.inc
@@ -254,8 +254,7 @@ function language_negotiation_configure_url_form($form, &$form_state) {
),
);
- // Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$prefixes = locale_language_negotiation_url_prefixes();
$domains = locale_language_negotiation_url_domains();
foreach ($languages as $langcode => $language) {
@@ -291,8 +290,7 @@ function language_negotiation_configure_url_form($form, &$form_state) {
* the prefix and domain are only blank for the default.
*/
function language_negotiation_configure_url_form_validate($form, &$form_state) {
- // Get the enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$default = language_default();
// Count repeated values for uniqueness check.
@@ -330,14 +328,14 @@ function language_negotiation_configure_url_form_validate($form, &$form_state) {
}
// Domain names should not contain protocol and/or ports.
- foreach ($languages as $langcode => $name) {
+ foreach ($languages as $langcode => $language) {
$value = $form_state['values']['domain'][$langcode];
if (!empty($value)) {
// Ensure we have a protocol but only one protocol in the setting for
// parse_url() checking against the hostname.
$host = 'http://' . str_replace(array('http://', 'https://'), '', $value);
if (parse_url($host, PHP_URL_HOST) != $value) {
- form_error($form['domain'][$langcode], t('The domain for %language may only contain the domain name, not a protocol and/or port.', array( '%language' => $name)));
+ form_error($form['domain'][$langcode], t('The domain for %language may only contain the domain name, not a protocol and/or port.', array( '%language' => $language->name)));
}
}
}
@@ -418,9 +416,7 @@ function locale_date_format_language_overview_page() {
array('data' => t('Operations'), 'colspan' => '2'),
);
- // Get the enabled languages only.
- $languages = language_list(TRUE);
-
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
foreach ($languages as $langcode => $language) {
$row = array();
$row[] = $language->name;
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index a4982e1..c745eea 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -12,7 +12,7 @@ include_once DRUPAL_ROOT . '/core/includes/gettext.inc';
*/
function locale_translate_import_form($form, &$form_state) {
drupal_static_reset('language_list');
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
// Initialize a language list to the ones available, including English if we
// are to translate Drupal to English as well.
@@ -76,7 +76,7 @@ function locale_translate_import_form_submit($form, &$form_state) {
// Add language, if not yet supported
drupal_static_reset('language_list');
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
$langcode = $form_state['values']['langcode'];
if (!isset($languages[$langcode])) {
include_once DRUPAL_ROOT . '/core/includes/standard.inc';
@@ -109,12 +109,12 @@ function locale_translate_import_form_submit($form, &$form_state) {
* User interface for the translation export screen.
*/
function locale_translate_export_screen() {
- // Get all enabled languages, except English, if we should not translate that.
+ // Get all configurable languages, except English, if we should not translate that.
drupal_static_reset('language_list');
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$language_options = array();
foreach ($languages as $langcode => $language) {
- if ($langcode != 'en' || locale_translate_english()) {
+ if (empty($language->locked) && ($langcode != 'en' || locale_translate_english())) {
$language_options[$langcode] = $language->name;
}
}
@@ -173,7 +173,7 @@ function locale_translate_export_po_form_submit($form, &$form_state) {
// If template is required, language code is not given.
$language = NULL;
if (isset($form_state['values']['langcode'])) {
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$language = $languages[$form_state['values']['langcode']];
}
_locale_export_po($language, _locale_export_po_generate($language, _locale_export_get_strings($language)));
@@ -211,8 +211,8 @@ function locale_translate_batch_import_files($langcode = NULL, $finish_feedback
}
else {
// If langcode was not provided, make sure to only import files for the
- // languages we have enabled.
- $langcodes = array_keys(language_list());
+ // languages we have configured.
+ $langcodes = array_keys(language_list(LANGUAGE_ADD_DISABLED));
}
foreach ($langcodes as $langcode) {
$files = array_merge($files, file_scan_directory($directory, '!' . (!empty($langcode) ? '\.' . preg_quote($langcode, '!') : '') . '\.po$!', array('recurse' => FALSE)));
diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install
index acf3a80..faf1770 100644
--- a/core/modules/locale/locale.install
+++ b/core/modules/locale/locale.install
@@ -44,7 +44,7 @@ function locale_install() {
function locale_enable() {
require_once DRUPAL_ROOT . '/core/includes/locale.inc';
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$prefixes_old = locale_language_negotiation_url_prefixes();
$domains_old = locale_language_negotiation_url_domains();
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 6d3ded0..2150011 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -220,15 +220,14 @@ function locale_permission() {
*/
function locale_language_selector_form($user) {
global $language_interface;
- // Get list of enabled languages only.
- $languages = language_list(TRUE);
+ $languages = language_list();
// 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_interface;
$names = array();
- foreach ($languages as $langcode => $item) {
- $names[$langcode] = $item->name;
+ foreach ($languages as $langcode => $language) {
+ $names[$langcode] = $language->name;
}
// Get language negotiation settings.
$mode = language_negotiation_method_get_first(LANGUAGE_TYPE_INTERFACE) != LANGUAGE_NEGOTIATION_DEFAULT;
@@ -530,6 +529,9 @@ function locale_modules_disabled($modules) {
* Implements hook_language_insert().
*/
function locale_language_insert($language) {
+ if (!empty($language->locked)) {
+ return;
+ }
// Add new language to the list of language prefixes.
$prefixes = locale_language_negotiation_url_prefixes();
$prefixes[$language->langcode] = (empty($language->default) ? $language->langcode : '');
@@ -924,7 +926,6 @@ function locale_block_view($type) {
if (language_multilingual()) {
$path = drupal_is_front_page() ? '' : $_GET['q'];
$links = language_negotiation_get_switch_links($type, $path);
-
if (isset($links->links)) {
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
$class = "language-switcher-{$links->method_id}";
@@ -951,6 +952,7 @@ function locale_preprocess_block(&$variables) {
* Rewrite outbound URLs with language based prefixes.
*/
function locale_url_outbound_alter(&$path, &$options, $original_path) {
+
// Only modify internal URLs.
if (!$options['external'] && language_multilingual()) {
static $drupal_static_fast;
@@ -981,13 +983,13 @@ function locale_url_outbound_alter(&$path, &$options, $original_path) {
$callbacks = array_keys($callbacks);
}
- foreach ($callbacks as $callback) {
- $callback($path, $options);
- }
-
// No language dependent path allowed in this mode.
if (empty($callbacks)) {
unset($options['language']);
+ return;
+ }
+ foreach ($callbacks as $callback) {
+ $callback($path, $options);
}
}
}
@@ -1019,7 +1021,7 @@ function locale_form_language_admin_overview_form_alter(&$form, &$form_state) {
'translated' => 0,
'ratio' => 0,
);
- if ($langcode != 'en' || locale_translate_english()) {
+ if (empty($language->locked) && ($langcode != 'en' || locale_translate_english())) {
$form['languages'][$langcode]['locale_statistics'] = array(
'#type' => 'link',
'#title' => t('@translated/@total (@ratio%)', array(
@@ -1030,9 +1032,14 @@ function locale_form_language_admin_overview_form_alter(&$form, &$form_state) {
'#href' => 'admin/config/regional/translate/translate',
);
}
+ elseif ($langcode == LANGUAGE_SYSTEM) {
+ $form['languages'][$langcode]['locale_statistics'] = array(
+ '#markup' => t('Built-in'),
+ );
+ }
else {
$form['languages'][$langcode]['locale_statistics'] = array(
- '#markup' => t('not applicable'),
+ '#markup' => t('Not applicable'),
);
}
}
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index 3df2832..1738e78 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -28,7 +28,7 @@ function _locale_translate_seek() {
if (!($query = _locale_translate_seek_query())) {
$query = array(
'translation' => 'all',
- 'language' => 'all',
+ 'language' => LANGUAGE_ALL,
'string' => '',
);
}
@@ -64,7 +64,7 @@ function _locale_translate_seek() {
}
$limit_language = NULL;
- if ($query['language'] != LANGUAGE_SYSTEM && $query['language'] != 'all') {
+ if ($query['language'] != LANGUAGE_SYSTEM && $query['language'] != LANGUAGE_ALL) {
$sql_query->condition('language', $query['language']);
$limit_language = $query['language'];
}
@@ -113,7 +113,7 @@ function _locale_translate_language_list($translation, $limit_language) {
// Add CSS.
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
if (!locale_translate_english()) {
unset($languages['en']);
}
@@ -150,9 +150,9 @@ function _locale_translate_seek_query() {
function locale_translation_filters() {
$filters = array();
- // Get all languages, except English
+ // Get all configurable languages, except English if not translatable.
drupal_static_reset('language_list');
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$language_options = array();
foreach ($languages as $langcode => $language) {
if ($langcode != 'en' || locale_translate_english()) {
@@ -167,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)')), $language_options),
+ 'options' => array_merge(array(LANGUAGE_ALL => t('All languages'), LANGUAGE_SYSTEM => t('System (English)')), $language_options),
);
$filters['translation'] = array(
@@ -327,10 +327,11 @@ function locale_translate_edit_form($form, &$form_state, $lid) {
// Include default form controls with empty values for all languages.
// This ensures that the languages are always in the same order in forms.
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
if (!locale_translate_english()) {
unset($languages['en']);
}
+
// Store languages to iterate for validation and submission of the form.
$form_state['langcodes'] = array_keys($languages);
$plural_formulas = variable_get('locale_translation_plurals', array());
diff --git a/core/modules/locale/locale.test b/core/modules/locale/locale.test
index f2395ad..aedacc3 100644
--- a/core/modules/locale/locale.test
+++ b/core/modules/locale/locale.test
@@ -2350,7 +2350,7 @@ 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(TRUE);
+ $languages = language_list();
variable_set('language_default', $languages['vi']);
// First visit this page to make sure our target string is searchable.
$this->drupalGet('admin/config');
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index ac18da7..2d4ec70 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -106,10 +106,10 @@ function node_filters() {
// Language filter if language support is present.
if (language_multilingual()) {
- $languages = language_list(TRUE);
- $language_options = array(LANGUAGE_NOT_SPECIFIED => t('- None -'));
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
foreach ($languages as $langcode => $language) {
- $language_options[$langcode] = $language->name;
+ // Make locked languages appear special in the list.
+ $language_options[$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
}
$filters['language'] = array(
'title' => t('language'),
@@ -474,7 +474,7 @@ function node_admin_nodes() {
$nodes = node_load_multiple($nids);
// Prepare the list of nodes.
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
$destination = drupal_get_destination();
$options = array();
foreach ($nodes as $node) {
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index b5ed7e8..f81731d 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2857,8 +2857,9 @@ function node_form_search_form_alter(&$form, $form_state) {
// Languages:
$language_options = array();
- foreach (language_list(TRUE) as $langcode => $language) {
- $language_options[$langcode] = $language->name;
+ foreach (language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED) as $langcode => $language) {
+ // Make locked languages appear special in the list.
+ $language_options[$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
}
if (count($language_options) > 1) {
$form['advanced']['language'] = array(
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index 4e94b26..9389731 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -176,17 +176,17 @@ function node_form($form, &$form_state, $node) {
$form['#node'] = $node;
if (variable_get('node_type_language_' . $node->type, 0) && module_exists('language')) {
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
$language_options = array();
foreach ($languages as $langcode => $language) {
- $language_options[$langcode] = $language->name;
+ // Make locked languages appear special in the list.
+ $language_options[$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
}
$form['langcode'] = array(
'#type' => 'select',
'#title' => t('Language'),
- '#default_value' => (isset($node->langcode) ? $node->langcode : ''),
+ '#default_value' => (isset($node->langcode) ? $node->langcode : LANGUAGE_NOT_SPECIFIED),
'#options' => $language_options,
- '#empty_value' => LANGUAGE_NOT_SPECIFIED,
);
}
else {
diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module
index a3df38f..2482c4e 100644
--- a/core/modules/openid/openid.module
+++ b/core/modules/openid/openid.module
@@ -263,7 +263,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];
}
- $enabled_languages = language_list(TRUE);
+ $enabled_languages = language_list();
// Iterate over the generated permutations starting with the longest (most
// specific) strings.
foreach (array_reverse($candidate_languages) as $candidate_language) {
diff --git a/core/modules/path/path.admin.inc b/core/modules/path/path.admin.inc
index 24921b8..d6bb7b7 100644
--- a/core/modules/path/path.admin.inc
+++ b/core/modules/path/path.admin.inc
@@ -145,7 +145,7 @@ function path_admin_form($form, &$form_state, $path = array('source' => '', 'ali
// A hidden value unless language.module is enabled.
if (module_exists('language')) {
- $languages = language_list(TRUE);
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
foreach ($languages as $langcode => $language) {
$language_options[$langcode] = $language->name;
}
diff --git a/core/modules/simpletest/tests/upgrade/upgrade.language.test b/core/modules/simpletest/tests/upgrade/upgrade.language.test
index 192f00c..b57c744 100644
--- a/core/modules/simpletest/tests/upgrade/upgrade.language.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade.language.test
@@ -37,7 +37,7 @@ class LanguageUpgradePathTestCase extends UpgradePathTestCase {
// Ensure Catalan was properly upgraded to be the new default language.
$this->assertTrue(language_default()->langcode == 'ca', t('Catalan is the default language'));
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
foreach ($languages as $language) {
$this->assertTrue($language->default == ($language->langcode == 'ca'), t('@language default property properly set', array('@language' => $language->name)));
}
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 2b8eb8a..67e408e 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3899,8 +3899,8 @@ function system_date_format_save($date_format, $dfid = 0) {
drupal_write_record('date_formats', $info, $keys);
}
- // Retrieve an array of language objects for enabled languages.
- $languages = language_list(TRUE);
+ // Retrieve an array of language objects for configurable languages.
+ $languages = language_list(LANGUAGE_ADD_DISABLED);
$locale_format = array();
$locale_format['type'] = $date_format['type'];
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index fa73df5..952c02e 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -137,7 +137,7 @@ function translation_form_node_form_alter(&$form, &$form_state) {
$node = $form['#node'];
// Build two lists with the disabled and enabled languages.
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ADD_DISABLED | LANGUAGE_ADD_LOCKED);
$grouped_languages = array();
foreach ($languages as $langcode => $language) {
$grouped_languages[(int) $language->enabled][$langcode] = $language;
@@ -149,7 +149,7 @@ function translation_form_node_form_alter(&$form, &$form_state) {
// 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_NOT_SPECIFIED => t('- None -')));
+ $options = array();
foreach (array(1, 0) as $status) {
$group = $groups[$status];
foreach ($grouped_languages[$status] as $langcode => $language) {
@@ -223,7 +223,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(TRUE);
+ $languages = language_list(LANGUAGE_ADD_LOCKED);
// There might be a language provider enabled defining custom language
// switch links which need to be taken into account while generating the
@@ -238,8 +238,7 @@ function translation_node_view($node, $view_mode) {
foreach ($translations as $langcode => $translation) {
// Do not show links to the same node, to unpublished translations or to
// translations in disabled languages.
- if ($translation->status && isset($languages[$langcode]) && $langcode != $node->langcode) {
- $language = $languages[$langcode];
+ if ($translation->status && isset($languages[$langcode]) && $language->enabled && $langcode != $node->langcode) {
$key = "translation_$langcode";
if (isset($custom_links->links[$langcode])) {
@@ -248,7 +247,7 @@ function translation_node_view($node, $view_mode) {
else {
$links[$key] = array(
'href' => "node/{$translation->nid}",
- 'title' => $language->name,
+ 'title' => language_name($langcode),
'language' => $language,
);
}
@@ -295,7 +294,7 @@ function translation_node_prepare($node) {
return;
}
- $language_list = language_list();
+ $language_list = language_list(LANGUAGE_ADD_DISABLED);
$langcode = $_GET['target'];
if (!isset($language_list[$langcode]) || ($source_node->langcode == $langcode)) {
// If not supported language, or same language as source node, break.
diff --git a/core/modules/translation/translation.pages.inc b/core/modules/translation/translation.pages.inc
index 66dfc42..4a5c264 100644
--- a/core/modules/translation/translation.pages.inc
+++ b/core/modules/translation/translation.pages.inc
@@ -33,7 +33,7 @@ function translation_node_overview($node) {
$type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE);
$header = array(t('Language'), t('Title'), t('Status'), t('Operations'));
- foreach (language_list() as $langcode => $language) {
+ foreach (language_list(LANGUAGE_ADD_DISABLED) as $langcode => $language) {
$options = array();
$language_name = $language->name;
if (isset($translations[$langcode])) {