summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwebchick2012-06-15 17:03:15 (GMT)
committerwebchick2012-06-15 17:03:15 (GMT)
commit18040223ad5a1b5b7d6ed2dc727647f5b79c42dc (patch)
tree0eeb43595220d400d172efa0d2adfe4c6ad6d1c5
parent9aaf3229920538b11194934c7ec3eb6345d368f6 (diff)
Issue #1471432 by Gábor Hojtsy, vasi1186, tobiasb, kalman.hosszu, Schnitzel, nod_, pixelite, dawehner: Rework language_list(), let people use more special languages.
-rw-r--r--core/includes/bootstrap.inc81
-rw-r--r--core/includes/update.inc58
-rw-r--r--core/lib/Drupal/Core/Language/Language.php1
-rw-r--r--core/modules/block/block.admin.inc6
-rw-r--r--core/modules/entity/lib/Drupal/entity/Entity.php7
-rw-r--r--core/modules/entity/lib/Drupal/entity/Tests/EntityTranslationTest.php2
-rw-r--r--core/modules/field/field.multilingual.inc31
-rw-r--r--core/modules/field/lib/Drupal/field/Tests/TranslationTest.php19
-rw-r--r--core/modules/language/language.admin.inc50
-rw-r--r--core/modules/language/language.install14
-rw-r--r--core/modules/language/language.module42
-rw-r--r--core/modules/language/language.negotiation.inc6
-rw-r--r--core/modules/node/node.admin.inc8
-rw-r--r--core/modules/node/node.module5
-rw-r--r--core/modules/node/node.pages.inc8
-rw-r--r--core/modules/openid/openid.module4
-rw-r--r--core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php8
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php2
-rw-r--r--core/modules/translation/translation.module7
19 files changed, 269 insertions, 90 deletions
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index acc82d6..8d3f4dc 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -204,6 +204,11 @@ const LANGUAGE_NOT_APPLICABLE = 'zxx';
const LANGUAGE_MULTIPLE = 'mul';
/**
+ * The language code used when referring to all languages.
+ */
+const LANGUAGE_ALL = TRUE;
+
+/**
* The type of language used to define the content language.
*/
const LANGUAGE_TYPE_CONTENT = 'language_content';
@@ -2653,18 +2658,28 @@ function language_multilingual() {
/**
* Returns a list of configured languages.
*
+ * @param $all
+ * (optional) A flag depending on the need for locked 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() {
+function language_list($all = FALSE) {
+
$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.
- $languages = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode', PDO::FETCH_ASSOC);
+ $languages = db_query('SELECT *, 0 as `default` FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode', PDO::FETCH_ASSOC);
// Initialize default property so callers have an easy reference and can
// save the same object without data loss.
@@ -2677,8 +2692,57 @@ function language_list() {
// No language module, so use the default language only.
$languages = array($default->langcode => $default);
}
+ // Add the special languages, they will be filtered later if needed.
+ $languages += language_locked_languages();
}
+ // 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
+ // those languages to be added as well.
+ $filtered_languages = array();
+ foreach ($languages as $langcode => $language) {
+ if ($language->locked && !$all) {
+ continue;
+ }
+ $filtered_languages[$langcode] = $language;
+ }
+
+ return $filtered_languages;
+}
+
+/**
+ * Returns a list with the locked languages.
+ *
+ * @param int $weight
+ * An integer value that is used as the start value for the weights of the
+ * locked languages.
+ *
+ * @return
+ * An array of language objects.
+ */
+function language_locked_languages($weight = 20) {
+ $locked_language = array(
+ 'default' => FALSE,
+ 'locked' => TRUE,
+ 'enabled' => TRUE,
+ );
+
+ $languages = array();
+ $languages[LANGUAGE_NOT_SPECIFIED] = new Language(array(
+ 'langcode' => LANGUAGE_NOT_SPECIFIED,
+ 'name' => t('Not specified'),
+ 'weight' => $weight++,
+ ) + $locked_language);
+ $languages[LANGUAGE_NOT_APPLICABLE] = new Language(array(
+ 'langcode' => LANGUAGE_NOT_APPLICABLE,
+ 'name' => t('Not applicable'),
+ 'weight' => $weight++,
+ ) + $locked_language);
+ $languages[LANGUAGE_MULTIPLE] = new Language(array(
+ 'langcode' => LANGUAGE_MULTIPLE,
+ 'name' => t('Multiple'),
+ 'weight' => $weight++,
+ ) + $locked_language);
return $languages;
}
@@ -2692,7 +2756,7 @@ function language_list() {
* A fully-populated language object or FALSE.
*/
function language_load($langcode) {
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ALL);
return isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
}
@@ -2720,6 +2784,16 @@ function language_name($langcode) {
}
/**
+ * Checks if a language is locked.
+ *
+ * @param $langcode
+ * The language code.
+ */
+function language_is_locked($langcode) {
+ return array_key_exists($langcode, language_locked_languages());
+}
+
+/**
* Returns the default language used on the site.
*
* @return
@@ -2731,6 +2805,7 @@ function language_default() {
'name' => 'English',
'direction' => 0,
'weight' => 0,
+ 'locked' => 0,
));
$info['default'] = TRUE;
return new Language($info);
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 65cbcf4..1dcb8e7 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -199,16 +199,54 @@ function update_prepare_d8_language() {
update_module_add_to_system($modules);
update_module_enable($modules);
- // Rename 'language' column to 'langcode'.
- db_drop_primary_key('language');
- $langcode_spec = array(
- 'type' => 'varchar',
- 'length' => 12,
- 'not null' => TRUE,
- 'default' => '',
- 'description' => "Language code, e.g. 'de' or 'en-US'.",
- );
- db_change_field('language', 'language', 'langcode', $langcode_spec, array('primary key' => array('langcode')));
+ // Rename language column to langcode and set it again as the primary key.
+ if (db_field_exists('language', 'language')) {
+ db_drop_primary_key('language');
+ $langcode_spec = array(
+ 'type' => 'varchar',
+ 'length' => 12,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => "Language code, e.g. 'de' or 'en-US'.",
+ );
+ db_change_field('language', 'language', 'langcode', $langcode_spec, array('primary key' => array('langcode')));
+ }
+
+ // Update the 'language_default' system variable, if configured.
+ $language_default = variable_get('language_default');
+ if (!empty($language_default) && isset($language_default->language)) {
+ $language_default->langcode = $language_default->language;
+ unset($language_default->language);
+ // 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
+ // array.
+ variable_set('language_default', (array) $language_default);
+ }
+
+ // Adds the locked column and saves the special languages.
+ 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);
+
+ $languages = language_locked_languages();
+ 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,
+ ))
+ ->execute();
+ }
+ }
// Update the 'language_default' system variable with the langcode change.
$language_default = variable_get('language_default');
diff --git a/core/lib/Drupal/Core/Language/Language.php b/core/lib/Drupal/Core/Language/Language.php
index 9b9223d..86bc8d3 100644
--- a/core/lib/Drupal/Core/Language/Language.php
+++ b/core/lib/Drupal/Core/Language/Language.php
@@ -21,7 +21,6 @@ class Language {
public $name = 'English';
public $langcode = 'en';
public $direction = 0;
- public $enabled = 1;
public $weight = 0;
public $default = FALSE;
public $method_id = NULL;
diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc
index 5d4ce72..aa018da 100644
--- a/core/modules/block/block.admin.inc
+++ b/core/modules/block/block.admin.inc
@@ -418,9 +418,9 @@ function block_admin_configure($form, &$form_state, $module, $delta) {
$default_language_type = $setting->type;
}
- // Fetch the enabled languages.
- $enabled_languages = language_list(TRUE);
- foreach ($enabled_languages as $language) {
+ // Fetch languages.
+ $languages = language_list(LANGUAGE_ALL);
+ foreach ($languages as $language) {
// @TODO $language->name is not wrapped with t(), it should be replaced
// by CMI translation implementation.
$langcodes_options[$language->langcode] = $language->name;
diff --git a/core/modules/entity/lib/Drupal/entity/Entity.php b/core/modules/entity/lib/Drupal/entity/Entity.php
index 3fa0ead..39de5a8 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity.php
@@ -205,14 +205,15 @@ class Entity implements EntityInterface {
protected function getFieldLangcode($field, $langcode = NULL) {
// Only apply the given langcode if the entity is language-specific.
// Otherwise translatable fields are handled as non-translatable fields.
- if (field_is_translatable($this->entityType, $field) && ($default_language = $this->language())) {
+ if (field_is_translatable($this->entityType, $field) && ($default_language = $this->language()) && !language_is_locked($this->langcode)) {
// For translatable fields the values in default language are stored using
// the language code of the default language.
return isset($langcode) ? $langcode : $default_language->langcode;
}
else {
- // Non-translatable fields always use LANGUAGE_NOT_SPECIFIED.
- return LANGUAGE_NOT_SPECIFIED;
+ // If there is a langcode defined for this field, just return it. Otherwise
+ // return LANGUAGE_NOT_SPECIFIED.
+ return (isset($this->langcode) ? $this->langcode : LANGUAGE_NOT_SPECIFIED);
}
}
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityTranslationTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityTranslationTest.php
index 5e59c45..99842e5 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityTranslationTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityTranslationTest.php
@@ -66,7 +66,7 @@ class EntityTranslationTest extends WebTestBase {
'name' => 'test',
'uid' => $GLOBALS['user']->uid,
));
- $this->assertFalse($entity->language(), 'No entity language has been specified.');
+ $this->assertEqual($entity->language()->langcode, LANGUAGE_NOT_SPECIFIED, 'Entity language not specified.');
$this->assertFalse($entity->translations(), 'No translations are available');
// Set the value in default language.
diff --git a/core/modules/field/field.multilingual.inc b/core/modules/field/field.multilingual.inc
index 0420168..3b92c99 100644
--- a/core/modules/field/field.multilingual.inc
+++ b/core/modules/field/field.multilingual.inc
@@ -165,14 +165,11 @@ function _field_language_suggestion($available_langcodes, $langcode_suggestion,
/**
* Returns available content language codes.
*
- * The language codes that may be associated to fields include
- * LANGUAGE_NOT_SPECIFIED.
- *
* @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_ALL));
}
/**
@@ -243,8 +240,8 @@ function field_has_translation_handler($entity_type, $handler = NULL) {
* A valid language code.
*/
function field_valid_language($langcode, $default = TRUE) {
- $enabled_languages = field_content_languages();
- if (in_array($langcode, $enabled_languages)) {
+ $languages = field_content_languages();
+ if (in_array($langcode, $languages)) {
return $langcode;
}
return $default ? language_default()->langcode : drupal_container()->get(LANGUAGE_TYPE_CONTENT)->langcode;
@@ -290,11 +287,25 @@ function field_language($entity_type, $entity, $field_name = NULL, $langcode = N
if (!isset($display_langcodes[$entity_type][$id][$langcode])) {
$display_langcode = array();
- // By default display language is set to LANGUAGE_NOT_SPECIFIED if the field
- // translation is not available. It is up to translation handlers to
- // implement language fallback rules.
+ // By default, display language is set to one of the locked languages
+ // if the field translation is not available. It is up to translation
+ // handlers to implement language fallback rules.
foreach (field_info_instances($entity_type, $bundle) as $instance) {
- $display_langcode[$instance['field_name']] = isset($entity->{$instance['field_name']}[$langcode]) ? $langcode : LANGUAGE_NOT_SPECIFIED;
+ if (isset($entity->{$instance['field_name']}[$langcode])) {
+ $display_langcode[$instance['field_name']] = $langcode;
+ }
+ else {
+ // If the field has a value for one of the locked languages, then use
+ // that language for display. If not, the default one will be
+ // LANGUAGE_NOT_SPECIFIED.
+ $display_langcode[$instance['field_name']] = LANGUAGE_NOT_SPECIFIED;
+ foreach (language_locked_languages() as $language_locked) {
+ if (isset($entity->{$instance['field_name']}[$language_locked->langcode])) {
+ $display_langcode[$instance['field_name']] = $language_locked->langcode;
+ break;
+ }
+ }
+ }
}
if (field_has_translation_handler($entity_type)) {
diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
index fe9e9fc..9e8c48b 100644
--- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php
@@ -69,11 +69,11 @@ class TranslationTest extends FieldTestBase {
// Test hook_field_languages() invocation on a translatable field.
variable_set('field_test_field_available_languages_alter', TRUE);
- $enabled_langcodes = field_content_languages();
+ $langcodes = field_content_languages();
$available_langcodes = field_available_languages($this->entity_type, $this->field);
foreach ($available_langcodes as $delta => $langcode) {
if ($langcode != 'xx' && $langcode != 'en') {
- $this->assertTrue(in_array($langcode, $enabled_langcodes), t('%language is an enabled language.', array('%language' => $langcode)));
+ $this->assertTrue(in_array($langcode, $langcodes), t('%language is an enabled language.', array('%language' => $langcode)));
}
}
$this->assertTrue(in_array('xx', $available_langcodes), t('%language was made available.', array('%language' => 'xx')));
@@ -263,6 +263,9 @@ class TranslationTest extends FieldTestBase {
$enabled_langcodes = field_content_languages();
$langcodes = array();
+ // This array is used to store, for each field name, which one of the locked
+ // languages will be used for display.
+ $locked_languages = array();
// Generate field translations for languages different from the first
// enabled.
@@ -277,6 +280,15 @@ class TranslationTest extends FieldTestBase {
while (isset($langcodes[$langcode]));
$langcodes[$langcode] = TRUE;
$entity->{$field_name}[$langcode] = $this->_generateTestFieldValues($field['cardinality']);
+ // If the langcode is one of the locked languages, then that one
+ // will also be used for display. Otherwise, the default one should be
+ // used, which is LANGUAGE_NOT_SPECIFIED.
+ if (language_is_locked($langcode)) {
+ $locked_languages[$field_name] = $langcode;
+ }
+ else {
+ $locked_languages[$field_name] = LANGUAGE_NOT_SPECIFIED;
+ }
}
// Test multiple-fields display languages for untranslatable entities.
@@ -286,14 +298,13 @@ class TranslationTest extends FieldTestBase {
$display_langcodes = field_language($entity_type, $entity, NULL, $requested_langcode);
foreach ($instances as $instance) {
$field_name = $instance['field_name'];
- $this->assertTrue($display_langcodes[$field_name] == LANGUAGE_NOT_SPECIFIED, t('The display language for field %field_name is %language.', array('%field_name' => $field_name, '%language' => LANGUAGE_NOT_SPECIFIED)));
+ $this->assertTrue($display_langcodes[$field_name] == $locked_languages[$field_name], t('The display language for field %field_name is %language.', array('%field_name' => $field_name, '%language' => $locked_languages[$field_name])));
}
// Test multiple-fields display languages for translatable entities.
field_test_entity_info_translatable($entity_type, TRUE);
drupal_static_reset('field_language');
$display_langcodes = field_language($entity_type, $entity, NULL, $requested_langcode);
-
foreach ($instances as $instance) {
$field_name = $instance['field_name'];
$langcode = $display_langcodes[$field_name];
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 168821e..a601d00 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -12,7 +12,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
*/
function language_admin_overview_form($form, &$form_state) {
drupal_static_reset('language_list');
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ALL);
$default = language_default();
$form['languages'] = array(
@@ -30,8 +30,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 .= '<div class="description">' . $description . '</div>';
+ }
$form['languages'][$langcode]['name'] = array(
- '#markup' => check_plain($language->name),
+ '#markup' => $title,
);
$form['languages'][$langcode]['default'] = array(
'#type' => 'radio',
@@ -50,22 +66,28 @@ function language_admin_overview_form($form, &$form_state) {
'#attributes' => array(
'class' => array('language-order-weight'),
),
+ '#delta' => 30,
);
$form['languages'][$langcode]['operations'] = array(
'#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']['#attributes']['disabled'] = 'disabled';
+ }
}
$form['actions'] = array('#type' => 'actions');
@@ -142,7 +164,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_ALL);
$old_default = language_default();
foreach ($languages as $langcode => $language) {
diff --git a/core/modules/language/language.install b/core/modules/language/language.install
index 5a962fa..1a1560b 100644
--- a/core/modules/language/language.install
+++ b/core/modules/language/language.install
@@ -12,8 +12,13 @@
* system on multilingual sites without needing any preliminary configuration.
*/
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_locked_languages();
+ foreach ($languages as $language) {
+ language_save($language);
+ }
// Enable URL language detection for each configurable language type.
require_once DRUPAL_ROOT . '/core/includes/language.inc';
@@ -82,6 +87,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(
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 2474943..46ba812 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -39,7 +39,7 @@ function language_help($path, $arg) {
case 'admin/structure/block/manage/%/%':
if ($arg[4] == 'language' && $arg[5] == 'language_interface') {
- return '<p>' . t('This block is only shown if <a href="@languages">at least two languages are enabled</a> and <a href="@configuration">language negotiation</a> is set to <em>URL</em> or <em>Session</em>.', array('@languages' => url('admin/config/regional/language'), '@configuration' => url('admin/config/regional/language/detection'))) . '</p>';
+ return '<p>' . t('With multiple languages enabled, registered users can select their preferred language and authors can assign a specific language to content.') . '</p>';
}
break;
}
@@ -77,14 +77,16 @@ 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',
);
@@ -119,6 +121,13 @@ function language_menu() {
}
/**
+ * 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() {
@@ -187,8 +196,8 @@ function language_save($language) {
variable_set('language_default', (array) $language);
}
- // Update language count based on enabled language count.
- variable_set('language_count', db_query('SELECT COUNT(langcode) FROM {language}')->fetchField());
+ // Update language count based on unlocked language count.
+ variable_set('language_count', db_query('SELECT COUNT(langcode) FROM {language} WHERE locked = 0')->fetchField());
// Kill the static cache in language_list().
drupal_static_reset('language_list');
@@ -205,8 +214,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_ALL);
+ if (isset($languages[$langcode]) && !$languages[$langcode]->locked) {
$language = $languages[$langcode];
module_invoke_all('language_delete', $language);
@@ -388,6 +397,10 @@ function language_modules_disabled($modules) {
* Implements hook_language_insert().
*/
function language_language_insert($language) {
+ if (!empty($language->locked)) {
+ return;
+ }
+
language_negotiation_include();
// Add new language to the list of language prefixes.
@@ -405,6 +418,10 @@ function language_language_insert($language) {
* Implements hook_language_update().
*/
function language_language_update($language) {
+ if (!empty($language->locked)) {
+ return;
+ }
+
language_negotiation_include();
// If the language is the default, then ensure that no other languages have
@@ -521,15 +538,16 @@ function language_url_outbound_alter(&$path, &$options, $original_path) {
$callbacks = array_keys($callbacks);
}
+ // No language dependent path allowed in this mode.
+ if (empty($callbacks)) {
+ unset($options['language']);
+ return;
+ }
+
foreach ($callbacks as $callback) {
if (function_exists($callback)) {
$callback($path, $options);
}
}
-
- // No language dependent path allowed in this mode.
- if (empty($callbacks)) {
- unset($options['language']);
- }
}
}
diff --git a/core/modules/language/language.negotiation.inc b/core/modules/language/language.negotiation.inc
index 0d6dd94..d573413 100644
--- a/core/modules/language/language.negotiation.inc
+++ b/core/modules/language/language.negotiation.inc
@@ -368,7 +368,7 @@ function language_url_rewrite_url(&$path, &$options) {
$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;
}
@@ -377,7 +377,7 @@ function language_url_rewrite_url(&$path, &$options) {
switch (variable_get('language_negotiation_url_part', LANGUAGE_NEGOTIATION_URL_PREFIX)) {
case LANGUAGE_NEGOTIATION_URL_DOMAIN:
$domains = language_negotiation_url_domains();
- if (!empty($domains[$options['language']->langcode])) {
+ if (is_object($options['language']) && !empty($domains[$options['language']->langcode])) {
// Ask for an absolute URL with our modified base_url.
global $is_https;
$url_scheme = ($is_https) ? 'https://' : 'http://';
@@ -396,7 +396,7 @@ function language_url_rewrite_url(&$path, &$options) {
case LANGUAGE_NEGOTIATION_URL_PREFIX:
$prefixes = 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;
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index 5cc25eb..1bb4547 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();
- $language_options = array(LANGUAGE_NOT_SPECIFIED => t('- None -'));
+ $languages = language_list(LANGUAGE_ALL);
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'),
@@ -476,7 +476,7 @@ function node_admin_nodes() {
$nodes = node_load_multiple($nids);
// Prepare the list of nodes.
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ALL);
$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 d4318e2..959cd9e 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2658,8 +2658,9 @@ function node_form_search_form_alter(&$form, $form_state) {
// Languages:
$language_options = array();
- foreach (language_list() as $langcode => $language) {
- $language_options[$langcode] = $language->name;
+ foreach (language_list(LANGUAGE_ALL) 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 70383b7..2e5ecee 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -187,17 +187,17 @@ function node_form($form, &$form_state, Node $node) {
$form['#node'] = $node;
if (variable_get('node_type_language_' . $node->type, 0) && module_exists('language')) {
- $languages = language_list();
+ $languages = language_list(LANGUAGE_ALL);
$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 3881320..034c7c2 100644
--- a/core/modules/openid/openid.module
+++ b/core/modules/openid/openid.module
@@ -263,11 +263,11 @@ function openid_form_user_register_form_alter(&$form, &$form_state) {
$candidate_langcodes[] = $parts[0] . '-' . $parts[2];
$candidate_langcodes[] = $parts[0] . '-' . $parts[1] . '-' . $parts[2];
}
- $enabled_languages = language_list();
+ $languages = language_list();
// Iterate over the generated permutations starting with the longest (most
// specific) strings.
foreach (array_reverse($candidate_langcodes) as $candidate_langcode) {
- if (isset($enabled_languages[$candidate_langcode])) {
+ if (isset($languages[$candidate_langcode])) {
$form['language']['preferred_langcode']['#type'] = 'hidden';
$form['language']['preferred_langcode']['#value'] = $candidate_langcode;
// Skip the rest of the foreach to not overwrite the specific
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php
index 0770fa6..f117729 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php
@@ -28,10 +28,6 @@ class SearchLanguageTest extends SearchTestBase {
}
function testLanguages() {
- // Check that there are initially no languages displayed.
- $this->drupalGet('search/node');
- $this->assertNoText(t('Languages'), t('No languages to choose from.'));
-
// Add predefined language.
$edit = array('predefined_langcode' => 'fr');
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
@@ -60,9 +56,5 @@ class SearchLanguageTest extends SearchTestBase {
$this->drupalPost(NULL, $edit, t('Save configuration'));
$this->assertNoFieldChecked('edit-site-default-en', t('Default language updated.'));
$this->drupalPost('admin/config/regional/language/delete/en', array(), t('Delete'));
-
- // Check that there are again no languages displayed.
- $this->drupalGet('search/node');
- $this->assertNoText(t('Languages'), t('No languages to choose from.'));
}
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
index 81e9676..39e6982 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
@@ -40,7 +40,7 @@ class LanguageUpgradePathTest extends UpgradePathTestBase {
// 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_ALL);
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/translation/translation.module b/core/modules/translation/translation.module
index b2c0635..0298097 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -197,7 +197,7 @@ function translation_node_view(Node $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();
+ $languages = language_list(LANGUAGE_ALL);
// There might be a language provider enabled defining custom language
// switch links which need to be taken into account while generating the
@@ -212,7 +212,6 @@ function translation_node_view(Node $node, $view_mode) {
foreach ($translations as $langcode => $translation) {
// Do not show links to the same node or to unpublished translations.
if ($translation->status && isset($languages[$langcode]) && $langcode != $node->langcode) {
- $language = $languages[$langcode];
$key = "translation_$langcode";
if (isset($custom_links->links[$langcode])) {
@@ -221,8 +220,8 @@ function translation_node_view(Node $node, $view_mode) {
else {
$links[$key] = array(
'href' => "node/{$translation->nid}",
- 'title' => $language->name,
- 'language' => $language,
+ 'title' => language_name($langcode),
+ 'language' => $languages[$langcode],
);
}