diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 6954c4d..7be3266 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'; diff --git a/core/includes/locale.inc b/core/includes/locale.inc index 1f9567b..73a9d96 100644 --- a/core/includes/locale.inc +++ b/core/includes/locale.inc @@ -359,6 +359,9 @@ function locale_language_switcher_url($type, $path) { $links = array(); foreach ($languages as $language) { + if (!empty($language->locked)) { + continue; + } $links[$language->langcode] = array( 'href' => $path, 'title' => $language->name, diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc index 33bc147..4e4e306 100644 --- a/core/modules/language/language.admin.inc +++ b/core/modules/language/language.admin.inc @@ -61,17 +61,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'); diff --git a/core/modules/language/language.install b/core/modules/language/language.install index ecf637d..7a31b82 100644 --- a/core/modules/language/language.install +++ b/core/modules/language/language.install @@ -9,8 +9,57 @@ * 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); + } +} + +/* + * @see http://drupal.org/node/1471432 + */ +function language_special_languages() { + $locked_language = array( + 'default' => FALSE, + 'locked' => TRUE, + 'enabled' => TRUE, + ); + $languages = language_list(); + + // 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_SYSTEM] = (object) (array( + 'langcode' => LANGUAGE_SYSTEM, + 'name' => t('System (English)'), + 'weight' => ++$max_weight, + ) + $locked_language); + $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); + $languages[LANGUAGE_ALL] = (object) (array( + 'langcode' => LANGUAGE_ALL, + 'name' => t('All languages'), + 'weight' => ++$max_weight, + ) + $locked_language); + return $languages; } /** @@ -65,6 +114,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 +157,23 @@ 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); + } + $languages = language_special_languages(); + foreach ($languages as $language) { + language_save($language); + } +} diff --git a/core/modules/locale/locale.admin.inc b/core/modules/locale/locale.admin.inc index 321b8ce..d94fb0e 100644 --- a/core/modules/locale/locale.admin.inc +++ b/core/modules/locale/locale.admin.inc @@ -259,6 +259,9 @@ function language_negotiation_configure_url_form($form, &$form_state) { $prefixes = locale_language_negotiation_url_prefixes(); $domains = locale_language_negotiation_url_domains(); foreach ($languages as $langcode => $language) { + if (!empty($language->locked)) { + continue; + } $form['prefix'][$langcode] = array( '#type' => 'textfield', '#title' => t('%language (%langcode) path prefix', array('%language' => $language->name, '%langcode' => $language->langcode)), @@ -298,6 +301,9 @@ function language_negotiation_configure_url_form_validate($form, &$form_state) { // Count repeated values for uniqueness check. $count = array_count_values($form_state['values']['prefix']); foreach ($languages as $langcode => $language) { + if (!empty($language->locked)) { + continue; + } $value = $form_state['values']['prefix'][$langcode]; if ($value === '') { @@ -315,6 +321,9 @@ function language_negotiation_configure_url_form_validate($form, &$form_state) { // Count repeated values for uniqueness check. $count = array_count_values($form_state['values']['domain']); foreach ($languages as $langcode => $language) { + if (!empty($language->locked)) { + continue; + } $value = $form_state['values']['domain'][$langcode]; if ($value === '') { @@ -330,14 +339,17 @@ 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) { + if (!empty($language->locked)) { + continue; + } $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))); } } } diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc index a4982e1..8253181 100644 --- a/core/modules/locale/locale.bulk.inc +++ b/core/modules/locale/locale.bulk.inc @@ -18,7 +18,7 @@ function locale_translate_import_form($form, &$form_state) { // are to translate Drupal to English as well. $existing_languages = array(); foreach ($languages as $langcode => $language) { - if ($langcode != 'en' || locale_translate_english()) { + if (empty($language->locked) && ($langcode != 'en' || locale_translate_english())) { $existing_languages[$langcode] = $language->name; } } @@ -114,7 +114,7 @@ function locale_translate_export_screen() { $languages = language_list(TRUE); $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; } } diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 6d3ded0..efa28fd 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -227,8 +227,10 @@ function locale_language_selector_form($user) { $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) { + if (empty($language->locked)) { + $names[$langcode] = $language->name; + } } // Get language negotiation settings. $mode = language_negotiation_method_get_first(LANGUAGE_TYPE_INTERFACE) != LANGUAGE_NEGOTIATION_DEFAULT; @@ -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}"; @@ -1019,7 +1020,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 +1031,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 0d59f42..3c9989c 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']; } @@ -119,7 +119,7 @@ function _locale_translate_language_list($translation, $limit_language) { } $output = ''; foreach ($languages as $langcode => $language) { - if (!$limit_language || $limit_language == $langcode) { + if (empty($language->locked) && (!$limit_language || $limit_language == $langcode)) { $output .= (!empty($translation[$langcode])) ? $langcode . ' ' : "$langcode "; } } @@ -155,7 +155,7 @@ function locale_translation_filters() { $languages = language_list(TRUE); $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; } } @@ -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( @@ -331,6 +331,12 @@ function locale_translate_edit_form($form, &$form_state, $lid) { if (!locale_translate_english()) { unset($languages['en']); } + foreach ($languages as $langcode => $language) { + if (!empty($language->locked)) { + unset($languages[$langcode]); + } + } + // 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/node/node.pages.inc b/core/modules/node/node.pages.inc index 4e94b26..df59ed2 100644 --- a/core/modules/node/node.pages.inc +++ b/core/modules/node/node.pages.inc @@ -184,9 +184,8 @@ function node_form($form, &$form_state, $node) { $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/simpletest/tests/common.test b/core/modules/simpletest/tests/common.test index 4f20361..2500eaa 100644 --- a/core/modules/simpletest/tests/common.test +++ b/core/modules/simpletest/tests/common.test @@ -1047,6 +1047,8 @@ class CommonDrupalHTTPRequestTestCase extends DrupalWebTestCase { $request = drupal_http_request(url('', array('absolute' => TRUE))); $this->assertEqual($request->headers['content-language'], 'en', t('Content-Language HTTP header is English.')); +// drupal_static_reset('locale_language_url_rewrite_url'); + // Add French language. $language = (object) array( 'langcode' => 'fr', @@ -1054,8 +1056,13 @@ class CommonDrupalHTTPRequestTestCase extends DrupalWebTestCase { ); language_save($language); + + // Request front page in French and check for matching Content-language. $request = drupal_http_request(url('', array('absolute' => TRUE, 'language' => $language))); +// debug($language); +// debug(language_list()); +// debug(url('', array('absolute' => TRUE, 'language' => $language))); $this->assertEqual($request->headers['content-language'], 'fr', t('Content-Language HTTP header is French.')); } }