? page_cache_d6.patch
? includes/bootstrap.inc.c
? includes/common.inc.c
? includes/language.inc.c
? sites/all/modules
? sites/default/files
? sites/default/settings.php
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.206.2.6
diff -u -p -r1.206.2.6 bootstrap.inc
--- includes/bootstrap.inc	22 Oct 2008 19:26:01 -0000	1.206.2.6
+++ includes/bootstrap.inc	2 Dec 2008 01:57:00 -0000
@@ -76,15 +76,16 @@ define('DRUPAL_BOOTSTRAP_ACCESS', 3);
 define('DRUPAL_BOOTSTRAP_SESSION', 4);
 
 /**
- * Sixth bootstrap phase: load bootstrap.inc and module.inc, start
- * the variable system and try to serve a page from the cache.
+ * Sixth bootstrap phase: start the variable system and find out
+ * language of the page.
  */
-define('DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE', 5);
+define('DRUPAL_BOOTSTRAP_LANGUAGE', 5);
 
 /**
- * Seventh bootstrap phase: find out language of the page.
+ * Seventh bootstrap phase: load bootstrap.inc and module.inc and
+ * try to serve a page from the cache.
  */
-define('DRUPAL_BOOTSTRAP_LANGUAGE', 6);
+define('DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE', 6);
 
 /**
  * Eighth bootstrap phase: set $_GET['q'] to Drupal path of request.
@@ -932,14 +933,15 @@ function drupal_anonymous_user($session 
  *     DRUPAL_BOOTSTRAP_DATABASE: initialize database layer.
  *     DRUPAL_BOOTSTRAP_ACCESS: identify and reject banned hosts.
  *     DRUPAL_BOOTSTRAP_SESSION: initialize session handling.
- *     DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE: load bootstrap.inc and module.inc, start
- *       the variable system and try to serve a page from the cache.
- *     DRUPAL_BOOTSTRAP_LANGUAGE: identify the language used on the page.
+ *     DRUPAL_BOOTSTRAP_LANGUAGE: start the variable system and identify the language
+ *       used on the page.
+ *     DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE: load bootstrap.inc and module.inc and
+ *       try to serve a page from the cache.
  *     DRUPAL_BOOTSTRAP_PATH: set $_GET['q'] to Drupal path of request.
  *     DRUPAL_BOOTSTRAP_FULL: Drupal is fully loaded, validate and fix input data.
  */
 function drupal_bootstrap($phase) {
-  static $phases = array(DRUPAL_BOOTSTRAP_CONFIGURATION, DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE, DRUPAL_BOOTSTRAP_DATABASE, DRUPAL_BOOTSTRAP_ACCESS, DRUPAL_BOOTSTRAP_SESSION, DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE, DRUPAL_BOOTSTRAP_LANGUAGE, DRUPAL_BOOTSTRAP_PATH, DRUPAL_BOOTSTRAP_FULL), $phase_index = 0;
+  static $phases = array(DRUPAL_BOOTSTRAP_CONFIGURATION, DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE, DRUPAL_BOOTSTRAP_DATABASE, DRUPAL_BOOTSTRAP_ACCESS, DRUPAL_BOOTSTRAP_SESSION,  DRUPAL_BOOTSTRAP_LANGUAGE, DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE, DRUPAL_BOOTSTRAP_PATH, DRUPAL_BOOTSTRAP_FULL), $phase_index = 0;
 
   while ($phase >= $phase_index && isset($phases[$phase_index])) {
     $current_phase = $phases[$phase_index];
@@ -949,7 +951,7 @@ function drupal_bootstrap($phase) {
 }
 
 function _drupal_bootstrap($phase) {
-  global $conf;
+  global $conf, $language, $language_redirect;
 
   switch ($phase) {
 
@@ -995,18 +997,40 @@ function _drupal_bootstrap($phase) {
       session_start();
       break;
 
-    case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE:
+    case DRUPAL_BOOTSTRAP_LANGUAGE:
       // Initialize configuration variables, using values from settings.php if available.
+      // The variable system is needed for language determination.
       $conf = variable_init(isset($conf) ? $conf : array());
+      drupal_init_language();
+      break;
+
+    case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE:
       // Load module handling.
       require_once './includes/module.inc';
       $cache_mode = variable_get('cache', CACHE_DISABLED);
-      // Get the page from the cache.
-      $cache = $cache_mode == CACHE_DISABLED ? '' : page_get_cache();
+
       // If the skipping of the bootstrap hooks is not enforced, call hook_boot.
       if ($cache_mode != CACHE_AGGRESSIVE) {
         bootstrap_invoke_all('boot');
       }
+
+      // If the language has been reset from the default, redirect
+      // to the new language.
+      if ($language_redirect && (($default_language = language_default()) != $language)) {
+        // Load modules required for hook_exit.
+        foreach (module_list(TRUE, TRUE) as $module) {
+          drupal_load('module', $module);
+        }
+        // We need the path system.
+        drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);
+        require_once './includes/common.inc';
+        $path = drupal_get_normal_path($_GET['q'], $default_language->language);
+        drupal_goto($path);
+      }
+
+      // Get the page from the cache.
+      $cache = $cache_mode == CACHE_DISABLED ? '' : page_get_cache();
+
       // If there is a cached page, display it.
       if ($cache) {
         drupal_page_cache_header($cache);
@@ -1021,10 +1045,6 @@ function _drupal_bootstrap($phase) {
       drupal_page_header();
       break;
 
-    case DRUPAL_BOOTSTRAP_LANGUAGE:
-      drupal_init_language();
-      break;
-
     case DRUPAL_BOOTSTRAP_PATH:
       require_once './includes/path.inc';
       // Initialize $_GET['q'] prior to loading modules and invoking hook_init().
Index: includes/language.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/language.inc,v
retrieving revision 1.14
diff -u -p -r1.14 language.inc
--- includes/language.inc	6 Jan 2008 16:46:02 -0000	1.14
+++ includes/language.inc	2 Dec 2008 01:57:00 -0000
@@ -7,10 +7,14 @@
  */
 
 /**
- *  Choose a language for the page, based on language negotiation settings.
+ * Choose a language for the page, based on language negotiation settings.
+ *
+ * @return
+ *   Boolean indicating whether the language set is valid for the current
+ *   path.
  */
 function language_initialize() {
-  global $user;
+  global $user, $language_redirect;
 
   // Configured presentation language mode.
   $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
@@ -52,13 +56,19 @@ function language_initialize() {
       break;
   }
 
+  // We should reach this point only if LANGUAGE_NEGOTIATION_PATH is set
+  // but no valid prefix was found or if some custom value has been set for
+  // language_negotiation.
+
   // User language.
   if ($user->uid && isset($languages[$user->language])) {
+    $language_redirect = TRUE;
     return $languages[$user->language];
   }
 
   // Browser accept-language parsing.
   if ($language = language_from_browser()) {
+    $language_redirect = TRUE;
     return $language;
   }
 
