? bootstrap.patch
? init.inc
Index: cron.php
===================================================================
RCS file: /cvs/drupal/drupal/cron.php,v
retrieving revision 1.28
diff -u -F^f -r1.28 cron.php
--- cron.php	9 Jan 2005 09:22:38 -0000	1.28
+++ cron.php	21 Jun 2005 20:49:08 -0000
@@ -7,7 +7,7 @@
  */
 
 include_once 'includes/bootstrap.inc';
-include_once 'includes/common.inc' ;
+drupal_bootstrap('full');
 
 // If not in 'safe mode', increase the maximum execution time:
 if (!ini_get('safe_mode')) {
Index: index.php
===================================================================
RCS file: /cvs/drupal/drupal/index.php,v
retrieving revision 1.84
diff -u -F^f -r1.84 index.php
--- index.php	21 May 2005 18:33:58 -0000	1.84
+++ index.php	21 Jun 2005 20:49:08 -0000
@@ -9,12 +9,8 @@
  * prints the appropriate page.
  */
 
-include_once 'includes/bootstrap.inc';
-drupal_page_header();
-include_once 'includes/common.inc';
-
-fix_gpc_magic();
-fix_checkboxes();
+require_once './includes/bootstrap.inc';
+drupal_bootstrap('full');
 
 $return = menu_execute_active_handler();
 switch ($return) {
Index: xmlrpc.php
===================================================================
RCS file: /cvs/drupal/drupal/xmlrpc.php,v
retrieving revision 1.9
diff -u -F^f -r1.9 xmlrpc.php
--- xmlrpc.php	21 Aug 2004 06:42:34 -0000	1.9
+++ xmlrpc.php	21 Jun 2005 20:49:08 -0000
@@ -7,8 +7,7 @@
  */
 
 include_once 'includes/bootstrap.inc';
-include_once 'includes/common.inc';
-include_once 'includes/xmlrpc.inc';
+drupal_bootstrap('full');
 include_once 'includes/xmlrpcs.inc';
 
 $functions = module_invoke_all('xmlrpc');
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.52
diff -u -F^f -r1.52 bootstrap.inc
--- includes/bootstrap.inc	21 Jun 2005 18:21:08 -0000	1.52
+++ includes/bootstrap.inc	21 Jun 2005 20:49:08 -0000
@@ -789,27 +789,72 @@ function drupal_is_denied($type, $mask) 
   return $deny && !$allow;
 }
 
-
-// Start a page timer:
-timer_start('page');
-
-unset($conf);
-$config = conf_init();
-
-include_once "$config/settings.php";
-include_once 'includes/database.inc';
-
-// deny access to hosts which were banned. t() is not yet available.
-if (drupal_is_denied('host', $_SERVER['REMOTE_ADDR'])) {
-  header('HTTP/1.0 403 Forbidden');
-  print "Sorry, ". $_SERVER['REMOTE_ADDR']. " has been banned.";
-  exit();
+/**
+ * A string describing a phase of Drupal to load. Each phase adds to the
+ * previous one, so invoking a later phase automatically runs the earlier
+ * phases too. The most important usage is that if you want to access
+ * Drupal database from a script without loading anything
+ * else, you can include bootstrap.inc, and call drupal_bootstrap('database').
+ *
+ * @param $phase
+ *   A string. Allowed values are:
+ *     'database': Initialize Drupal database system.
+ *     'session': Initialize Drupal session handling system.
+ *     'page cache': Load bootstrap.inc and module.inc, start the variable
+ *                   system and try to serve a page from the cache.
+ *    'full': Drupal is fully loaded. input data checks and fixes are
+ *            performed.
+ */
+function drupal_bootstrap($phase) {
+  static $phases = array('database', 'session', 'page cache', 'full');
+
+  while ($current_phase = array_shift($phases)) {
+    _drupal_bootstrap($current_phase);
+    if ($phase == $current_phase) {
+      return;
+    }
+  }
 }
 
-include_once 'includes/session.inc';
-include_once 'includes/module.inc';
+function _drupal_bootstrap($phase) {
+  global $conf;
 
-// Initialize configuration variables, using values from conf.php if available.
-$conf = variable_init(isset($conf) ? $conf : array());
+  switch ($phase) {
+    case 'database':
+      global $db_url, $base_url;
+      unset($conf);
+      require_once conf_init() .'/settings.php';
+      require_once './includes/database.inc';
+      // Initialize the default database.
+      db_set_active();
+      break;
+    case 'session':
+      require_once './includes/session.inc';
+      session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
+      session_start();
+      break;
+    case 'page cache':
+      require_once './includes/bootstrap.inc';
+      require_once './includes/module.inc';
+      // Start a page timer:
+      timer_start('page');
+
+      // deny access to hosts which were banned. t() is not yet available.
+      if (drupal_deny('host', $_SERVER['REMOTE_ADDR'])) {
+        header('HTTP/1.0 403 Forbidden');
+        print "Sorry, ". $_SERVER['REMOTE_ADDR']. " has been banned.";
+        exit();
+      }
+
+      // Initialize configuration variables, using values from conf.php if available.
+      $conf = variable_init(isset($conf) ? $conf : array());
+      drupal_page_header();
+      break;
+    case 'full':
+      require_once './includes/common.inc';
+      _drupal_bootstrap_full();
+      break;
+  }
+}
 
 ?>
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.455
diff -u -F^f -r1.455 common.inc
--- includes/common.inc	21 Jun 2005 09:45:42 -0000	1.455
+++ includes/common.inc	21 Jun 2005 20:49:10 -0000
@@ -812,7 +812,7 @@ function format_plural($count, $singular
   if ($count == 1) return t($singular, array("%count" => $count));
 
   // get the plural index through the gettext formula
-  $index = (function_exists('locale')) ? locale_get_plural($count) : -1;
+  $index = (function_exists('locale_get_plural')) ? locale_get_plural($count) : -1;
   if ($index < 0) { // backward compatibility
     return t($plural, array("%count" => $count));
   }
@@ -2001,12 +2001,8 @@ function drupal_get_path($type, $name) {
 /**
  * Provide a substitute clone() function for PHP4.
  */
-if (version_compare(phpversion(), '5.0') < 0) {
-  eval('
-    function clone($object) {
-      return $object;
-    }
-  ');
+function drupal_clone($object) {
+  return version_compare(phpversion(), '5.0') < 0 ? $object : clone($object);
 }
 
 /**
@@ -2054,44 +2050,48 @@ function drupal_implode_autocomplete($ar
   return implode('||', $output);
 }
 
-// Set the Drupal custom error handler.
-set_error_handler('error_handler');
-
-include_once 'includes/theme.inc';
-include_once 'includes/pager.inc';
-include_once 'includes/menu.inc';
-include_once 'includes/tablesort.inc';
-include_once 'includes/file.inc';
-include_once 'includes/xmlrpc.inc';
-include_once 'includes/image.inc';
-
-// Emit the correct charset HTTP header.
-drupal_set_header('Content-Type: text/html; charset=utf-8');
-
-// Initialize $_GET['q'] prior to loading modules and invoking hook_init().
-if (!empty($_GET['q'])) {
-  $_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
-}
-else {
-  $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
-}
-
-// Initialize all enabled modules.
-module_init();
-
-if (!user_access('bypass input data check')) {
-  // We can't use $_REQUEST because it consists of the contents of $_POST,
-  // $_GET and $_COOKIE: if any of the input arrays share a key, only one
-  // value will be verified.
-  if (!valid_input_data($_GET)
-   || !valid_input_data($_POST)
-   || !valid_input_data($_COOKIE)
-   || !valid_input_data($_FILES)) {
-    die('Terminated request because of suspicious input data.');
+function _drupal_bootstrap_full() {
+  static $called;
+  global $locale;
+
+  if ($called) {
+    return;
+  }
+  $called = 1;
+  require_once './includes/theme.inc';
+  require_once './includes/pager.inc';
+  require_once './includes/menu.inc';
+  require_once './includes/tablesort.inc';
+  require_once './includes/file.inc';
+  require_once './includes/xmlrpc.inc';
+  require_once './includes/image.inc';
+  // Set the Drupal custom error handler.
+  set_error_handler('error_handler');
+  // Emit the correct charset HTTP header.
+  drupal_set_header('Content-Type: text/html; charset=utf-8');
+  // Initialize $_GET['q'] prior to loading modules and invoking hook_init().
+  if (!empty($_GET['q'])) {
+    $_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
+  }
+  else {
+    $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
   }
+  // Initialize all enabled modules.
+  module_init();
+  if (!user_access('bypass input data check')) {
+    // We can't use $_REQUEST because it consists of the contents of $_POST,
+    // $_GET and $_COOKIE: if any of the input arrays share a key, only one
+    // value will be verified.
+    if (!valid_input_data($_GET)
+    || !valid_input_data($_POST)
+    || !valid_input_data($_COOKIE)
+    || !valid_input_data($_FILES)) {
+      die('Terminated request because of suspicious input data.');
+    }
+  }
+  fix_gpc_magic();
+  fix_checkboxes();
+  // Initialize the localization system.
+  $locale = locale_initialize();
 }
-
-// Initialize the localization system.
-$locale = locale_initialize();
-
 ?>
Index: includes/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.inc,v
retrieving revision 1.40
diff -u -F^f -r1.40 database.inc
--- includes/database.inc	8 Apr 2005 14:24:03 -0000	1.40
+++ includes/database.inc	21 Jun 2005 20:49:10 -0000
@@ -279,7 +279,4 @@ function db_rewrite_sql($query, $primary
  * @} End of "defgroup database".
  */
 
-// Initialize the default database.
-db_set_active();
-
 ?>
Index: includes/database.mysql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v
retrieving revision 1.30
diff -u -F^f -r1.30 database.mysql.inc
--- includes/database.mysql.inc	23 May 2005 21:14:01 -0000	1.30
+++ includes/database.mysql.inc	21 Jun 2005 20:49:10 -0000
@@ -47,15 +47,20 @@ function db_connect($url) {
 function _db_query($query, $debug = 0) {
   global $active_db;
   global $queries;
+  static $dev_query;
 
-  if (variable_get('dev_query', 0)) {
+  if (!isset($dev_query)) {
+    $dev_query = function_exists('dev_query') ? variable_get('dev_query', 0) : $GLOBALS['conf']['dev_query'];
+  }
+
+  if ($dev_query) {
     list($usec, $sec) = explode(' ', microtime());
     $timer = (float)$usec + (float)$sec;
   }
 
   $result = mysql_query($query, $active_db);
 
-  if (variable_get('dev_query', 0)) {
+  if ($dev_query) {
     list($usec, $sec) = explode(' ', microtime());
     $stop = (float)$usec + (float)$sec;
     $diff = $stop - $timer;
Index: includes/database.pgsql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v
retrieving revision 1.8
diff -u -F^f -r1.8 database.pgsql.inc
--- includes/database.pgsql.inc	23 May 2005 21:14:01 -0000	1.8
+++ includes/database.pgsql.inc	21 Jun 2005 20:49:10 -0000
@@ -36,15 +36,20 @@ function db_connect($url) {
 function _db_query($query, $debug = 0) {
   global $active_db, $last_result;
   global $queries;
+  static $dev_query;
 
-  if (variable_get('dev_query', 0)) {
+  if (!isset($dev_query)) {
+    $dev_query = function_exists('dev_query') ? variable_get('dev_query', 0) : $GLOBALS['conf']['dev_query'];
+  }
+
+  if ($dev_query) {
     list($usec, $sec) = explode(' ', microtime());
     $timer = (float)$usec + (float)$sec;
   }
 
   $last_result = pg_query($active_db, $query);
 
-  if (variable_get('dev_query', 0)) {
+  if ($dev_query) {
     list($usec, $sec) = explode(' ', microtime());
     $stop = (float)$usec + (float)$sec;
     $diff = $stop - $timer;
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.81
diff -u -F^f -r1.81 menu.inc
--- includes/menu.inc	5 Jun 2005 09:47:13 -0000	1.81
+++ includes/menu.inc	21 Jun 2005 20:49:10 -0000
@@ -351,7 +351,7 @@ function menu_execute_active_handler() {
     $arguments = array_merge($arguments, explode('/', $arg));
   }
 
-  return call_user_func_array($menu['items'][$mid]['callback'], $arguments);
+  return function_exists($menu['items'][$mid]['callback']) ?  call_user_func_array($menu['items'][$mid]['callback'], $arguments) : '';
 }
 
 /**
Index: includes/session.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/session.inc,v
retrieving revision 1.16
diff -u -F^f -r1.16 session.inc
--- includes/session.inc	7 May 2005 11:39:54 -0000	1.16
+++ includes/session.inc	21 Jun 2005 20:49:11 -0000
@@ -6,9 +6,6 @@
  * User session handling functions.
  */
 
-session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
-session_start();
-
 /*** Session functions *****************************************************/
 
 function sess_open($save_path, $session_name) {
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.243
diff -u -F^f -r1.243 theme.inc
--- includes/theme.inc	19 Jun 2005 08:59:06 -0000	1.243
+++ includes/theme.inc	21 Jun 2005 20:49:11 -0000
@@ -34,6 +34,7 @@
 function init_theme() {
   global $user, $custom_theme, $theme_engine, $theme_key;
 
+  drupal_bootstrap('database');
   $themes = list_themes();
 
   // Only select the user selected theme if it is available in the
Index: modules/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node.module,v
retrieving revision 1.498
diff -u -F^f -r1.498 node.module
--- modules/node.module	21 Jun 2005 18:58:26 -0000	1.498
+++ modules/node.module	21 Jun 2005 20:49:12 -0000
@@ -1470,7 +1470,7 @@ function node_preview($node) {
 
     // Display a preview of the node:
     // Previewing alters $node so it needs to be cloned.
-    $output = theme('node_preview', clone($node));
+    $output = theme('node_preview', drupal_clone($node));
 
     $output .= node_form($node);
 
