? .DS_Store
? language_negotiation_00.patch
? language_negotiation_01.patch
? modules/.DS_Store
? profiles/.DS_Store
? sites/.DS_Store
? sites/default/files
? sites/default/settings.php
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.256
diff -u -p -r1.256 bootstrap.inc
--- includes/bootstrap.inc	30 Nov 2008 01:05:16 -0000	1.256
+++ includes/bootstrap.inc	2 Dec 2008 22:20:37 -0000
@@ -175,23 +175,14 @@ define('DRUPAL_KILOBYTE', 1024);
 define('LANGUAGE_NEGOTIATION_NONE', 0);
 
 /**
- * Path based negotiation with fallback to default language
- * if no defined path prefix identified.
+ * Path based negotiation.
  */
-define('LANGUAGE_NEGOTIATION_PATH_DEFAULT', 1);
+define('LANGUAGE_NEGOTIATION_PATH', 1);
 
 /**
- * Path based negotiation with fallback to user preferences
- * and browser language detection if no defined path prefix
- * identified.
+ * Domain based negotiation.
  */
-define('LANGUAGE_NEGOTIATION_PATH', 2);
-
-/**
- * Domain based negotiation with fallback to default language
- * if no language identified by domain.
- */
-define('LANGUAGE_NEGOTIATION_DOMAIN', 3);
+define('LANGUAGE_NEGOTIATION_DOMAIN', 2);
 
 /**
  * For convenience, define a short form of the request time global.
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.832
diff -u -p -r1.832 common.inc
--- includes/common.inc	30 Nov 2008 01:05:16 -0000	1.832
+++ includes/common.inc	2 Dec 2008 22:20:38 -0000
@@ -1889,7 +1889,7 @@ function drupal_add_css($path = NULL, $o
     $css[$media][$type][$path] = $options['preprocess'];
 
     // If the current language is RTL, add the CSS file with RTL overrides.
-    if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
+    if (defined('LANGUAGE_RTL') && $language['interface']->direction == LANGUAGE_RTL) {
       $rtl_path = str_replace('.css', '-rtl.css', $path);
       if (file_exists($rtl_path)) {
         $css[$media][$type][$rtl_path] = $options['preprocess'];
Index: includes/language.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/language.inc,v
retrieving revision 1.16
diff -u -p -r1.16 language.inc
--- includes/language.inc	14 Apr 2008 17:48:33 -0000	1.16
+++ includes/language.inc	2 Dec 2008 22:20:39 -0000
@@ -14,56 +14,119 @@ function language_initialize() {
 
   // Configured presentation language mode.
   $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
+
+  // The user wants to see the site in the default language.
+  if ($user->language == '<default>' && variable_get('language_user_override', FALSE)) {
+    switch ($mode) {
+      case LANGUAGE_NEGOTIATION_NONE:
+        $language['content'] = $language['interface'] = language_default();
+        break;
+      case LANGUAGE_NEGOTIATION_PATH:
+        $language['content'] = $language['interface'] = language_negotiate_path();
+        break;
+      case LANGUAGE_NEGOTIATION_DOMAIN:
+        $language['content'] = $language['interface'] = language_negotiate_domain();
+        break;
+    }
+  }
+  // The user wants to see the site in a language of his choice.
+  else {
+    switch ($mode) {
+      case LANGUAGE_NEGOTIATION_NONE:
+        $language['content'] = $language['interface'] = language_exists($user->language);
+        break;
+      case LANGUAGE_NEGOTIATION_PATH:
+        $language['content'] = language_negotiate_path();
+        $language['interface'] = language_exists($user->language);
+        break;
+      case LANGUAGE_NEGOTIATION_DOMAIN:
+        $language['content'] = language_negotiate_domain();
+        $language['interface'] = language_exists($user->language);
+        break;
+    }
+  }
+  return $language;
+}
+
+/**
+ * Load a language if enabled or the default otherwise.
+ *
+ * @param $language
+ *   A language code, i.e. 'en'.
+ *
+ * @return
+ *   A language object.
+ */
+function language_exists($language = NULL) {
   // Get a list of enabled languages.
   $languages = language_list('enabled');
   $languages = $languages[1];
 
-  switch ($mode) {
-    case LANGUAGE_NEGOTIATION_NONE:
-      return language_default();
-
-    case LANGUAGE_NEGOTIATION_DOMAIN:
-      foreach ($languages as $language) {
-        $parts = parse_url($language->domain);
-        if (!empty($parts['host']) && ($_SERVER['SERVER_NAME'] == $parts['host'])) {
-          return $language;
-        }
-      }
-      return language_default();
+  return isset($languages[$language]) ? $languages[$language] : language_fallback();
+}
 
-    case LANGUAGE_NEGOTIATION_PATH_DEFAULT:
-    case LANGUAGE_NEGOTIATION_PATH:
-      // $_GET['q'] might not be available at this time, because
-      // path initialization runs after the language bootstrap phase.
-      $args = isset($_GET['q']) ? explode('/', $_GET['q']) : array();
-      $prefix = array_shift($args);
-      // Search prefix within enabled languages.
-      foreach ($languages as $language) {
-        if (!empty($language->prefix) && $language->prefix == $prefix) {
-          // Rebuild $GET['q'] with the language removed.
-          $_GET['q'] = implode('/', $args);
-          return $language;
-        }
-      }
-      if ($mode == LANGUAGE_NEGOTIATION_PATH_DEFAULT) {
-        // If we did not found the language by prefix, choose the default.
-        return language_default();
-      }
-      break;
-  }
+/**
+ * Indentify the language from the current domain.
+ *
+ * @return
+ *   The object of the identified language.
+ */
+function language_negotiate_domain() {
+  // Get a list of enabled languages.
+  $languages = language_list('enabled');
+  $languages = $languages[1];
 
-  // User language.
-  if ($user->uid && isset($languages[$user->language])) {
-    return $languages[$user->language];
+  foreach ($languages as $language) {
+    $parts = parse_url($language->domain);
+    if (!empty($parts['host']) && ($_SERVER['SERVER_NAME'] == $parts['host'])) {
+      return $language;
+    }
   }
+  return language_fallback(); 
+}
+
+/**
+ * Indentify the language from the current path.
+ *
+ * @return
+ *   The object of the identified language.
+ */
+function language_negotiate_path() {
+  // Get a list of enabled languages.
+  $languages = language_list('enabled');
+  $languages = $languages[1];
 
-  // Browser accept-language parsing.
-  if ($language = language_from_browser()) {
-    return $language;
+  // $_GET['q'] might not be available at this time, because
+  // path initialization runs after the language bootstrap phase.
+  $args = isset($_GET['q']) ? explode('/', $_GET['q']) : array();
+  $prefix = array_shift($args);
+  // Search prefix within enabled languages.
+  foreach ($languages as $language) {
+    if (!empty($language->prefix) && $language->prefix == $prefix) {
+      // Rebuild $GET['q'] with the language removed.
+      $_GET['q'] = implode('/', $args);
+      return $language;
+    }
   }
+  return language_fallback(); 
+}
+
+/**
+ * Get language by using fallback methods.
+ *
+ * @return
+ *   A language object.
+ */
+function language_fallback() {
+  if (variable_get('language_negotiation_fallback', TRUE)) {
+    // Browser accept-language parsing.
+    if ($language = language_from_browser()) {
+      return $language;
+    }
 
-  // Fall back on the default if everything else fails.
-  return language_default();
+    // Fall back on the default if everything else fails.
+    return language_default();
+  }
 }
 
 /**
Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.195
diff -u -p -r1.195 locale.inc
--- includes/locale.inc	16 Nov 2008 19:41:14 -0000	1.195
+++ includes/locale.inc	2 Dec 2008 22:20:39 -0000
@@ -456,29 +456,27 @@ function locale_languages_configure_form
     '#type' => 'radios',
     '#options' => array(
       LANGUAGE_NEGOTIATION_NONE => t('None.'),
-      LANGUAGE_NEGOTIATION_PATH_DEFAULT => t('Path prefix only.'),
-      LANGUAGE_NEGOTIATION_PATH => t('Path prefix with language fallback.'),
-      LANGUAGE_NEGOTIATION_DOMAIN => t('Domain name only.')),
+      LANGUAGE_NEGOTIATION_PATH => t('Path prefix.'),
+      LANGUAGE_NEGOTIATION_DOMAIN => t('Domain name.')),
     '#default_value' => variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE),
     '#description' => t("Select the mechanism used to determine your site's presentation language. <strong>Modifying this setting may break all incoming URLs and should be used with caution in a production environment.</strong>")
   );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save settings')
+  $form['language_negotiation_fallback'] = array(
+    '#title' => t('Language negotiation fallback'),
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('language_negotiation_fallback', TRUE),
+    '#description' => t("Display the site in the user's browser language or your site's default language if a match for <em>Language negotiation</em> cannot be found."),
   );
-  return $form;
+  $form['language_user_override'] = array(
+    '#title' => t('Allow user preferred language'),
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('language_user_override', FALSE),
+    '#description' => t("Allow authenticated users to select in which language to view your site. This will not affect your site's presentation language, unless <em>Language negotiation</em> has been set to <em>None</em>."),
+  );
+  return system_settings_form($form);
 }
 
 /**
- * Submit function for language negotiation settings.
- */
-function locale_languages_configure_form_submit($form, &$form_state) {
-  variable_set('language_negotiation', $form_state['values']['language_negotiation']);
-  drupal_set_message(t('Language negotiation configuration saved.'));
-  $form_state['redirect'] = 'admin/settings/language';
-  return;
-}
-/**
  * @} End of "locale-languages-negotiation"
  */
 
Index: includes/path.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/path.inc,v
retrieving revision 1.28
diff -u -p -r1.28 path.inc
--- includes/path.inc	14 Oct 2008 11:01:08 -0000	1.28
+++ includes/path.inc	2 Dec 2008 22:20:40 -0000
@@ -48,7 +48,7 @@ function drupal_lookup_path($action, $pa
   // $map is an array with language keys, holding arrays of Drupal paths to alias relations
   static $map = array(), $no_src = array(), $count;
 
-  $path_language = $path_language ? $path_language : $language->language;
+  $path_language = $path_language ? $path_language : $language['content']->language;
 
   // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
   if (!isset($count)) {
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.232
diff -u -p -r1.232 locale.module
--- modules/locale/locale.module	23 Nov 2008 16:00:06 -0000	1.232
+++ modules/locale/locale.module	2 Dec 2008 22:20:40 -0000
@@ -50,10 +50,9 @@ function locale_help($path, $arg) {
       return '<p>' . t('Add all languages to be supported by your site. If your desired language is not available in the <em>Language name</em> drop-down, click <em>Custom language</em> and provide a language code and other details manually. When providing a language code manually, be sure to enter a standardized language code, since this code may be used by browsers to determine an appropriate display language.') . '</p>';
     case 'admin/settings/language/configure':
       $output = '<p>' . t("Language negotiation settings determine the site's presentation language. Available options include:") . '</p>';
-      $output .= '<ul><li>' . t('<strong>None.</strong> The default language is used for site presentation, though users may (optionally) select a preferred language on the <em>My Account</em> page. (User language preferences will be used for site e-mails, if available.)') . '</li>';
-      $output .= '<li>' . t('<strong>Path prefix only.</strong> The presentation language is determined by examining the path for a language code or other custom string that matches the path prefix (if any) specified for each language. If a suitable prefix is not identified, the default language is used. <em>Example: "example.com/de/contact" sets presentation language to German based on the use of "de" within the path.</em>') . '</li>';
-      $output .= '<li>' . t("<strong>Path prefix with language fallback.</strong> The presentation language is determined by examining the path for a language code or other custom string that matches the path prefix (if any) specified for each language. If a suitable prefix is not identified, the display language is determined by the user's language preferences from the <em>My Account</em> page, or by the browser's language settings. If a presentation language cannot be determined, the default language is used.") . '</li>';
-      $output .= '<li>' . t('<strong>Domain name only.</strong> The presentation language is determined by examining the domain used to access the site, and comparing it to the language domain (if any) specified for each language. If a match is not identified, the default language is used. <em>Example: "http://de.example.com/contact" sets presentation language to German based on the use of "http://de.example.com" in the domain.</em>') . '</li></ul>';
+      $output .= '<ul><li>' . t('<strong>None.</strong> The default language is used for site presentation.') . '</li>';
+      $output .= '<li>' . t('<strong>Path prefix.</strong> The presentation language is determined by examining the path for a language code or other custom string that matches the path prefix (if any) specified for each language. <em>Example: "example.com/de/contact" sets presentation language to German based on the use of "de" within the path.</em>') . '</li>';
+      $output .= '<li>' . t('<strong>Domain name.</strong> The presentation language is determined by examining the domain used to access the site, and comparing it to the language domain (if any) specified for each language. <em>Example: "http://de.example.com/contact" sets presentation language to German based on the use of "http://de.example.com" in the domain.</em>') . '</li></ul>';
       $output .= '<p>' . t('The path prefix or domain name for a language may be set by editing the <a href="@languages">available languages</a>. In the absence of an appropriate match, the site is displayed in the <a href="@languages">default language</a>.', array('@languages' => url('admin/settings/language'))) . '</p>';
       return $output;
     case 'admin/build/translate':
@@ -241,7 +240,8 @@ function locale_language_selector_form($
   // If the user is being created, we set the user language to the page language.
   $user_preferred_language = $user ? user_preferred_language($user) : $language;
 
-  $names = array();
+  $default_language = language_default();
+  $names = array('<default>' => t('Default') . ' (' . t('Currently %language', array('%language' => t($default_language->name))) . ')');
   foreach ($languages as $langcode => $item) {
     $name = t($item->name);
     $names[$langcode] = $name . ($item->native != $name ? ' (' . $item->native . ')' : '');
@@ -259,7 +259,7 @@ function locale_language_selector_form($
     '#title' => t('Language'),
     '#default_value' => $user_preferred_language->language,
     '#options' => $names,
-    '#description' => ($mode == LANGUAGE_NEGOTIATION_PATH) ? t("This account's default language for e-mails, and preferred language for site presentation.") : t("This account's default language for e-mails."),
+    '#description' => ($mode == LANGUAGE_NEGOTIATION_NONE) ? t("This account's default interface and content language.") : t("This account's default interface language."),
   );
   return $form;
 }
