? bootstrap_new.patch
Index: API.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/API.php,v
retrieving revision 1.36
diff -u -p -r1.36 API.php
--- API.php	25 Jul 2008 13:53:51 -0000	1.36
+++ API.php	17 Sep 2008 17:50:02 -0000
@@ -476,3 +476,51 @@ function hook_domainignore() {
   // User login should always be from the current domain.
   return array('user_login');
 }
+
+/**
+ * Hook domain_bootstrap_lookup allows modules to modify the domain record used on the
+ * current page on bootstrap level, that is, before it is used anywhere else.
+ *
+ * This for example allows to change the domain_id matched to the current
+ * domain name before related information is retrieved during domain_init().
+ *
+ * Note: Because this function is usually called VERY early, many Drupal
+ * functions or modules won't be loaded yet.
+ *
+ * In order for this hook to work your module needs to be registered in
+ * domain/settings.inc.
+ *
+ * @param $domain
+ * An array containing current domain (host) name (used during bootstrap) and
+ * the results of lookup against {domain} table.
+ * @return
+ * An array containing at least a valid domain_id.
+ */
+function hook_domain_bootstrap_lookup($domain) {
+  // match en.example.org to default domain (id:0)
+  if ($domain['subdomain'] == 'en.example.org') {
+    $domain['domain_id'] = 0;
+  }
+
+  return $domain;
+}
+
+/**
+ * Hook hook_domain_bootstrap_full allows modules to execute code after the domain
+ * bootstrap phases which (usually) is even before drupal's hook_boot().
+ *
+ * This can be used to modify drupal's variables system or prefix database
+ * tables, as used in modules domain_conf and domain_prefix.
+ *
+ * Note: Because this function is usually called VERY early, many Drupal
+ * functions or modules won't be loaded yet.
+ *
+ * In order for this hook to work your module needs to be registered in
+ * domain/settings.inc.
+ *
+ * @param $domain
+ * An array containing current subdomain and domain_id and any other values
+ * added during domain bootstrap phase 2 (DOMAIN_BOOTSTRAP_DOMAINNAME_RESOLVE).
+ */
+function hook_domain_bootstrap_full($domain) {
+}
Index: domain.bootstrap.inc
===================================================================
RCS file: domain.bootstrap.inc
diff -N domain.bootstrap.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ domain.bootstrap.inc	17 Sep 2008 17:50:02 -0000
@@ -0,0 +1,353 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Domain bootstrap file.
+ *
+ * The domain bootstrap process is initiated in domain/settings.inc which is
+ * (supposed to be) included in the user's settings.php and therefore initiated
+ * during drupal's first bootstrap phase (DRUPAL_BOOTSTRAP_CONFIGURATION).
+ *
+ * The purpose of this is to allow domain-based modules to modify basic drupal
+ * systems like the variable or database/prefix system - before they are used by
+ * any other modules.
+ *
+ * @ingroup domain
+ */
+
+/**
+ * Domain bootstrap phase 1: makes sure that database is initialised and
+ * loads all necessary module files.
+ */
+define('DOMAIN_BOOTSTRAP_INIT', 0);
+
+/**
+ * Domain bootstrap phase 2: resolves host and does a lookup in the {domain}
+ * table. Also invokes hook "hook_domain_bootstrap_lookup".
+ */
+define('DOMAIN_BOOTSTRAP_DOMAINNAME_RESOLVE', 1);
+
+/**
+ * Domain bootstrap phase 3: invokes bootstrap hook "hook_domain_bootstrap_full".
+ */
+define('DOMAIN_BOOTSTRAP_FULL', 2);
+
+/**
+ * Domain module bootstrap: calls all bootstrap phases.
+ *
+ * @todo
+ * Change handling of bootstrap errors (atm it uses die() to send a msg
+ * and exit the script; watchdog is not initialised yet and cannot be used.
+ * Maybe php:trigger_error() is an option?
+ */
+function domain_bootstrap() {
+  $phases = array(DOMAIN_BOOTSTRAP_INIT, DOMAIN_BOOTSTRAP_DOMAINNAME_RESOLVE, DOMAIN_BOOTSTRAP_FULL);
+  foreach ($phases as $phase) {
+    if (!_domain_bootstrap($phase)) {
+      die('Domain Module: Error during domain_bootstrap(), Phase '.$phase);
+    }
+  }
+}
+
+/**
+ * Calls individuell bootstrap phases.
+ *
+ * @param $phase
+ * The domain bootstrap phase to call.
+ *
+ * @return
+ * Returns TRUE if the bootstrap phase was successful and FALSE otherwise.
+ */
+function _domain_bootstrap($phase) {
+  global $_domain;
+  switch ($phase) {
+  case DOMAIN_BOOTSTRAP_INIT:
+    // make sure database is loaded
+    _drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
+
+    // load bootstrap modules
+    _domain_bootstrap_modules_load();
+    // if essential core module file has not been loaded, bootstrap fails.
+    if (!function_exists('domain_load')) {
+      return FALSE;
+    }
+
+    break;
+
+  case DOMAIN_BOOTSTRAP_DOMAINNAME_RESOLVE:
+    // get domain_id
+    $_domain = domain_resolve_host();
+    // if we don't have a valid domain id now, we can't really go on, bootstrap fails.
+    if (empty($_domain) || !is_numeric($_domain['domain_id'])) {
+      return FALSE;
+    }
+    break;
+
+  case DOMAIN_BOOTSTRAP_FULL:
+    _domain_bootstrap_invoke_all('full', $_domain);
+    break;
+  }
+  return TRUE;
+}
+
+/**
+ * Registers a module so it is loaded during domain_bootstrap and invoked
+ * domain_bootstrap hooks on.
+ *
+ * This function should be called from within hook_enable() implementations.
+ *
+ * @param $name
+ * The name of the module that is registered.
+ * @param $weight
+ * The weight of the module as an integer number. The default value is the
+ * respective value from the {system} table. Optional.
+ */
+function domain_bootstrap_register($name, $weight=NULL) {
+  // load old list of modules
+  $modules = _domain_bootstrap_modules_get();
+
+  // if $weight is not an integer load the weight from the {system} table.
+  if (!is_integer($weight)) {
+    $weight = db_result(db_query("SELECT weight FROM {system} WHERE name = '%s'", $name));
+  }
+
+  // update/add the module and its weight:
+  $modules[$weight.'-'.$name] = $name;
+
+  // and store the new list of modules.
+  _domain_bootstrap_modules_set($modules);
+}
+
+/**
+ * Removes a module so it is not loaded during domain_bootstrap anymore.
+ *
+ * This function should be called from within hook_disable() implementations.
+ *
+ * @param $name
+ * The name of the module that is un-registered.
+ */
+function domain_bootstrap_unregister($name) {
+  $modules = _domain_bootstrap_modules_get();
+  if (is_array($modules)) {
+    foreach($modules as $k => $v){
+      if ($v == $name) {
+        unset($modules[$k]);
+      }
+    }
+  }
+  _domain_bootstrap_modules_set($modules);
+}
+
+/**
+ * Returns a list of modules which are loaded during domain_bootstrap phases and
+ * called respective hooks on.
+ *
+ * The domain module is always in the list of modules and has weight -99 so it
+ * should usually be first one as well.
+ *
+ * @param $reset
+ * If set to TRUE the cached list of modules is updated with the value from the
+ * {variable} table again. Default value is FALSE. Optional.
+ *
+ * @return
+ * An array of module names.
+ */
+function domain_bootstrap_modules($reset = FALSE) {
+  static $modules = NULL;
+
+  // if parameter is not given but $bootstrap_modules empty load modules from db
+  if ($reset || is_null($modules)) {
+    $modules = _domain_bootstrap_modules_get();
+    if (!is_array($modules)) {
+      $modules = Array();
+    }
+    if (!in_array('domain', $modules)) {
+      $modules['-99-domain'] = 'domain';
+    }
+    ksort($modules);
+  }
+
+  return $modules;
+}
+
+/**
+ * Tries to load all domain bootstrap modules (see _domain_bootstrap_modules()).
+ */
+function _domain_bootstrap_modules_load() {
+  $modules = domain_bootstrap_modules();
+
+  foreach ($modules as $module) {
+    drupal_load('module', $module);
+  }
+}
+
+/**
+ * Retrieves the value of the variable 'domain_bootstrap_modules' from the
+ * {variable} table. This function does not use Drupal's variable system.
+ *
+ * @return
+ * An array containing module names. (The keys are combined from module weight
+ * and module name and used for sorting during domain_bootstrap_modules().)
+ */
+function _domain_bootstrap_modules_get() {
+  $key = 'domain_bootstrap_modules';
+  $conf[$key] = unserialize(db_result(db_query("SELECT value FROM {variable} WHERE name = '%s'", $key)));
+  return $conf[$key];
+}
+
+/**
+ * Set variable 'domain_bootstrap_modules' to given value.
+ *
+ * This function does not use drupal's variable system calls because they are not
+ * yet available in all cases.
+ *
+ * @param $modules
+ * An array containing module names. The keys should be of the format
+ * {weight}-{module-name} to allow easy sorting by module weight later.
+ */
+function _domain_bootstrap_modules_set($modules = NULL){
+  $key = 'domain_bootstrap_modules';
+
+  if (!is_array($modules)) {
+    $modules = array();
+  }
+
+  $serialized_value = serialize($modules);
+  db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $key);
+  if (!db_affected_rows()) {
+    db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $key, $serialized_value);
+  }
+
+  $conf[$key] = $modules;
+}
+
+/**
+ * Removes all disabled or not installed modules from the
+ * 'domain_bootstrap_modules' variable.
+ */
+function domain_bootstrap_modules_cleanup() {
+  $modules = _domain_bootstrap_modules_get();
+  foreach($modules as $k => $name) {
+    $status = db_result(db_query("SELECT status FROM {system} WHERE name = '%s'", $name));
+    if (!$status) {
+      unset($modules[$k]);
+    }
+  }
+  _domain_bootstrap_modules_set($modules);
+}
+
+/**
+ * Tries to call specified hook on all domain_bootstrap modules.
+ *
+ * The hook function names are of the following format:
+ * {$module}_domain_bootstrap_{$hook}
+ * where {$module} is the name of the module implementing the hook and {$hook}
+ * is the identifier for the concrete domain bootstrap hook.
+ *
+ * This function is basically a copy of module_invoke_all() adjusted to our
+ * needs.
+ *
+ * @param $hook
+ * The name of the bootstrap hook to invoke.
+ *
+ * @link http://api.drupal.org/api/function/module_invoke_all/6
+ */
+function _domain_bootstrap_invoke_all() {
+  $args = func_get_args();
+  $hook = $args[0];
+  unset($args[0]);
+  $return = array();
+  foreach (domain_bootstrap_modules() as $module) {
+    $function = $module . '_domain_bootstrap_' . $hook;
+    if (function_exists($function)) {
+      $result = call_user_func_array($function, $args);
+      if (isset($result) && is_array($result)) {
+        $return = array_merge_recursive($return, $result);
+      } else if (isset($result)) {
+        $return[] = $result;
+      }
+    }
+  }
+
+  return $return;
+}
+
+/**
+ * Tries to match the current (host) domainname to a domain in the {domain}
+ * table and returns a respective domain_id.
+ *
+ * @param $_domainname
+ * The domainname to match against. Optional.
+ *
+ * @return
+ * An array containing a domain_id matching the current domainname.
+ */
+function domain_resolve_host($_domainname = "") {
+  if (empty($_domainname)) {
+    $_domainname = domain_current_domainname();
+  }
+
+  return _domain_lookup_simple($_domainname);
+}
+
+/**
+ * Determines current fully qualified domainname.
+ *
+ * @return
+ * The current (host) domainname as a String.
+ */
+function domain_current_domainname() {
+  // We lower case this, since EXAMPLE.com == example.com.
+  return strtolower(rtrim($_SERVER['HTTP_HOST']));
+}
+
+/**
+ * Determines a domain_id matching given $_domainname.
+ *
+ * This function runs a lookup against the {domain} table matching the
+ * subdomain column against the given parameter $_domainname. If a match is
+ * found the function returns an array containing the subdomain (= $_domainname)
+ * and the matching domain_id from the {domain} table.
+ *
+ * If no match is found domain_id is set to 0 for the default domain.
+ *
+ * During the process hook_domain_bootstrap_lookup() is invoked to allow other
+ * modules to modify that result.
+ *
+ * @param $domainname
+ * The string representation of a {domain} entry.
+ *
+ * @param $reset
+ * Set TRUE to ignore cached versions and look the name up again. Optional.
+ *
+ * @return
+ * An array containing a domain_id from {domain} matching the given domainname
+ */
+function _domain_lookup_simple($_domainname, $reset = false) {
+  static $cache = array();
+
+  if (empty($_domainname)) return 0;
+
+  if ($reset || !isset($cache[$_domainname])) {
+    // Lookup the given domainname against our allowed hosts record.
+    $domain = db_fetch_array(db_query_range("SELECT domain_id FROM {domain} WHERE subdomain = '%s' ", $_domainname, 0, 1));
+
+    if (!is_array($domain)) {
+      $domain = array();
+    }
+
+    $domain['subdomain'] = $_domainname;
+    // invoke hook_domain_bootstrap_lookup()
+    $domain_new = _domain_bootstrap_invoke_all('lookup', $domain);
+    if (is_array($domain_new)) {
+      $domain = array_merge($domain, $domain_new);
+    }
+    // no match => use default (0)
+    if (!isset($domain['domain_id'])) {
+      $domain['domain_id'] = 0;
+    }
+
+    $cache[$_domainname] = $domain;
+  }
+  return $cache[$_domainname];
+}
Index: domain.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/domain.module,v
retrieving revision 1.67
diff -u -p -r1.67 domain.module
--- domain.module	17 Sep 2008 17:35:26 -0000	1.67
+++ domain.module	17 Sep 2008 17:50:04 -0000
@@ -32,41 +32,34 @@ define('DOMAIN_EDITOR_RULE', FALSE);
 define('DOMAIN_SITE_GRANT', TRUE);
 
 /**
- * Implements hook_init()
+ * Implementation of hook_init().
  *
- * Inititalizes a global $_domain variable and set it based on the
- * third-level domain used to access the page.
- */
+ * Inititalizes a global $_domain variable if necessary (usually that's done in
+ * domain_bootstrap.inc) and loads information on current domain.
+ *
+ * Also handles www stripping, checks the validity of user domains and updates
+ * $conf['site_name'].
+*/
 function domain_init() {
   global $_domain, $conf;
-  $_domain = array();
-  // We lower case this, since EXAMPLE.com == example.com.
-  $_subdomain = strtolower(rtrim($_SERVER['HTTP_HOST']));
 
-  // Strip the www. off the subdomain, if required by the module settings.
-  $raw_domain = $_subdomain;
-  if (variable_get('domain_www', 0)) {
-    $_subdomain = str_replace('www.', '', $_subdomain);
-  }
-  // Lookup the active domain against our allowed hosts record.
-  $data = db_fetch_array(db_query("SELECT domain_id FROM {domain} WHERE subdomain = '%s'", $_subdomain));
-  // Get the domain data.
-  $_domain = domain_lookup($data['domain_id']);
+  // if $_domain is empty start domain bootstrap (by including settings.inc)
+  if (!isset($_domain['domain_id'])) {
+    include drupal_get_path('module', 'domain') .'/settings.inc';
+  }
 
-  // If return is -1, then the DNS didn't match anything, so use defaults.
-  if ($_domain == -1) {
-    $_domain = domain_default();
-    // If the request was not for the primary domain, send the user there.  See http://drupal.org/node/293453.
-    if (!empty($_domain['subdomain']) && $_subdomain != $_domain['subdomain']) {
-      $request = domain_get_uri($_domain);
-      drupal_set_message(t('You have followed an incorrect link to this website.  Please update your links and bookmarks to <a href="!url">!url</a>.', array('!url' => $request)));
-      drupal_goto($request);
-    }
+  // Strip the www. off the subdomain, if required by the module settings.
+  if (variable_get('domain_www', 0) && strpos($_domain['subdomain'], 'www.') !== FALSE) {
+    $_domain['subdomain'] = str_replace('www.', '', $_domain['subdomain']);
+    $www_replaced = TRUE;
   }
 
-  // If we stripped the www. send the user to the proper domain.  This should only
-  // happen once, on an inbound link or typed URL, so the overhead is acceptable.
-  if ($raw_domain != $_subdomain) {
+  // add information from domain_lookup but keep existing values (domain_id and subdomain)
+  $domain = domain_lookup($_domain['domain_id']);
+  $_domain = array_merge($domain, $_domain);
+
+  // If we have replaced 'www.' in the url, redirect to the clean domain.
+  if ($www_replaced) {
     drupal_goto(domain_get_uri($_domain));
   }
 
@@ -330,7 +323,7 @@ function domain_user($op, &$edit, &$acco
           '#weight' => 10,
           '#title' => t('Domain status'),
         );
-        // Filter out all the emoty options.
+        // Filter out all the empty options.
         $account->domain_user = array_filter($account->domain_user);
         if (empty($account->domain_user)) {
           $output = t('This user is not assiged to a domain.');
@@ -1228,6 +1221,9 @@ function domain_grant_all($reset= FALSE)
  * Implements hook_domaininstall()
  */
 function domain_domaininstall() {
+  // Cleanup list of bootstrap modules (remove disabled ones)
+  domain_bootstrap_modules_cleanup();
+
   // Check to see if the hook_url_alter() patch is installed.
   if (url('domain_access_test_path') != url('domain_access_path_test')) {
     drupal_set_message(t('The <em>custom_url_rewrite_outbound()</em> function is not installed.  Some features are not available. See the <em>custom_url_rewrite_outbound()</em> section of <a href="!url">INSTALL.txt</a>', array('!url' => base_path() . drupal_get_path('module', 'domain') .'/INSTALL.txt')));
Index: settings.inc
===================================================================
RCS file: settings.inc
diff -N settings.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ settings.inc	17 Sep 2008 17:50:04 -0000
@@ -0,0 +1,141 @@
+<?php
+// $Id$
+/**
+ *
+ * @file
+ * settings.inc
+ *
+ * This file should be included at the bottom of your settings.php file:
+ * <?php
+ * include '/sites/all/modules/domain/settings.inc';
+ * ?>
+ * If you have installed the domain module into a different folder than
+ * /sites/all/modules/domain please adjust the path approriately.
+ *
+ * @ingroup domain
+ */
+
+/**
+ * Include bootstrap file, setup checker function and start bootstrap phases.
+ */
+include 'domain.bootstrap.inc';
+domain_settings_setup_ok();
+domain_bootstrap();
+
+/**
+ * Small helper function to determine whether this file was included correctly in
+ * the user's settings.php
+ *
+ * If it was included at the right time then cache.inc shouldn't be included
+ * yet and the function 'cache_get' not be defined.
+ *
+ * When the function is called first (from within this file) the state is saved
+ * in a static variable, every later call will return that boolean value.
+ *
+ * @return
+ * TRUE if settings.inc was included correctly in settings.php, else FALSE
+ */
+function domain_settings_setup_ok() {
+  static $state = NULL;
+  if ($state === NULL) {
+    $state = !function_exists('cache_get');
+  }
+  return $state;
+}
+
+/**
+ * Implements custom_url_rewrite_outbound().
+ * Forces absolute paths for domains when needed.
+ */
+function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
+  global $_domain;
+
+  // If the domain_id is not set, then the Domain module is not active, and we cannot run this function.
+  if (isset($_domain['domain_id'])) {
+    // Set static variables for the node lookups, to remove redundant queries.
+    static $domain_site, $domain, $nodepaths;
+
+    // Check to see that this function is installed.
+    $skip = FALSE;
+    $arg = arg(0);
+    if ($arg == 'admin' && ($path == 'domain_access_test_path' || $path == 'domain_access_path_test')) {
+      $path = 'yes';
+      $skip = TRUE;
+    }
+
+    // This routine only needs to be run from certain urls or if we want to
+    // force all links to go to a single domain for SEO.
+    // See http://drupal.org/node/195366 for the background.
+    $check = domain_grant_all();
+    $seo = variable_get('domain_seo', 0);
+    // If using Domain Source, we force links to a specific domain.
+    $use_source =  module_exists('domain_source');
+
+    if (!$skip && ($check || $seo || $use_source)) {
+      // Check to see if this is a node or comment link and set $nid accordingly.
+      // We static the $nid results to make this more efficient.
+      $pattern = explode('/', $original_path);
+
+      // Advanced pattern matching, we find the node id based on token %n in the path string.
+      if (!isset($nodepaths)) {
+        $pathdata = variable_get('domain_paths', "node/%n\r\nnode/%n/edit\r\ncomment/reply/%n\r\nnode/add/book/parent/%n\r\nbook/export/html/%n\r\nnode\%n\outline");
+        $path_match = preg_replace('/(\r\n?|\n)/', '|', $pathdata);
+        $nodepaths = explode("|", $path_match);
+      }
+      $nid = FALSE;
+      foreach ($nodepaths as $match) {
+        $match_array = explode('/', $match);
+        $placeholder = array_search('%n', $match_array);
+        if (isset($pattern[$placeholder])) {
+          $match_array[$placeholder] = $pattern[$placeholder];
+          if (is_numeric($pattern[$placeholder]) && $match_array == $pattern) {
+            $nid = (int) $pattern[$placeholder];
+            break;
+          }
+        }
+      }
+      // This path has matched a node id, so it may need to be rewritten.
+      if ($nid) {
+        $root = domain_lookup(variable_get('domain_default_source', 0));
+        // Remove redundancy from the domain_site check.
+        if (!isset($domain_site[$nid])) {
+          // If this check works, we don't need to rewrite the path unless SEO rules demand it.
+          $domain_site[$nid] = db_result(db_query("SELECT grant_view FROM {node_access} WHERE nid = %d AND gid = 0 AND realm = '%s'", $nid, 'domain_site'));
+        }
+        if (!$domain_site[$nid] || $use_source) {
+          // Remove rendundancy from the domain_id check.
+          if (!isset($domain[$nid])) {
+            // The Domain Source module is optional, and allows nodes to be assigned to specific domains for the
+            // purpose of this check.
+            if ($use_source) {
+              $source = db_result(db_query("SELECT domain_id FROM {domain_source} WHERE nid = %d", $nid));
+              $domain[$nid] = domain_lookup($source);
+            }
+            else {
+              // Load the domain data for this node -- but only take the first match.
+              $id = db_result(db_query_range("SELECT gid FROM {node_access} WHERE nid = %d AND realm = '%s' AND grant_view = 1 ORDER BY gid", $nid, 'domain_id', 0, 1));
+              $domain[$nid] = domain_lookup($id);
+            }
+          }
+          // Can we and do we need to rewrite this path?
+          if ($domain[$nid] != -1 && $domain[$nid]['domain_id'] != $_domain['domain_id']) {
+            $options['absolute'] = TRUE;
+            // In this case, the $base_url cannot have a trailing slash
+            $options['base_url'] = rtrim($domain[$nid]['path'], '/');
+            // Domain Source trumps the seo rules below.
+            if (isset($source)) {
+              $seo = FALSE;
+            }
+          }
+        }
+        // If strict SEO rules are enabled, we set "all affiliate" links to the root domain.
+        // Only needed if we are not on the default source domain.
+        else if ($root != -1 && $seo && $_domain['domain_id'] != $root['domain_id']) {
+          $options['absolute'] = TRUE;
+          // In this case, the $base_url cannot have a trailing slash
+          $options['base_url'] = rtrim($root['path'], '/');
+        }
+      }
+    }
+  }
+}
Index: settings_custom_url.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/settings_custom_url.inc,v
retrieving revision 1.7
diff -u -p -r1.7 settings_custom_url.inc
--- settings_custom_url.inc	6 Jul 2008 21:16:39 -0000	1.7
+++ settings_custom_url.inc	17 Sep 2008 17:50:04 -0000
@@ -10,99 +10,3 @@
  * @ingroup domain
  */
 
-/**
- * Implements custom_url_rewrite_outbound().
- * Forces absolute paths for domains when needed.
- */
-function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
-  global $_domain;
-
-  // If the domain_id is not set, then the Domain module is not active, and we cannot run this function.
-  if (isset($_domain['domain_id'])) {
-    // Set static variables for the node lookups, to remove redundant queries.
-    static $domain_site, $domain, $nodepaths;
-
-    // Check to see that this function is installed.
-    $skip = FALSE;
-    $arg = arg(0);
-    if ($arg == 'admin' && ($path == 'domain_access_test_path' || $path == 'domain_access_path_test')) {
-      $path = 'yes';
-      $skip = TRUE;
-    }
-
-    // This routine only needs to be run from certain urls or if we want to
-    // force all links to go to a single domain for SEO.
-    // See http://drupal.org/node/195366 for the background.
-    $check = domain_grant_all();
-    $seo = variable_get('domain_seo', 0);
-    // If using Domain Source, we force links to a specific domain.
-    $use_source =  module_exists('domain_source');
-
-    if (!$skip && ($check || $seo || $use_source)) {
-      // Check to see if this is a node or comment link and set $nid accordingly.
-      // We static the $nid results to make this more efficient.
-      $pattern = explode('/', $original_path);
-
-      // Advanced pattern matching, we find the node id based on token %n in the path string.
-      if (!isset($nodepaths)) {
-        $pathdata = variable_get('domain_paths', "node/%n\r\nnode/%n/edit\r\ncomment/reply/%n\r\nnode/add/book/parent/%n\r\nbook/export/html/%n\r\nnode\%n\outline");
-        $path_match = preg_replace('/(\r\n?|\n)/', '|', $pathdata);
-        $nodepaths = explode("|", $path_match);
-      }
-      $nid = FALSE;
-      foreach ($nodepaths as $match) {
-        $match_array = explode('/', $match);
-        $placeholder = array_search('%n', $match_array);
-        if (isset($pattern[$placeholder])) {
-          $match_array[$placeholder] = $pattern[$placeholder];
-          if (is_numeric($pattern[$placeholder]) && $match_array == $pattern) {
-            $nid = (int) $pattern[$placeholder];
-            break;
-          }
-        }
-      }
-      // This path has matched a node id, so it may need to be rewritten.
-      if ($nid) {
-        $root = domain_lookup(variable_get('domain_default_source', 0));
-        // Remove redundancy from the domain_site check.
-        if (!isset($domain_site[$nid])) {
-          // If this check works, we don't need to rewrite the path unless SEO rules demand it.
-          $domain_site[$nid] = db_result(db_query("SELECT grant_view FROM {node_access} WHERE nid = %d AND gid = 0 AND realm = '%s'", $nid, 'domain_site'));
-        }
-        if (!$domain_site[$nid] || $use_source) {
-          // Remove rendundancy from the domain_id check.
-          if (!isset($domain[$nid])) {
-            // The Domain Source module is optional, and allows nodes to be assigned to specific domains for the
-            // purpose of this check.
-            if ($use_source) {
-              $source = db_result(db_query("SELECT domain_id FROM {domain_source} WHERE nid = %d", $nid));
-              $domain[$nid] = domain_lookup($source);
-            }
-            else {
-              // Load the domain data for this node -- but only take the first match.
-              $id = db_result(db_query_range("SELECT gid FROM {node_access} WHERE nid = %d AND realm = '%s' AND grant_view = 1 ORDER BY gid", $nid, 'domain_id', 0, 1));
-              $domain[$nid] = domain_lookup($id);
-            }
-          }
-          // Can we and do we need to rewrite this path?
-          if ($domain[$nid] != -1 && $domain[$nid]['domain_id'] != $_domain['domain_id']) {
-            $options['absolute'] = TRUE;
-            // In this case, the $base_url cannot have a trailing slash
-            $options['base_url'] = rtrim($domain[$nid]['path'], '/');
-            // Domain Source trumps the seo rules below.
-            if (isset($source)) {
-              $seo = FALSE;
-            }
-          }
-        }
-        // If strict SEO rules are enabled, we set "all affiliate" links to the root domain.
-        // Only needed if we are not on the default source domain.
-        else if ($root != -1 && $seo && $_domain['domain_id'] != $root['domain_id']) {
-          $options['absolute'] = TRUE;
-          // In this case, the $base_url cannot have a trailing slash
-          $options['base_url'] = rtrim($root['path'], '/');
-        }
-      }
-    }
-  }
-}
Index: domain_conf/domain_conf.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/domain_conf/domain_conf.install,v
retrieving revision 1.4
diff -u -p -r1.4 domain_conf.install
--- domain_conf/domain_conf.install	26 Mar 2008 02:47:31 -0000	1.4
+++ domain_conf/domain_conf.install	17 Sep 2008 17:50:04 -0000
@@ -32,3 +32,21 @@ function domain_conf_schema() {
 function domain_conf_uninstall() {
   drupal_uninstall_schema('domain_conf');
 }
+
+/**
+ * Implementation of hook_enable().
+ *
+ * Register the domain_conf with the domain module so it's loaded during domain
+ * bootstrap and can implement domain_bootstrap hooks.
+ */
+function domain_conf_enable() {
+  domain_bootstrap_register('domain_conf');
+}
+
+/**
+ * Implementation of hook_disable().
+ */
+function domain_conf_disable() {
+  domain_bootstrap_unregister('domain_conf');
+}
+
Index: domain_conf/domain_conf.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/domain_conf/domain_conf.module,v
retrieving revision 1.25
diff -u -p -r1.25 domain_conf.module
--- domain_conf/domain_conf.module	6 Jul 2008 21:16:39 -0000	1.25
+++ domain_conf/domain_conf.module	17 Sep 2008 17:50:05 -0000
@@ -17,6 +17,51 @@
  */
 
 /**
+ * Implementation of hook_domain_bootstrap_full().
+ *
+ * Dynamic domain settings loading: Loads the settings for the current domain.
+ *
+ * This routine was in hook_init(), but there are cases where
+ * the $conf array needs to be loaded in early phases of bootstrap.
+ * In particular, these variables need to be available during variable_init().
+ *
+ * Hook hook_domain_bootstrap_full allows to execute code at domain bootstrap
+ * time which is before drupal's hook_boot() and before variable_init().
+ *
+ * In order for this to work correctly the settings.inc needs to be included
+ * in settings.php (see readme)
+ *
+ * @param $domain
+ * Array containing domain_id for current hostname
+ *
+ * @return void
+ */
+function domain_conf_domain_bootstrap_full($domain) {
+  // To work properly this function needs to be loaded before variable_init(),
+  // therefore we check that domain bootstrap was setup correctly.
+  if (!domain_settings_setup_ok()) {
+    drupal_set_message(t('The Domain module is not installed correctly. Please edit your settings.php file as described in <a href="!url">INSTALL.txt</a>', array('!url' => base_path() . drupal_get_path('module', 'domain') .'/INSTALL.txt')), 'error', FALSE);
+    return;
+  }
+  if (!is_numeric($domain['domain_id'])) {
+    drupal_set_message('Domain Configuration: domain_conf_domain_bootstrap_full, no valid id given. ', 'error');
+    return;
+  }
+  else {
+    $data = array();
+    $data = db_fetch_array(db_query("SELECT settings FROM {domain_conf} WHERE domain_id = %d", $domain['domain_id']));
+    if (!empty($data)) {
+      global $conf;
+      $settings = unserialize($data['settings']);
+      // Overwrite the $conf variables.
+      foreach ($settings as $key => $value) {
+        $conf[$key] = $value;
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_init()
  */
 function domain_conf_init() {
@@ -108,16 +153,6 @@ function domain_conf_domainwarnings() {
 }
 
 /**
- * Implements hook_domaininstall()
- */
-function domain_conf_domaininstall() {
-  // If Domain Conf is being used, check to see that it is installed correctly.
-  if (module_exists('domain_conf') && !function_exists('_domain_conf_load')) {
-    drupal_set_message(t('The Domain Configuration module is not installed correctly.  Please edit your settings.php file as described in <a href="!url">INSTALL.txt</a>', array('!url' => base_path() . drupal_get_path('module', 'domain_conf') .'/INSTALL.txt')));
-  }
-}
-
-/**
  * Implements hook_domainbatch()
  */
 function domain_conf_domainbatch() {
Index: domain_prefix/domain_prefix.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/domain_prefix/domain_prefix.install,v
retrieving revision 1.6
diff -u -p -r1.6 domain_prefix.install
--- domain_prefix/domain_prefix.install	30 Mar 2008 17:51:46 -0000	1.6
+++ domain_prefix/domain_prefix.install	17 Sep 2008 17:50:05 -0000
@@ -60,3 +60,21 @@ function domain_prefix_uninstall() {
  *
  * Developer note: the next update will be update 2.
  */
+
+/**
+ * Implementation of hook_enable().
+ *
+ * Register the domain_prefix with the domain module so it's loaded during domain
+ * bootstrap and can implement domain_bootstrap hooks.
+ */
+function domain_prefix_enable() {
+  domain_bootstrap_register('domain_prefix');
+}
+
+/**
+ * Implementation of hook_disable().
+ */
+function domain_prefix_disable() {
+  domain_bootstrap_unregister('domain_prefix');
+}
+
Index: domain_prefix/domain_prefix.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/domain/domain_prefix/domain_prefix.module,v
retrieving revision 1.20
diff -u -p -r1.20 domain_prefix.module
--- domain_prefix/domain_prefix.module	16 Aug 2008 16:28:26 -0000	1.20
+++ domain_prefix/domain_prefix.module	17 Sep 2008 17:50:05 -0000
@@ -26,6 +26,60 @@ define('DOMAIN_PREFIX_DROP', 8);
 define('DOMAIN_PREFIX_UPDATE', 16);
 
 /**
+ * Implementation of hook_domain_bootstrap_full().
+ *
+ * Dynamic domain settings loading: Loads the settings for the current domain.
+ *
+ * This routine was in hook_init(), but there are cases where
+ * the $conf array needs to be loaded in early phases of bootstrap.
+ * In particular, these variables need to be available during variable_init().
+ *
+ * Hook hook_domain_bootstrap_full allows to execute code at domain bootstrap
+ * time which is before drupal's hook_boot() and before variable_init().
+ *
+ * In order for this to work correctly settings.inc needs to be included
+ * in settings.php.
+ *
+ * @param $domain
+ * Array containing domain_id for current hostname
+ *
+ * @return void
+ */
+function domain_prefix_domain_bootstrap_full($domain) {
+  // To work properly this function needs to be loaded before variable_init(),
+  // therefore we check that domain bootstrap was setup correctly.
+  if (!domain_settings_setup_ok()) {
+    drupal_set_message(t('The Domain module is not installed correctly. Please edit your settings.php file as described in <a href="!url">INSTALL.txt</a>', array('!url' => base_path() . drupal_get_path('module', 'domain') .'/INSTALL.txt')), 'error', FALSE);
+    return;
+  }
+  else if (!is_numeric($domain['domain_id'])) {
+    drupal_set_message('Domain Prefix: domain_prefix_domain_bootstrap_full, no valid id given. ', 'error');
+    return;
+  }
+  else {
+    $tables = array();
+    $prefix = 'domain_'. $domain['domain_id'] .'_';
+    $result = db_query("SELECT tablename FROM {domain_prefix} WHERE domain_id = %d AND status > %d", $domain['domain_id'], 1);
+    while ($data = db_fetch_array($result)) {
+      $tables[] = $data['tablename'];
+    }
+    if (!empty($tables)) {
+      global $db_prefix;
+      $new_prefix = array();
+      // There might be global prefixing; if so, prepend the global.
+      if (is_string($db_prefix)) {
+        $new_prefix['default'] = $db_prefix;
+        $prefix = $db_prefix . $prefix;
+      }
+      foreach ($tables as $table) {
+        $new_prefix[$table] = $prefix;
+      }
+      $db_prefix = $new_prefix;
+    }
+  }
+}
+
+/**
  * Implements hook_menu()
  */
 function domain_prefix_menu() {
@@ -76,16 +130,6 @@ function domain_prefix_theme() {
 }
 
 /**
- * Implements hook_domaininstall()
- */
-function domain_prefix_domaininstall() {
-  // If Domain Prefix is being used, check to see that it is installed correctly.
-  if (module_exists('domain_prefix') && !function_exists('_domain_prefix_load')) {
-    drupal_set_message(t('The Domain Prefix module is not installed correctly.  Please edit your settings.php file as described in <a href="!url">INSTALL.txt</a>', array('!url' => base_path() . drupal_get_path('module', 'domain_prefix') .'/INSTALL.txt')));
-  }
-}
-
-/**
  * Implements hook_domainlinks()
  *
  * @param $domain
