summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel2011-10-27 03:55:02 (GMT)
committerNathaniel2011-10-27 03:55:02 (GMT)
commita7c925997914768932efe77b82f0a0beca4c7d4c (patch)
treeac2dc263dd9bb856071f557dd6623994682ebfbe
parentd0fb1ad515d93a96473777e4802055ea67e0bf74 (diff)
Issue #1266318 by Gábor Hojtsy, alberto56, David Lesieur: Make English a first class language.
-rw-r--r--includes/bootstrap.inc17
-rw-r--r--includes/common.inc2
-rw-r--r--includes/locale.inc4
-rw-r--r--modules/locale/locale.admin.inc7
-rw-r--r--modules/locale/locale.bulk.inc12
-rw-r--r--modules/locale/locale.install17
-rw-r--r--modules/locale/locale.module32
-rw-r--r--modules/locale/locale.pages.inc20
-rw-r--r--modules/locale/locale.test64
9 files changed, 127 insertions, 48 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 8b377de..29e5c3a 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -159,6 +159,13 @@ define('DRUPAL_AUTHENTICATED_RID', 2);
define('DRUPAL_KILOBYTE', 1024);
/**
+ * System language (only applicable to UI).
+ *
+ * Refers to the language used in Drupal and module/theme source code.
+ */
+define('LANGUAGE_SYSTEM', 'system');
+
+/**
* The language code used when no language is explicitly assigned.
*
* Defined by ISO639-2 for "Undetermined".
@@ -1476,7 +1483,7 @@ function t($string, array $args = array(), array $options = array()) {
// Merge in default.
if (empty($options['langcode'])) {
- $options['langcode'] = isset($language->language) ? $language->language : 'en';
+ $options['langcode'] = isset($language->language) ? $language->language : LANGUAGE_SYSTEM;
}
if (empty($options['context'])) {
$options['context'] = '';
@@ -1494,7 +1501,7 @@ function t($string, array $args = array(), array $options = array()) {
$string = $custom_strings[$options['langcode']][$options['context']][$string];
}
// Translate with locale module if enabled.
- elseif ($options['langcode'] != 'en' && function_exists('locale')) {
+ elseif ($options['langcode'] != LANGUAGE_SYSTEM && ($options['langcode'] != 'en' || variable_get('locale_translate_english', FALSE)) && function_exists('locale')) {
$string = locale($string, $options['context'], $options['langcode']);
}
if (empty($args)) {
@@ -2632,12 +2639,6 @@ function language_list($field = 'language') {
$default = language_default();
if (drupal_multilingual() || module_exists('locale')) {
$languages['language'] = db_query('SELECT * FROM {languages} ORDER BY weight ASC, name ASC')->fetchAllAssoc('language');
- // Users cannot uninstall the native English language. However, we allow
- // it to be hidden from the installed languages. Therefore, at least one
- // other language must be enabled then.
- if (!$languages['language']['en']->enabled && !variable_get('language_native_enabled', TRUE)) {
- unset($languages['language']['en']);
- }
}
else {
// No locale module, so use the default language only.
diff --git a/includes/common.inc b/includes/common.inc
index 5f7cdb8..c851715 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -1875,7 +1875,7 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
// Use the default langcode if none is set.
global $language;
if (empty($langcode)) {
- $langcode = isset($language->language) ? $language->language : 'en';
+ $langcode = isset($language->language) ? $language->language : LANGUAGE_SYSTEM;
}
switch ($type) {
diff --git a/includes/locale.inc b/includes/locale.inc
index 5a0138c..01c35fa 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -703,7 +703,9 @@ function _locale_invalidate_js($langcode = NULL) {
if (empty($langcode)) {
// Invalidate all languages.
$languages = language_list();
- unset($languages['en']);
+ if (!locale_translate_english()) {
+ unset($languages['en']);
+ }
foreach ($languages as $lcode => $data) {
$parsed['refresh:' . $lcode] = 'waiting';
}
diff --git a/modules/locale/locale.admin.inc b/modules/locale/locale.admin.inc
index 42c54e0..6abe48b 100644
--- a/modules/locale/locale.admin.inc
+++ b/modules/locale/locale.admin.inc
@@ -79,7 +79,7 @@ function locale_language_overview_form($form, &$form_state) {
'#type' => 'link',
'#title' => t('delete'),
'#href' => 'admin/config/regional/language/delete/' . $langcode,
- '#access' => $langcode != 'en' && $langcode != $default->language,
+ '#access' => $langcode != $default->language,
);
}
@@ -416,11 +416,6 @@ function locale_languages_edit_form_submit($form, &$form_state) {
*/
function locale_languages_delete_form($form, &$form_state, $language) {
$langcode = $language->language;
- // Do not allow deletion of English locale.
- if ($langcode == 'en') {
- drupal_set_message(t('The English language cannot be deleted.'));
- drupal_goto('admin/config/regional/language');
- }
if (language_default()->language == $langcode) {
drupal_set_message(t('The default language cannot be deleted.'));
diff --git a/modules/locale/locale.bulk.inc b/modules/locale/locale.bulk.inc
index 51f80a6..ce10f05 100644
--- a/modules/locale/locale.bulk.inc
+++ b/modules/locale/locale.bulk.inc
@@ -14,7 +14,9 @@ function locale_translate_import_form($form) {
// Get all languages, except English
drupal_static_reset('language_list');
$names = locale_language_list('name');
- unset($names['en']);
+ if (!locale_translate_english()) {
+ unset($names['en']);
+ }
if (!count($names)) {
$languages = _locale_prepare_predefined_list();
@@ -101,7 +103,9 @@ function locale_translate_export_screen() {
// Get all languages, except English
drupal_static_reset('language_list');
$names = locale_language_list('name');
- unset($names['en']);
+ if (!locale_translate_english()) {
+ unset($names['en']);
+ }
$output = '';
// Offer translation export if any language is set up.
if (count($names)) {
@@ -215,7 +219,9 @@ function locale_batch_by_language($langcode, $finished = NULL, $skip = array())
function locale_batch_by_component($components, $finished = '_locale_batch_system_finished') {
$files = array();
$languages = language_list('enabled');
- unset($languages[1]['en']);
+ if (!locale_translate_english()) {
+ unset($languages[1]['en']);
+ }
if (count($languages[1])) {
$language_list = join('|', array_keys($languages[1]));
// Collect all files to import for all $components.
diff --git a/modules/locale/locale.install b/modules/locale/locale.install
index edd22c3..6cca4c4 100644
--- a/modules/locale/locale.install
+++ b/modules/locale/locale.install
@@ -9,20 +9,9 @@
* Implements hook_install().
*/
function locale_install() {
- // locales_source.source and locales_target.target are not used as binary
- // fields; non-MySQL database servers need to ensure the field type is text
- // and that LIKE produces a case-sensitive comparison.
-
- db_insert('languages')
- ->fields(array(
- 'language' => 'en',
- 'name' => 'English',
- 'direction' => 0,
- 'enabled' => 1,
- 'weight' => 0,
- 'javascript' => '',
- ))
- ->execute();
+ // Add the default language to the database too.
+ include_once DRUPAL_ROOT . '/includes/locale.inc';
+ locale_language_save(language_default());
}
/**
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 03757ac..9eab429 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -1100,7 +1100,7 @@ function locale_form_locale_language_overview_form_alter(&$form, &$form_state) {
'translated' => 0,
'ratio' => 0,
);
- if ($langcode != 'en') {
+ if ($langcode != 'en' || locale_translate_english()) {
$form['languages'][$langcode]['locale_statistics'] = array(
'#type' => 'link',
'#title' => t('@translated/@total (@ratio%)', array(
@@ -1113,8 +1113,36 @@ function locale_form_locale_language_overview_form_alter(&$form, &$form_state) {
}
else {
$form['languages'][$langcode]['locale_statistics'] = array(
- '#markup' => t('built-in'),
+ '#markup' => t('not applicable'),
);
}
}
}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for locale_languages_edit_form().
+ */
+function locale_form_locale_languages_edit_form_alter(&$form, &$form_state) {
+ if ($form['langcode']['#type'] == 'value' && $form['langcode']['#value'] == 'en') {
+ $form['locale_translate_english'] = array(
+ '#title' => t('Enable interface translation to English'),
+ '#type' => 'checkbox',
+ '#default_value' => locale_translate_english(),
+ );
+ $form['#submit'][] = 'locale_form_locale_languages_edit_form_alter_submit';
+ }
+}
+
+/**
+ * Submission handler to record our custom setting.
+ */
+function locale_form_locale_languages_edit_form_alter_submit($form, $form_state) {
+ variable_set('locale_translate_english', $form_state['values']['locale_translate_english']);
+}
+
+/**
+ * Utility function to tell if locale translates to English.
+ */
+function locale_translate_english() {
+ return variable_get('locale_translate_english', FALSE);
+}
diff --git a/modules/locale/locale.pages.inc b/modules/locale/locale.pages.inc
index 09cc184..ef843ec 100644
--- a/modules/locale/locale.pages.inc
+++ b/modules/locale/locale.pages.inc
@@ -55,8 +55,8 @@ function _locale_translate_seek() {
default:
$condition = db_or()
->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE');
- if ($query['language'] != 'en') {
- // Only search in translations if the language is not forced to English.
+ if ($query['language'] != LANGUAGE_SYSTEM) {
+ // Only search in translations if the language is not forced to system language.
$condition->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
}
$sql_query->condition($condition);
@@ -64,7 +64,7 @@ function _locale_translate_seek() {
}
$limit_language = NULL;
- if ($query['language'] != 'en' && $query['language'] != 'all') {
+ if ($query['language'] != LANGUAGE_SYSTEM && $query['language'] != 'all') {
$sql_query->condition('language', $query['language']);
$limit_language = $query['language'];
}
@@ -114,7 +114,9 @@ function _locale_translate_language_list($translation, $limit_language) {
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
$languages = language_list();
- unset($languages['en']);
+ if (!locale_translate_english()) {
+ unset($languages['en']);
+ }
$output = '';
foreach ($languages as $langcode => $language) {
if (!$limit_language || $limit_language == $langcode) {
@@ -151,7 +153,9 @@ function locale_translation_filters() {
// Get all languages, except English
drupal_static_reset('language_list');
$languages = locale_language_list('name');
- unset($languages['en']);
+ if (!locale_translate_english()) {
+ unset($languages['en']);
+ }
$filters['string'] = array(
'title' => t('String contains'),
@@ -160,7 +164,7 @@ function locale_translation_filters() {
$filters['language'] = array(
'title' => t('Language'),
- 'options' => array_merge(array('all' => t('All languages'), 'en' => t('English (provided by Drupal)')), $languages),
+ 'options' => array_merge(array('all' => t('All languages'), LANGUAGE_SYSTEM => t('System (English)')), $languages),
);
$filters['translation'] = array(
@@ -297,7 +301,9 @@ 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();
- unset($languages['en']);
+ if (!locale_translate_english()) {
+ unset($languages['en']);
+ }
$form['translations'] = array('#tree' => TRUE);
// Approximate the number of rows to use in the default textarea.
$rows = min(ceil(str_word_count($source->source) / 12), 10);
diff --git a/modules/locale/locale.test b/modules/locale/locale.test
index 4af9c54..fa19eb3 100644
--- a/modules/locale/locale.test
+++ b/modules/locale/locale.test
@@ -163,11 +163,36 @@ class LocaleConfigurationTest extends DrupalWebTestCase {
// Make sure the "language_count" variable has not changed.
$this->assertEqual(variable_get('language_count', 1), count($enabled[1]), t('Language count is correct.'));
+ // Ensure we can delete the English language. Right now English is the only
+ // language so we must add a new language and make it the default before
+ // deleting English.
+ $langcode = 'xx';
+ $name = $this->randomName(16);
+ $edit = array(
+ 'predefined_langcode' => 'custom',
+ 'langcode' => $langcode,
+ 'name' => $name,
+ 'direction' => '0',
+ );
+ $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
+ $this->assertEqual($this->getUrl(), url('admin/config/regional/language', array('absolute' => TRUE)), t('Correct page redirection.'));
+ $this->assertText($name, t('Name found.'));
- // Ensure we can't delete the English language.
- $this->drupalGet('admin/config/regional/language/delete/en');
+ // Check if we can change the default language.
+ $path = 'admin/config/regional/language';
+ $this->drupalGet($path);
+ $this->assertFieldChecked('edit-site-default-en', t('English is the default language.'));
+ // Change the default language.
+ $edit = array(
+ 'site_default' => $langcode,
+ );
+ $this->drupalPost(NULL, $edit, t('Save configuration'));
+ $this->assertNoFieldChecked('edit-site-default-en', t('Default language updated.'));
$this->assertEqual($this->getUrl(), url('admin/config/regional/language', array('absolute' => TRUE)), t('Correct page redirection.'));
- $this->assertText(t('The English language cannot be deleted.'), t('Failed to delete English language.'));
+
+ $this->drupalPost('admin/config/regional/language/delete/en', array(), t('Delete'));
+ // We need raw here because %locale will add HTML.
+ $this->assertRaw(t('The language %locale has been removed.', array('%locale' => 'English')), t('The English language has been removed.'));
}
}
@@ -296,6 +321,7 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
$language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
// This will be the translation of $name.
$translation = $this->randomName(16);
+ $translation_to_en = $this->randomName(16);
// Add custom language.
$this->drupalLogin($admin_user);
@@ -335,13 +361,39 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
$lid = $matches[1];
// No t() here, it's surely not translated yet.
$this->assertText($name, t('name found on edit screen.'));
+ $this->assertNoText('English', t('No way to translate the string to English.'));
+ $this->drupalLogout();
+ $this->drupalLogin($admin_user);
+ $this->drupalPost('admin/config/regional/language/edit/en', array('locale_translate_english' => TRUE), t('Save language'));
+ $this->drupalLogout();
+ $this->drupalLogin($translate_user);
+ $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
+ // assertText() seems to remove the input field where $name always could be
+ // found, so this is not a false assert. See how assertNoText succeeds
+ // later.
+ $this->assertText($name, t('Search found the name.'));
+ $this->assertRaw($language_indicator, t('Name is untranslated.'));
+ // Assume this is the only result, given the random name.
+ $this->clickLink(t('edit'));
+ $string_edit_url = $this->getUrl();
$edit = array(
"translations[$langcode]" => $translation,
+ 'translations[en]' => $translation_to_en,
);
$this->drupalPost(NULL, $edit, t('Save translations'));
$this->assertText(t('The string has been saved.'), t('The string has been saved.'));
$this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), t('Correct page redirection.'));
- $this->assertTrue($name != $translation && t($name, array(), array('langcode' => $langcode)) == $translation, t('t() works.'));
+ $this->drupalGet($string_edit_url);
+ $this->assertRaw($translation, t('Non-English translation properly saved.'));
+ $this->assertRaw($translation_to_en, t('English translation properly saved.'));
+ $this->assertTrue($name != $translation && t($name, array(), array('langcode' => $langcode)) == $translation, t('t() works for non-English.'));
+ // Refresh the locale() cache to get fresh data from t() below. We are in
+ // the same HTTP request and therefore t() is not refreshed by saving the
+ // translation above.
+ locale_reset();
+ // Now we should get the proper fresh translation from t().
+ $this->assertTrue($name != $translation_to_en && t($name, array(), array('langcode' => 'en')) == $translation_to_en, t('t() works for English.'));
+ $this->assertTrue(t($name, array(), array('langcode' => LANGUAGE_SYSTEM)) == $name, t('t() works for LANGUAGE_SYSTEM.'));
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
// The indicator should not be here.
$this->assertNoRaw($language_indicator, t('String is translated.'));
@@ -627,10 +679,10 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), t('Search found the translation.'));
- // Ensure translated string doesn't appear if searching on English.
+ // Ensure translated string doesn't appear if searching in System (English).
$search = array(
'string' => $translation,
- 'language' => 'en',
+ 'language' => LANGUAGE_SYSTEM,
'translation' => 'all',
);
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));