From 9c668d1fc0af107e798696533baff0d2a7c82dbe Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Wed, 28 Sep 2011 19:47:48 +0900
Subject: [PATCH] =?UTF-8?q?Issue=20#1215716=20by=20G=C3=A1bor=20Hojtsy,=20?=
 =?UTF-8?q?svendecabooter:=20Introduce=20locale=5Flanguage=5Fsave().?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 includes/bootstrap.inc               |   8 ++-
 includes/install.core.inc            |  14 +++-
 includes/locale.inc                  | 101 +++++++++++----------------
 modules/field/field.multilingual.inc |  14 ++++
 modules/field/tests/field.test       |   7 +-
 modules/locale/locale.admin.inc      |  87 ++++++++---------------
 modules/locale/locale.api.php        |  33 +++++++++
 modules/locale/locale.bulk.inc       |   5 +-
 modules/locale/locale.test           |  84 +++++++++++++---------
 modules/system/system.test           |   6 +-
 10 files changed, 205 insertions(+), 154 deletions(-)

diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index edeb2fa1ff2a..8e9991214685 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -2579,6 +2579,7 @@ function language_list($field = 'language') {
   $languages = &drupal_static(__FUNCTION__);
   // Init language list
   if (!isset($languages)) {
+    $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
@@ -2590,9 +2591,14 @@ function language_list($field = 'language') {
     }
     else {
       // No locale module, so use the default language only.
-      $default = language_default();
       $languages['language'][$default->language] = $default;
     }
+
+    // Initialize default property so callers have an easy reference and
+    // can save the same object without data loss.
+    foreach ($languages['language'] as $langcode => $language) {
+      $languages['language'][$langcode]->default = ($langcode == $default->language);
+    }
   }
 
   // Return the array indexed by the right field
diff --git a/includes/install.core.inc b/includes/install.core.inc
index 3791d71b56ce..608ed5608eb2 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -1382,11 +1382,21 @@ function install_import_locales(&$install_state) {
   if (!isset($predefined[$install_locale])) {
     // Drupal does not know about this language, so we prefill its values with
     // our best guess. The user will be able to edit afterwards.
-    locale_add_language($install_locale, $install_locale, $install_locale, LANGUAGE_LTR, '', '', TRUE, TRUE);
+    $language = (object) array(
+      'language' => $install_locale,
+      'name' => $install_locale,
+      'native' => $install_locale,
+      'default' => TRUE,
+    );
+    locale_language_save($language);
   }
   else {
     // A known predefined language, details will be filled in properly.
-    locale_add_language($install_locale, NULL, NULL, NULL, '', '', TRUE, TRUE);
+    $language = (object) array(
+      'language' => $install_locale,
+      'default' => TRUE,
+    );
+    locale_language_save($language);
   }
 
   // Collect files to import for this language.
diff --git a/includes/locale.inc b/includes/locale.inc
index 199edd1918e0..2da67c888564 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -429,85 +429,66 @@ function locale_string_is_safe($string) {
 }
 
 /**
- * @defgroup locale-api-add Language addition API
- * @{
- * Add a language.
+ * API function to add or update a language.
  *
- * The language addition API is used to create languages and store them.
+ * @param $language
+ *   Language object with properties corresponding to 'languages' table columns.
  */
-
-/**
- * API function to add a language.
- *
- * @param $langcode
- *   Language code.
- * @param $name
- *   English name of the language
- * @param $native
- *   Native name of the language
- * @param $direction
- *   LANGUAGE_LTR or LANGUAGE_RTL
- * @param $domain
- *   Optional custom domain name with protocol, without
- *   trailing slash (eg. http://de.example.com).
- * @param $prefix
- *   Optional path prefix for the language. Defaults to the
- *   language code if omitted.
- * @param $enabled
- *   Optionally TRUE to enable the language when created or FALSE to disable.
- * @param $default
- *   Optionally set this language to be the default.
- */
-function locale_add_language($langcode, $name = NULL, $native = NULL, $direction = LANGUAGE_LTR, $domain = '', $prefix = '', $enabled = TRUE, $default = FALSE) {
-  // Default prefix on language code.
-  if (empty($prefix)) {
-    $prefix = $langcode;
+function locale_language_save($language) {
+  $language->is_new = !(bool) db_query_range('SELECT 1 FROM {languages} WHERE language = :language', 0, 1, array(':language' => $language->language))->fetchField();
+  // Default prefix on language code if not provided otherwise.
+  if (!isset($language->prefix)) {
+    $language->prefix = $language->language;
   }
 
   // If name was not set, we add a predefined language.
-  if (!isset($name)) {
+  if (!isset($language->name)) {
     include_once DRUPAL_ROOT . '/includes/standard.inc';
     $predefined = standard_language_list();
-    $name = $predefined[$langcode][0];
-    $native = isset($predefined[$langcode][1]) ? $predefined[$langcode][1] : $predefined[$langcode][0];
-    $direction = isset($predefined[$langcode][2]) ? $predefined[$langcode][2] : LANGUAGE_LTR;
+    $language->name = $predefined[$language->language][0];
+    $language->native = isset($predefined[$language->language][1]) ? $predefined[$language->language][1] : $predefined[$language->language][0];
+    $language->direction = isset($predefined[$language->language][2]) ? $predefined[$language->language][2] : LANGUAGE_LTR;
   }
 
-  db_insert('languages')
-    ->fields(array(
-      'language' => $langcode,
-      'name' => $name,
-      'native' => $native,
-      'direction' => $direction,
-      'domain' => $domain,
-      'prefix' => $prefix,
-      'enabled' => $enabled,
-    ))
-    ->execute();
+  // Set to enabled for the default language and unless specified otherwise.
+  if (!empty($language->default) || !isset($language->enabled)) {
+    $language->enabled = TRUE;
+  }
+  // Let other modules modify $language before saved.
+  module_invoke_all('locale_language_presave', $language);
 
-  // Only set it as default if enabled.
-  if ($enabled && $default) {
-    variable_set('language_default', (object) array('language' => $langcode, 'name' => $name, 'native' => $native, 'direction' => $direction, 'enabled' => (int) $enabled, 'plurals' => 0, 'formula' => '', 'domain' => '', 'prefix' => $prefix, 'weight' => 0, 'javascript' => ''));
+  // Save the record and inform others about the change.
+  if ($language->is_new) {
+    drupal_write_record('languages', $language);
+    module_invoke_all('locale_language_insert', $language);
+    watchdog('locale', 'The %language (%langcode) language has been created.', array('%language' => $language->name, '%langcode' => $language->language));
+  }
+  else {
+    drupal_write_record('languages', $language, array('language'));
+    module_invoke_all('locale_language_update', $language);
+    watchdog('locale', 'The %language (%langcode) language has been updated.', array('%language' => $language->name, '%langcode' => $language->language));
   }
 
-  if ($enabled) {
-    // Increment enabled language count if we are adding an enabled language.
-    variable_set('language_count', variable_get('language_count', 1) + 1);
+  if (!empty($language->default)) {
+    // Set the new version of this language as default in a variable.
+    $default_language = language_default();
+    variable_set('language_default', $language);
   }
 
+  // Update language count based on enabled language count.
+  variable_set('language_count', db_query('SELECT COUNT(language) FROM {languages} WHERE enabled = 1')->fetchField());
+
   // Kill the static cache in language_list().
   drupal_static_reset('language_list');
 
-  // Force JavaScript translation file creation for the newly added language.
-  _locale_invalidate_js($langcode);
+  // @todo move these two cache clears out. See http://drupal.org/node/1293252
+  // Changing the language settings impacts the interface.
+  cache_clear_all('*', 'cache_page', TRUE);
+  // Force JavaScript translation file re-creation for the modified language.
+  _locale_invalidate_js($language->language);
 
-  watchdog('locale', 'The %language language (%code) has been created.', array('%language' => $name, '%code' => $langcode));
-
-  module_invoke_all('multilingual_settings_changed');
+  return $language;
 }
-/**
- * @} End of "locale-api-add"
- */
 
 /**
  * Parses a JavaScript file, extracts strings wrapped in Drupal.t() and
diff --git a/modules/field/field.multilingual.inc b/modules/field/field.multilingual.inc
index d9227455cca5..44970741e985 100644
--- a/modules/field/field.multilingual.inc
+++ b/modules/field/field.multilingual.inc
@@ -59,6 +59,20 @@
  *   field is returned by field_language().
  */
 
+/**
+ * Implements hook_locale_language_insert().
+ */
+function field_locale_language_insert() {
+  field_info_cache_clear();
+}
+
+/**
+ * Implements hook_locale_language_update().
+ */
+function field_locale_language_update() {
+  field_info_cache_clear();
+}
+
 /**
  * Implements hook_locale_language_delete().
  */
diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test
index b361637146e9..99eeb8a0abb7 100644
--- a/modules/field/tests/field.test
+++ b/modules/field/tests/field.test
@@ -2644,7 +2644,12 @@ class FieldTranslationsTestCase extends FieldTestCase {
 
     require_once DRUPAL_ROOT . '/includes/locale.inc';
     for ($i = 0; $i < 3; ++$i) {
-      locale_add_language('l' . $i, $this->randomString(), $this->randomString());
+      $language = (object) array(
+        'language' => 'l' . $i,
+        'name' => $this->randomString(),
+        'native' => $this->randomString(),
+      );
+      locale_language_save($language);
     }
   }
 
diff --git a/modules/locale/locale.admin.inc b/modules/locale/locale.admin.inc
index cd2edf5bd1a5..f2da1e5c18b5 100644
--- a/modules/locale/locale.admin.inc
+++ b/modules/locale/locale.admin.inc
@@ -119,60 +119,35 @@ function theme_locale_languages_overview_form($variables) {
  */
 function locale_languages_overview_form_submit($form, &$form_state) {
   $languages = language_list();
-  $default = language_default();
+  $old_default = language_default();
   $url_prefixes = variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX) == LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX;
-  $enabled_count = 0;
 
   foreach ($languages as $langcode => $language) {
-    if ($form_state['values']['site_default'] == $langcode || $default->language == $langcode) {
+    $language->default = ($form_state['values']['site_default'] == $langcode);
+    $language->weight = $form_state['values']['weight'][$langcode];
+
+    if ($language->default || $old_default->language == $langcode) {
       // Automatically enable the default language and the language
       // which was default previously (because we will not get the
       // value from that disabled checkbox).
       $form_state['values']['enabled'][$langcode] = 1;
     }
+    $language->enabled = (int) !empty($form_state['values']['enabled'][$langcode]);
 
     // If language URL prefixes are enabled we must clear language domains and
     // assign a valid prefix to each non-default language.
     if ($url_prefixes) {
       $language->domain = '';
-      if (empty($language->prefix) && $form_state['values']['site_default'] != $langcode) {
+      if (empty($language->prefix) && !$language->default) {
         $language->prefix = $langcode;
       }
     }
 
-    if ($form_state['values']['enabled'][$langcode]) {
-      $enabled_count++;
-      $language->enabled = 1;
-    }
-    else {
-      $language->enabled = 0;
-    }
-
-    $language->weight = $form_state['values']['weight'][$langcode];
-
-    db_update('languages')
-      ->fields(array(
-        'enabled' => $language->enabled,
-        'weight' => $language->weight,
-        'prefix' => $language->prefix,
-        'domain' => $language->domain,
-      ))
-      ->condition('language', $langcode)
-      ->execute();
-
-    $languages[$langcode] = $language;
+    locale_language_save($language);
   }
 
-  variable_set('language_default', $languages[$form_state['values']['site_default']]);
-  variable_set('language_count', $enabled_count);
   drupal_set_message(t('Configuration saved.'));
-
-  // Changing the language settings impacts the interface.
-  cache('page')->flush();
-  module_invoke_all('multilingual_settings_changed');
-
   $form_state['redirect'] = 'admin/config/regional/language';
-  return;
 }
 
 /**
@@ -350,14 +325,25 @@ function locale_languages_predefined_form_submit($form, &$form_state) {
   $langcode = $form_state['values']['langcode'];
   if (isset($form_state['values']['name'])) {
     // Custom language form.
-    locale_add_language($langcode, $form_state['values']['name'], $form_state['values']['native'], $form_state['values']['direction'], $form_state['values']['domain'], $form_state['values']['prefix']);
+    $language = (object) array(
+      'language' => $langcode,
+      'name' => $form_state['values']['name'],
+      'native' => $form_state['values']['native'],
+      'direction' => $form_state['values']['direction'],
+      'domain' => $form_state['values']['domain'],
+      'prefix' => $form_state['values']['prefix'],
+    );
+    locale_language_save($language);
     drupal_set_message(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => t($form_state['values']['name']), '@locale-help' => url('admin/help/locale'))));
   }
   else {
     // Predefined language selection.
     include_once DRUPAL_ROOT . '/includes/standard.inc';
     $predefined = standard_language_list();
-    locale_add_language($langcode);
+    $language = (object) array(
+      'language' => $langcode,
+    );
+    locale_language_save($language);
     drupal_set_message(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => t($predefined[$langcode][0]), '@locale-help' => url('admin/help/locale'))));
   }
 
@@ -404,28 +390,17 @@ function locale_languages_edit_form_validate($form, &$form_state) {
  * Process the language editing form submission.
  */
 function locale_languages_edit_form_submit($form, &$form_state) {
-  db_update('languages')
-    ->fields(array(
-      'name' => $form_state['values']['name'],
-      'native' => $form_state['values']['native'],
-      'domain' => $form_state['values']['domain'],
-      'prefix' => $form_state['values']['prefix'],
-      'direction' => $form_state['values']['direction'],
-    ))
-    ->condition('language',  $form_state['values']['langcode'])
-    ->execute();
-  $default = language_default();
-  if ($default->language == $form_state['values']['langcode']) {
-    $properties = array('name', 'native', 'direction', 'enabled', 'plurals', 'formula', 'domain', 'prefix', 'weight');
-    foreach ($properties as $keyname) {
-      if (isset($form_state['values'][$keyname])) {
-        $default->$keyname = $form_state['values'][$keyname];
-      }
-    }
-    variable_set('language_default', $default);
-  }
+  // Prepare a language object for saving
+  $languages = language_list();
+  $langcode = $form_state['values']['langcode'];
+  $language = $languages[$langcode];
+  $language->name = $form_state['values']['name'];
+  $language->native = $form_state['values']['native'];
+  $language->direction = $form_state['values']['direction'];
+  $language->domain = $form_state['values']['domain'];
+  $language->prefix = $form_state['values']['prefix'];
+  locale_language_save($language);
   $form_state['redirect'] = 'admin/config/regional/language';
-  return;
 }
 
 /**
diff --git a/modules/locale/locale.api.php b/modules/locale/locale.api.php
index 96f5b778b835..7b2712edbd1c 100644
--- a/modules/locale/locale.api.php
+++ b/modules/locale/locale.api.php
@@ -165,6 +165,39 @@ function hook_language_fallback_candidates_alter(array &$fallback_candidates) {
   $fallback_candidates = array_reverse($fallback_candidates);
 }
 
+ /**
+ * React to a language about to be added or updated in the system.
+ *
+ * @param $language
+ *   A language object.
+ */
+function hook_locale_language_presave($language) {
+  if ($language->default) {
+    // React to a new default language.
+    example_new_default_language($language);
+  }
+}
+
+/**
+ * React to a language that was just added to the system.
+ *
+ * @param $language
+ *   A language object.
+ */
+function hook_locale_language_insert($language) {
+  example_refresh_permissions();
+}
+
+/**
+ * React to a language that was just updated in the system.
+ *
+ * @param $language
+ *   A language object.
+ */
+function hook_locale_language_update($language) {
+  example_refresh_permissions();
+}
+
 /**
  * Allow modules to react before the deletion of a language.
  *
diff --git a/modules/locale/locale.bulk.inc b/modules/locale/locale.bulk.inc
index d27c80a5ad2d..51f80a635d7a 100644
--- a/modules/locale/locale.bulk.inc
+++ b/modules/locale/locale.bulk.inc
@@ -70,7 +70,10 @@ function locale_translate_import_form_submit($form, &$form_state) {
     if (!isset($languages[$langcode])) {
       include_once DRUPAL_ROOT . '/includes/standard.inc';
       $predefined = standard_language_list();
-      locale_add_language($langcode);
+      $language = (object) array(
+        'language' => $langcode,
+      );
+      locale_language_save($language);
       drupal_set_message(t('The language %language has been created.', array('%language' => t($predefined[$langcode][0]))));
     }
 
diff --git a/modules/locale/locale.test b/modules/locale/locale.test
index 255642e594ee..31556cbeb0c4 100644
--- a/modules/locale/locale.test
+++ b/modules/locale/locale.test
@@ -1097,12 +1097,18 @@ class LocaleUninstallFunctionalTest extends DrupalWebTestCase {
 
     // Add a new language and optionally set it as default.
     require_once DRUPAL_ROOT . '/includes/locale.inc';
-    locale_add_language('fr', 'French', 'Français', LANGUAGE_LTR, '', '', TRUE, $this->language == 'fr');
+
+    $language = (object) array(
+      'language' => 'fr',
+      'name' => 'French',
+      'native' => 'Français',
+      'default' => $this->language == 'fr',
+    );
+    locale_language_save($language);
 
     // Check the UI language.
     drupal_language_initialize();
-    global $language;
-    $this->assertEqual($language->language, $this->language, t('Current language: %lang', array('%lang' => $language->language)));
+    $this->assertEqual($GLOBALS['language']->language, $this->language, t('Current language: %lang', array('%lang' => $GLOBALS['language']->language)));
 
     // Enable multilingual workflow option for articles.
     variable_set('language_content_type_article', 1);
@@ -1147,7 +1153,7 @@ class LocaleUninstallFunctionalTest extends DrupalWebTestCase {
 
     // Check the init language logic.
     drupal_language_initialize();
-    $this->assertEqual($language->language, 'en', t('Language after uninstall: %lang', array('%lang' => $language->language)));
+    $this->assertEqual($GLOBALS['language']->language, 'en', t('Language after uninstall: %lang', array('%lang' => $GLOBALS['language']->language)));
 
     // Check JavaScript files deletion.
     $this->assertTrue($result = !file_exists($js_file), t('JavaScript file deleted: %file', array('%file' => $result ? $js_file : t('found'))));
@@ -1270,19 +1276,19 @@ class LocaleLanguageSwitchingFunctionalTest extends DrupalWebTestCase {
     );
     foreach ($language_switcher->ul->li as $link) {
       $classes = explode(" ", (string) $link['class']);
-      list($language) = array_intersect($classes, array('en', 'fr'));
+      list($langcode) = array_intersect($classes, array('en', 'fr'));
       if (in_array('active', $classes)) {
-        $links['active'][] = $language;
+        $links['active'][] = $langcode;
       }
       else {
-        $links['inactive'][] = $language;
+        $links['inactive'][] = $langcode;
       }
       $anchor_classes = explode(" ", (string) $link->a['class']);
       if (in_array('active', $anchor_classes)) {
-        $anchors['active'][] = $language;
+        $anchors['active'][] = $langcode;
       }
       else {
-        $anchors['inactive'][] = $language;
+        $anchors['inactive'][] = $langcode;
       }
     }
     $this->assertIdentical($links, array('active' => array('en'), 'inactive' => array('fr')), t('Only the current language list item is marked as active on the language switcher block.'));
@@ -1795,13 +1801,13 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
   function testUILanguageNegotiation() {
     // A few languages to switch to.
     // This one is unknown, should get the default lang version.
-    $language_unknown = 'blah-blah';
+    $langcode_unknown = 'blah-blah';
     // For testing browser lang preference.
-    $language_browser_fallback = 'vi';
+    $langcode_browser_fallback = 'vi';
     // For testing path prefix.
-    $language = 'zh-hans';
+    $langcode = 'zh-hans';
     // For setting browser language preference to 'vi'.
-    $http_header_browser_fallback = array("Accept-Language: $language_browser_fallback;q=1");
+    $http_header_browser_fallback = array("Accept-Language: $langcode_browser_fallback;q=1");
     // For setting browser language preference to some unknown.
     $http_header_blah = array("Accept-Language: blah;q=1");
 
@@ -1810,8 +1816,14 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
 
     // Setup the site languages by installing two languages.
     require_once DRUPAL_ROOT . '/includes/locale.inc';
-    locale_add_language($language_browser_fallback);
-    locale_add_language($language);
+    $language = (object) array(
+      'language' => $langcode_browser_fallback,
+    );
+    locale_language_save($language);
+    $language = (object) array(
+      'language' => $langcode,
+    );
+    locale_language_save($language);
 
     // We will look for this string in the admin/config screen to see if the
     // corresponding translated string is shown.
@@ -1830,16 +1842,16 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
     variable_del('language_default');
 
     // Translate the string.
-    $language_browser_fallback_string = "In $language_browser_fallback In $language_browser_fallback In $language_browser_fallback";
-    $language_string = "In $language In $language In $language";
+    $language_browser_fallback_string = "In $langcode_browser_fallback In $langcode_browser_fallback In $langcode_browser_fallback";
+    $language_string = "In $langcode In $langcode In $langcode";
     // Do a translate search of our target string.
     $edit = array( 'string' => $default_string);
     $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Filter'));
     // Should find the string and now click edit to post translated string.
     $this->clickLink('edit');
     $edit = array(
-      "translations[$language_browser_fallback]" => $language_browser_fallback_string,
-      "translations[$language]" => $language_string,
+      "translations[$langcode_browser_fallback]" => $language_browser_fallback_string,
+      "translations[$langcode]" => $language_string,
     );
     $this->drupalPost(NULL, $edit, t('Save translations'));
 
@@ -1858,7 +1870,7 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
       // Language prefix.
       array(
         'language_negotiation' => array(LOCALE_LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_DEFAULT),
-        'path' => "$language/admin/config",
+        'path' => "$langcode/admin/config",
         'expect' => $language_string,
         'http_header' => $http_header_browser_fallback,
         'message' => 'URL (PATH) > DEFAULT: with language prefix, UI language is switched based on path prefix',
@@ -1874,7 +1886,7 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
       // Prefix, switch to the language.
       array(
         'language_negotiation' => array(LOCALE_LANGUAGE_NEGOTIATION_URL, LOCALE_LANGUAGE_NEGOTIATION_BROWSER),
-        'path' => "$language/admin/config",
+        'path' => "$langcode/admin/config",
         'expect' => $language_string,
         'http_header' => $http_header_browser_fallback,
         'message' => 'URL (PATH) > BROWSER: with langage prefix, UI language is based on path prefix',
@@ -1895,13 +1907,13 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
 
     // Unknown language prefix should return 404.
     variable_set('language_negotiation_' . LANGUAGE_TYPE_INTERFACE, locale_language_negotiation_info());
-    $this->drupalGet("$language_unknown/admin/config", array(), $http_header_browser_fallback);
+    $this->drupalGet("$langcode_unknown/admin/config", array(), $http_header_browser_fallback);
     $this->assertResponse(404, "Unknown language path prefix should return 404");
 
     // Setup for domain negotiation, first configure the language to have domain
     // URL. We use https and a port to make sure that only the domain name is used.
     $edit = array('prefix' => '', 'domain' => "https://$language_domain:99");
-    $this->drupalPost("admin/config/regional/language/edit/$language", $edit, t('Save language'));
+    $this->drupalPost("admin/config/regional/language/edit/$langcode", $edit, t('Save language'));
     // Set the site to use domain language negotiation.
 
     $tests = array(
@@ -1952,8 +1964,11 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
    */
   function testUrlLanguageFallback() {
     // Add the Italian language.
-    $language_browser_fallback = 'it';
-    locale_add_language($language_browser_fallback);
+    $langcode_browser_fallback = 'it';
+    $language = (object) array(
+      'language' => $langcode_browser_fallback,
+    );
+    locale_language_save($language);
     $languages = language_list();
 
     // Enable the path prefix for the default language: this way any unprefixed
@@ -1977,14 +1992,14 @@ class LocaleUILanguageNegotiationTest extends DrupalWebTestCase {
 
     // Access the front page without specifying any valid URL language prefix
     // and having as browser language preference a non-default language.
-    $http_header = array("Accept-Language: $language_browser_fallback;q=1");
+    $http_header = array("Accept-Language: $langcode_browser_fallback;q=1");
     $this->drupalGet('', array(), $http_header);
 
     // Check that the language switcher active link matches the given browser
     // language.
-    $args = array(':url' => base_path() . (!empty($GLOBALS['conf']['clean_url']) ? $language_browser_fallback : "?q=$language_browser_fallback"));
+    $args = array(':url' => base_path() . (!empty($GLOBALS['conf']['clean_url']) ? $langcode_browser_fallback : "?q=$langcode_browser_fallback"));
     $fields = $this->xpath('//div[@id="block-locale-language"]//a[@class="language-link active" and @href=:url]', $args);
-    $this->assertTrue($fields[0] == $languages[$language_browser_fallback]->native, t('The browser language is the URL active language'));
+    $this->assertTrue($fields[0] == $languages[$langcode_browser_fallback]->native, t('The browser language is the URL active language'));
 
     // Check that URLs are rewritten using the given browser language.
     $fields = $this->xpath('//div[@id="site-name"]//a[@rel="home" and @href=:url]//span', $args);
@@ -2094,7 +2109,12 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase {
 
     // Add a new language.
     require_once DRUPAL_ROOT . '/includes/locale.inc';
-    locale_add_language('it', 'Italian', 'Italiano', LANGUAGE_LTR, '', '', TRUE, FALSE);
+    $language = (object) array(
+      'language' => 'it',
+      'name' => 'Italian',
+      'native' => 'Italiano',
+    );
+    locale_language_save($language);
 
     // Enable URL language detection and selection.
     $edit = array('language[enabled][locale-url]' => '1');
@@ -2252,13 +2272,13 @@ class LocaleCommentLanguageFunctionalTest extends DrupalWebTestCase {
     // language and interface language do not influence comment language, as
     // only content language has to.
     foreach (language_list() as $node_langcode => $node_language) {
-      $language_none = LANGUAGE_NONE;
+      $langcode_none = LANGUAGE_NONE;
 
       // Create "Article" content.
       $title = $this->randomName();
       $edit = array(
         "title" => $title,
-        "body[$language_none][0][value]" => $this->randomName(),
+        "body[$langcode_none][0][value]" => $this->randomName(),
         "language" => $node_langcode,
       );
       $this->drupalPost("node/add/article", $edit, t('Save'));
@@ -2267,7 +2287,7 @@ class LocaleCommentLanguageFunctionalTest extends DrupalWebTestCase {
       foreach (language_list() as $langcode => $language) {
         // Post a comment with content language $langcode.
         $prefix = empty($language->prefix) ? '' : $language->prefix . '/';
-        $edit = array("comment_body[$language_none][0][value]" => $this->randomName());
+        $edit = array("comment_body[$langcode_none][0][value]" => $this->randomName());
         $this->drupalPost("{$prefix}node/{$node->nid}", $edit, t('Save'));
 
         // Check that comment language matches the current content language.
diff --git a/modules/system/system.test b/modules/system/system.test
index b384400d9a47..1dd2349f7007 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -1215,7 +1215,11 @@ class DateTimeFunctionalTest extends DrupalWebTestCase {
     $this->assertFalse($format, 'Unlocalized date format resides not in localized table.');
 
     // Enable German language
-    locale_add_language('de', NULL, NULL, LANGUAGE_LTR, '', '', TRUE, 'en');
+    $language = (object) array(
+      'language' => 'de',
+      'default' => TRUE,
+    );
+    locale_language_save($language);
 
     $date_format = array(
       'type' => 'short',
-- 
GitLab