Index: install.php =================================================================== RCS file: /cvs/drupal/drupal/install.php,v retrieving revision 1.125 diff -u -p -r1.125 install.php --- install.php 18 Jul 2008 07:24:29 -0000 1.125 +++ install.php 25 Jul 2008 01:13:36 -0000 @@ -45,11 +45,9 @@ function install_main() { // Load module basics (needed for hook invokes). include_once './includes/module.inc'; - $module_list['system']['filename'] = 'modules/system/system.module'; - $module_list['filter']['filename'] = 'modules/filter/filter.module'; - module_list(TRUE, FALSE, FALSE, $module_list); - drupal_load('module', 'system'); - drupal_load('module', 'filter'); + $modules = array('system', 'filter'); + variable_set('module_list', $modules, FALSE); + module_load($modules); // Set up theme system for the maintenance page. drupal_maintenance_theme(); @@ -145,6 +143,8 @@ function install_main() { variable_set('install_profile_modules', array_diff($modules, array('system'))); } + // Delete our temporary module list. + variable_del('module_list', FALSE); // The database is set up, turn to further tasks. install_tasks($profile, $task); } Index: includes/actions.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/actions.inc,v retrieving revision 1.13 diff -u -p -r1.13 actions.inc --- includes/actions.inc 29 Jun 2008 12:07:15 -0000 1.13 +++ includes/actions.inc 25 Jul 2008 01:13:36 -0000 @@ -83,7 +83,10 @@ function actions_do($action_ids, $object } // Singleton action; $action_id is the function name. else { - $result[$action_id] = $action_id($object, $context, $a1, $a2); + $function = $action_id; + } + if (drupal_function_exists($function)) { + $result[$action_id] = $function($object, $context, $a1, $a2); } } } @@ -250,7 +253,7 @@ function actions_function_lookup($hash) */ function actions_synchronize($actions_in_code = array(), $delete_orphans = FALSE) { if (!$actions_in_code) { - $actions_in_code = actions_list(); + $actions_in_code = actions_list(TRUE); } $actions_in_db = array(); $result = db_query("SELECT * FROM {actions} WHERE parameters = ''"); Index: includes/batch.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/batch.inc,v retrieving revision 1.20 diff -u -p -r1.20 batch.inc --- includes/batch.inc 24 Jun 2008 21:51:02 -0000 1.20 +++ includes/batch.inc 25 Jul 2008 01:13:36 -0000 @@ -190,7 +190,7 @@ function _batch_process() { // We assume a single pass operation and set the completion level // to 1 by default. $finished = 1; - if ((list($function, $args) = reset($current_set['operations'])) && function_exists($function)) { + if ((list($function, $args) = reset($current_set['operations'])) && drupal_function_exists($function)) { // Build the 'context' array, execute the function call, // and retrieve the user message. $batch_context = array('sandbox' => &$current_set['sandbox'], 'results' => &$current_set['results'], 'finished' => &$finished, 'message' => &$task_message); @@ -282,7 +282,7 @@ function _batch_next_set() { if (isset($batch['sets'][$batch['current_set'] + 1])) { $batch['current_set']++; $current_set =& _batch_current_set(); - if (isset($current_set['form_submit']) && ($function = $current_set['form_submit']) && function_exists($function)) { + if (isset($current_set['form_submit']) && ($function = $current_set['form_submit']) && drupal_function_exists($function)) { // We use our stored copies of $form and $form_state, to account for // possible alteration by the submit handlers. $function($batch['form'], $batch['form_state']); @@ -306,7 +306,7 @@ function _batch_finished() { if (isset($batch_set['file']) && is_file($batch_set['file'])) { include_once($batch_set['file']); } - if (function_exists($batch_set['finished'])) { + if (drupal_function_exists($batch_set['finished'])) { $batch_set['finished']($batch_set['success'], $batch_set['results'], $batch_set['operations']); } } Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.217 diff -u -p -r1.217 bootstrap.inc --- includes/bootstrap.inc 17 Jul 2008 21:10:39 -0000 1.217 +++ includes/bootstrap.inc 25 Jul 2008 01:13:36 -0000 @@ -430,10 +430,11 @@ function drupal_get_filename($type, $nam // nothing } // Verify that we have an active database connection, before querying - // the database. This is required because this function is called both + // the database. This is required because this function is called both // before we have a database connection (i.e. during installation) and - // when a database connection fails. - elseif (db_is_active() && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) { + // when a database connection fails. As this is called very, very early + // during the install process, even database.inc might not be loaded. + elseif (function_exists('db_is_active') && db_is_active() && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) { $files[$type][$name] = $file; } else { @@ -507,17 +508,21 @@ function variable_get($name, $default) { * @param $value * The value to set. This can be any PHP data type; these functions take care * of serialization as necessary. + * @param $permanent + * Whether to persist this variable value after the current request. */ -function variable_set($name, $value) { +function variable_set($name, $value, $permanent = TRUE) { global $conf; - $serialized_value = serialize($value); - db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name); - if (!db_affected_rows()) { - @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value); - } + if ($permanent) { + $serialized_value = serialize($value); + db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name); + if (!db_affected_rows()) { + @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value); + } - cache_clear_all('variables', 'cache'); + cache_clear_all('variables', 'cache'); + } $conf[$name] = $value; } @@ -527,12 +532,16 @@ function variable_set($name, $value) { * * @param $name * The name of the variable to undefine. + * @param $permanent + * If FALSE, the value will be available again on the next page load. */ -function variable_del($name) { +function variable_del($name, $permanent = TRUE) { global $conf; - db_query("DELETE FROM {variable} WHERE name = '%s'", $name); - cache_clear_all('variables', 'cache'); + if ($permanent) { + db_query("DELETE FROM {variable} WHERE name = '%s'", $name); + cache_clear_all('variables', 'cache'); + } unset($conf[$name]); } @@ -561,18 +570,6 @@ function page_get_cache() { } /** - * Call all init or exit hooks without including all modules. - * - * @param $hook - * The name of the bootstrap hook we wish to invoke. - */ -function bootstrap_invoke_all($hook) { - foreach (module_list(TRUE, TRUE) as $module) { - module_invoke($module, $hook); - } -} - -/** * Includes a file with the provided type and name. This prevents * including a theme, engine, module, etc., more than once. * @@ -580,23 +577,41 @@ function bootstrap_invoke_all($hook) { * The type of item to load (i.e. theme, theme_engine, module). * @param $name * The name of the item to load. + * @param $filename + * The name of the file to be loaded. Optional. * * @return * TRUE if the item is loaded or has already been loaded. */ -function drupal_load($type, $name) { - static $files = array(); +function drupal_load($type, $name, $filename = '') { + static $files = array(), $module_dependencies = NULL; if (isset($files[$type][$name])) { return TRUE; } - $filename = drupal_get_filename($type, $name); + if (!$filename) { + $filename = drupal_get_filename($type, $name); + } if ($filename) { include_once "./$filename"; $files[$type][$name] = TRUE; - + if ($type == 'module') { + if (!isset($dependencies)) { + $dependencies = variable_get('module_dependencies', array()); + } + if (isset($dependencies[$name])) { + foreach ($dependencies[$name] as $dependency => $dependency_filename) { + // There is no need for recursively calling back drupal_load because + // dependencies are already filled out by _module_build_dependencies. + if (!isset($files[$type][$dependency])) { + include_once "./$dependency_filename"; + $files[$type][$dependency] = TRUE; + } + } + } + } return TRUE; } @@ -677,13 +692,6 @@ function drupal_page_cache_header($cache } /** - * Define the critical hooks that force modules to always be loaded. - */ -function bootstrap_hooks() { - return array('boot', 'exit'); -} - -/** * Unserializes and appends elements from a serialized string. * * @param $obj @@ -819,7 +827,7 @@ function watchdog($type, $message, $vari ); // Call the logging hooks to log/process the message - foreach (module_implements('watchdog', TRUE) as $module) { + foreach (module_implements('watchdog') as $module) { module_invoke($module, 'watchdog', $log_message); } } @@ -956,15 +964,24 @@ function drupal_anonymous_user($session * DRUPAL_BOOTSTRAP_LANGUAGE: identify the language used on the page. * DRUPAL_BOOTSTRAP_PATH: set $_GET['q'] to Drupal path of request. * DRUPAL_BOOTSTRAP_FULL: Drupal is fully loaded, validate and fix input data. + * + * Optional. If drupal_bootstrap is called without parameters, it only + * returns the array of phases left. + * + * @return + * Array of phases left. */ -function drupal_bootstrap($phase) { +function drupal_bootstrap($phase = NULL) { 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; - while ($phase >= $phase_index && isset($phases[$phase_index])) { - $current_phase = $phases[$phase_index]; - unset($phases[$phase_index++]); - _drupal_bootstrap($current_phase); + if (isset($phase)) { + while ($phase >= $phase_index && isset($phases[$phase_index])) { + $current_phase = $phases[$phase_index]; + unset($phases[$phase_index++]); + _drupal_bootstrap($current_phase); + } } + return $phases; } function _drupal_bootstrap($phase) { @@ -1027,14 +1044,14 @@ function _drupal_bootstrap($phase) { $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'); + module_invoke_all('boot'); } // If there is a cached page, display it. if ($cache) { drupal_page_cache_header($cache); // If the skipping of the bootstrap hooks is not enforced, call hook_exit. if ($cache_mode != CACHE_AGGRESSIVE) { - bootstrap_invoke_all('exit'); + module_invoke_all('exit'); } // We are done. exit; @@ -1215,36 +1232,47 @@ function ip_address($reset = false) { * * @param $function * The name of the function to check or load. + * @param $file + * The name of the file this function belongs to. Optional. + * @param $module + * The name of the module $file belongs to. Optional. + * @param $module_filename + * The filename of the module $file belongs to. Optional. * @return - * TRUE if the function is now available, FALSE otherwise. + * $function if the function is now available, FALSE otherwise. */ -function drupal_function_exists($function) { - static $checked = array(); - - if (defined('MAINTENANCE_MODE')) { - return function_exists($function); - } +function drupal_function_exists($function, $file = '', $module = '', $module_filename = '') { + static $checked = array(), $modules = array(); - if (isset($checked[$function])) { - return $checked[$function]; - } - $checked[$function] = FALSE; - - if (function_exists($function)) { - registry_mark_code('function', $function); - $checked[$function] = TRUE; - return TRUE; - } - - $file = db_result(db_query("SELECT filename FROM {registry} WHERE name = '%s' AND type = '%s'", $function, 'function')); - if ($file) { - require_once($file); - $checked[$function] = function_exists($function); + // Is this the first time we see this function? + if (!isset($checked[$function])) { + $checked[$function] = function_exists($function) ? $function : FALSE; + // It does not exist, let's try include files. + if (!$checked[$function]) { + // If we are not given a file but have the database loaded already, + // we try to look it up. + if (!$file && !defined('MAINTENANCE_MODE') && ($result = db_fetch_object(db_query("SELECT filename, module, module_filename FROM {registry} WHERE name = '%s' AND type = 'function'", $function)))) { + $file = $result->filename; + $module_filename = $result->module_filename; + $module = $result->module; + } + // Either a $file was passed to the function or one was found in the database. + if ($file) { + // Load it. + require_once($file); + // Does it exist now? + $checked[$function] = function_exists($function) ? $function : FALSE; + // Modules are files where we store common functionality so we need to + // make sure they are loaded along with the function itself. + if ($module && $file != $module_filename) { + drupal_load('module', $module, $module_filename); + } + } + } if ($checked[$function]) { registry_mark_code('function', $function); } } - return $checked[$function]; } @@ -1331,31 +1359,6 @@ function drupal_rebuild_code_registry() } /** - * Save hook implementations cache. - * - * @param $hook - * Array with the hook name and list of modules that implement it. - * @param $write_to_persistent_cache - * Whether to write to the persistent cache. - */ -function registry_cache_hook_implementations($hook, $write_to_persistent_cache = FALSE) { - static $implementations; - - if ($hook) { - // Newer is always better, so overwrite anything that's come before. - $implementations[$hook['hook']] = $hook['modules']; - } - - if ($write_to_persistent_cache === TRUE) { - // Only write this to cache if the implementations data we are going to cache - // is different to what we loaded earlier in the request. - if ($implementations != registry_get_hook_implementations_cache()) { - cache_set('hooks', $implementations, 'cache_registry'); - } - } -} - -/** * Save the files required by the registry for this path. */ function registry_cache_path_files() { @@ -1404,22 +1407,6 @@ function registry_load_path_files($retur } /** - * registry_get_hook_implementations_cache - */ -function registry_get_hook_implementations_cache() { - static $implementations; - if ($implementations === NULL) { - if ($cache = cache_get('hooks', 'cache_registry')) { - $implementations = $cache->data; - } - else { - $implementations = array(); - } - } - return $implementations; -} - -/** * @} End of "ingroup registry". */ Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.779 diff -u -p -r1.779 common.inc --- includes/common.inc 19 Jul 2008 10:38:13 -0000 1.779 +++ includes/common.inc 25 Jul 2008 01:13:36 -0000 @@ -1482,7 +1482,8 @@ function drupal_page_footer() { module_invoke_all('exit'); - registry_cache_hook_implementations(FALSE, TRUE); + // Write the implementation cache. + module_implements(); registry_cache_path_files(); } @@ -2465,8 +2466,8 @@ function _drupal_bootstrap_full() { unicode_check(); // Undo magic quotes fix_gpc_magic(); - // Load all enabled modules - module_load_all(); + // Load all essential modules. + module_load(); // Let all modules take action before menu system handles the request // We do not want this while running update.php. if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') { @@ -3052,9 +3053,6 @@ function drupal_get_schema($table = NULL // Otherwise, rebuild the schema cache. else { $schema = array(); - // Load the .install files to get hook_schema. - module_load_all_includes('install'); - // Invoke hook_schema for all modules. foreach (module_implements('schema') as $module) { $current = module_invoke($module, 'schema'); Index: includes/file.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/file.inc,v retrieving revision 1.127 diff -u -p -r1.127 file.inc --- includes/file.inc 5 Jul 2008 18:34:29 -0000 1.127 +++ includes/file.inc 25 Jul 2008 01:13:36 -0000 @@ -585,6 +585,7 @@ function file_save_upload($source, $vali $errors = array(); foreach ($validators as $function => $args) { array_unshift($args, $file); + drupal_function_exists($function); $errors = array_merge($errors, call_user_func_array($function, $args)); } Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.282 diff -u -p -r1.282 menu.inc --- includes/menu.inc 10 Jul 2008 10:58:01 -0000 1.282 +++ includes/menu.inc 25 Jul 2008 01:13:36 -0000 @@ -454,9 +454,11 @@ function _menu_load_objects(&$item, &$ma } } array_unshift($args, $value); - $return = call_user_func_array($function, $args); + if (drupal_function_exists($function)) { + $return = call_user_func_array($function, $args); + } } - else { + elseif (drupal_function_exists($function)) { $return = $function($value); } // If callback returned an error or there is no callback, trigger 404. @@ -498,7 +500,7 @@ function _menu_check_access(&$item, $map if ($callback == 'user_access') { $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]); } - else { + elseif (drupal_function_exists($callback)) { $item['access'] = call_user_func_array($callback, $arguments); } } @@ -545,7 +547,7 @@ function _menu_item_localize(&$item, $ma $item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map)); } } - elseif ($callback) { + elseif ($callback && drupal_function_exists($callback)) { if (empty($item['title_arguments'])) { $item['title'] = $callback($item['title']); } @@ -1726,7 +1728,7 @@ function menu_router_build($reset = FALS // We need to manually call each module so that we can know which module // a given item came from. $callbacks = array(); - foreach (module_implements('menu', NULL, TRUE) as $module) { + foreach (module_implements('menu') as $module) { $router_items = call_user_func($module . '_menu'); if (isset($router_items) && is_array($router_items)) { foreach (array_keys($router_items) as $path) { Index: includes/module.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/module.inc,v retrieving revision 1.121 diff -u -p -r1.121 module.inc --- includes/module.inc 23 Jul 2008 07:34:34 -0000 1.121 +++ includes/module.inc 25 Jul 2008 01:13:36 -0000 @@ -9,67 +9,21 @@ /** * Load all the modules that have been enabled in the system table. */ -function module_load_all() { - foreach (module_list(TRUE, FALSE) as $module) { - drupal_load('module', $module); +function module_load($modules = array('node', 'user', 'filter')) { + foreach ($modules as $module) { + drupal_load('module', $module, "./modules/$module/$module.module"); } } /** - * Collect a list of all loaded modules. During the bootstrap, return only - * vital modules. See bootstrap.inc + * Collect a list of all loaded modules. * - * @param $refresh - * Whether to force the module list to be regenerated (such as after the - * administrator has changed the system settings). - * @param $bootstrap - * Whether to return the reduced set of modules loaded in "bootstrap mode" - * for cached pages. See bootstrap.inc. - * @param $sort - * By default, modules are ordered by weight and filename, settings this option - * to TRUE, module list will be ordered by module name. - * @param $fixed_list - * (Optional) Override the module list with the given modules. Stays until the - * next call with $refresh = TRUE. * @return * An associative array whose keys and values are the names of all loaded * modules. */ -function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_list = NULL) { - static $list, $sorted_list; - - if ($refresh || $fixed_list) { - unset($sorted_list); - $list = array(); - if ($fixed_list) { - foreach ($fixed_list as $name => $module) { - drupal_get_filename('module', $name, $module['filename']); - $list[$name] = $name; - } - } - else { - if ($bootstrap) { - $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, filename ASC"); - } - else { - $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, filename ASC"); - } - while ($module = db_fetch_object($result)) { - if (file_exists($module->filename)) { - drupal_get_filename('module', $module->name, $module->filename); - $list[$module->name] = $module->name; - } - } - } - } - if ($sort) { - if (!isset($sorted_list)) { - $sorted_list = $list; - ksort($sorted_list); - } - return $sorted_list; - } - return $list; +function module_list() { + return variable_get('module_list', array()); } /** @@ -112,26 +66,21 @@ function module_rebuild_cache() { // modify the data in the .info files if necessary. drupal_alter('system_info', $files[$filename]->info, $files[$filename]); - // Log the critical hooks implemented by this module. - $bootstrap = 0; - foreach (bootstrap_hooks() as $hook) { - if (module_hook($file->name, $hook)) { - $bootstrap = 1; - break; - } - } - // Update the contents of the system table: if (isset($file->status) || (isset($file->old_filename) && $file->old_filename != $file->filename)) { - db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", serialize($files[$filename]->info), $file->name, $file->filename, $bootstrap, $file->old_filename); + db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s' WHERE filename = '%s'", serialize($files[$filename]->info), $file->name, $file->filename, $file->old_filename); + if ($file->status) { + $module_list[$file->name] = $file->name; + } } else { // This is a new module. $files[$filename]->status = 0; - db_query("INSERT INTO {system} (name, info, type, filename, status, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0, $bootstrap); + db_query("INSERT INTO {system} (name, info, type, filename, status) VALUES ('%s', '%s', '%s', '%s', %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0); } } $files = _module_build_dependencies($files); + variable_set('module_list', $module_list); return $files; } @@ -154,13 +103,15 @@ function module_rebuild_cache() { * The same array with dependencies and dependents added where applicable. */ function _module_build_dependencies($files) { + $module_depencies = array(); do { $new_dependency = FALSE; - foreach ($files as $filename => $file) { - // We will modify this object (module A, see doxygen for module A, B, C). - $file = &$files[$filename]; + foreach ($files as $filename => &$file) { if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { foreach ($file->info['dependencies'] as $dependency_name) { + if ($file->status) { + $module_depencies[$file->name][$dependency_name] = $files[$dependency_name]->filename; + } // This is a nonexistent module. if ($dependency_name == '-circular-' || !isset($files[$dependency_name])) { continue; @@ -195,15 +146,14 @@ function _module_build_dependencies($fil } } } - // Don't forget to break the reference. - unset($file); } } while ($new_dependency); + variable_set('module_dependencies', $module_depencies); return $files; } /** - * Determine whether a given module exists. + * Determine whether a given module exists and load it if it does. * * @param $module * The name of the module (without the .module extension). @@ -212,7 +162,10 @@ function _module_build_dependencies($fil */ function module_exists($module) { $list = module_list(); - return isset($list[$module]); + if (isset($list[$module])) { + drupal_load('module', $module); + return TRUE; + } } /** @@ -252,17 +205,6 @@ function module_load_include($type, $mod } /** - * Load an include file for each of the modules that have been enabled in - * the system table. - */ -function module_load_all_includes($type, $name = NULL) { - $modules = module_list(); - foreach ($modules as $module) { - module_load_include($type, $module, $name); - } -} - -/** * Enable a given list of modules. * * @param $module_list @@ -273,7 +215,6 @@ function module_enable($module_list) { foreach ($module_list as $module) { $existing = db_fetch_object(db_query("SELECT status FROM {system} WHERE type = '%s' AND name = '%s'", 'module', $module)); if ($existing->status == 0) { - module_load_install($module); db_query("UPDATE {system} SET status = %d WHERE type = '%s' AND name = '%s'", 1, 'module', $module); drupal_load('module', $module); $invoke_modules[] = $module; @@ -281,8 +222,6 @@ function module_enable($module_list) { } if (!empty($invoke_modules)) { - // Refresh the module list to include the new enabled module. - module_list(TRUE, FALSE); // Force to regenerate the stored list of hook implementations. drupal_rebuild_code_registry(); } @@ -314,7 +253,6 @@ function module_disable($module_list) { node_access_needs_rebuild(TRUE); } - module_load_install($module); module_invoke($module, 'disable'); db_query("UPDATE {system} SET status = %d WHERE type = '%s' AND name = '%s'", 0, 'module', $module); $invoke_modules[] = $module; @@ -322,8 +260,6 @@ function module_disable($module_list) { } if (!empty($invoke_modules)) { - // Refresh the module list to exclude the disabled modules. - module_list(TRUE, FALSE); // Force to regenerate the stored list of hook implementations. drupal_rebuild_code_registry(); } @@ -368,13 +304,7 @@ function module_disable($module_list) { * implemented in that module. */ function module_hook($module, $hook) { - $function = $module . '_' . $hook; - if (defined('MAINTENANCE_MODE')) { - return function_exists($function); - } - else { - return drupal_function_exists($function); - } + return drupal_function_exists($module . '_' . $hook); } /** @@ -382,9 +312,6 @@ function module_hook($module, $hook) { * * @param $hook * The name of the hook (e.g. "help" or "menu"). - * @param $sort - * By default, modules are ordered by weight and filename, settings this option - * to TRUE, module list will be ordered by module name. * @param $refresh * For internal use only: Whether to force the stored list of hook * implementations to be regenerated (such as after enabling a new module, @@ -392,25 +319,64 @@ function module_hook($module, $hook) { * @return * An array with the names of the modules which are implementing this hook. */ -function module_implements($hook, $sort = FALSE, $refresh = FALSE) { - static $implementations = array(); +function module_implements($hook = '', $refresh = FALSE) { + static $implementations = array(), $loaded = array(), $cache; - if ($refresh) { + // If we are in maintenance mode but managed to bootstrap fully then we can + // use the registry. + if (defined('MAINTENANCE_MODE') && drupal_bootstrap()) { $implementations = array(); - } - else if (!defined('MAINTENANCE_MODE') && empty($implementations)) { - $implementations = registry_get_hook_implementations_cache(); - } - - if (!isset($implementations[$hook])) { - $implementations[$hook] = array(); foreach (module_list() as $module) { if (module_hook($module, $hook)) { - $implementations[$hook][] = $module; + $implementations[] = $module; + } + } + return $implementations; + } + if ($refresh) { + $implementations = array(); + $loaded = array(); + cache_clear_all('hooks', 'cache_registry'); + return; + } + if (!$hook) { + // Only write this to cache if the implementations data we are going to cache + // is different to what we loaded earlier in the request. + if ($cache && $implementations != $cache->data) { + cache_set('hooks', $implementations, 'cache_registry'); + } + return; + } + + if (empty($implementations) && ($cache = cache_get('hooks', 'cache_registry'))) { + $implementations = $cache->data; + } + + if (empty($loaded[$hook])) { + if (isset($implementations[$hook])) { + $cached = TRUE; + // $candidate_list holds the possible implementations. + foreach ($implementations[$hook] as $module) { + $function = $module .'_'. $hook; + // If the implementations are already cached but there are functions + // to be looked up, then we discard the cache. The per router path + // caching will make this rare. + if (!function_exists($function)) { + unset($implementations[$hook]); + break; + } + } + } + if (!isset($implementations[$hook])) { + $implementations[$hook] = array(); + $result = db_query("SELECT name, filename, module, module_filename FROM {registry} WHERE type = 'function' AND hook = '%s'", $hook); + while ($function = db_fetch_object($result)) { + $implementations[$hook][] = $function->module; + drupal_function_exists($function->name, $function->filename, $function->module, $function->module_filename); } } + $loaded[$hook] = TRUE; } - registry_cache_hook_implementations(array('hook' => $hook, 'modules' => $implementations[$hook])); // The explicit cast forces a copy to be made. This is needed because // $implementations[$hook] is only a reference to an element of Index: includes/registry.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/registry.inc,v retrieving revision 1.1 diff -u -p -r1.1 registry.inc --- includes/registry.inc 6 May 2008 12:32:02 -0000 1.1 +++ includes/registry.inc 25 Jul 2008 01:13:36 -0000 @@ -23,6 +23,10 @@ * @See drupal_rebuild_code_registry. */ function _drupal_rebuild_code_registry() { + include_once './includes/module.inc'; + include_once './includes/common.inc'; + include_once './includes/file.inc'; + drupal_load('module', 'system', 'modules/system/system.module'); // Reset the resources cache. _registry_get_resource_name(); // Get the list of files we are going to parse. @@ -31,7 +35,7 @@ function _drupal_rebuild_code_registry() if ($module->status) { $dir = dirname($module->filename); foreach ($module->info['files'] as $file) { - $files["./$dir/$file"] = array(); + $files["./$dir/$file"] = array('module' => $module); } } } @@ -53,6 +57,7 @@ function _drupal_rebuild_code_registry() } _registry_parse_files($files); + module_implements('', TRUE); cache_clear_all('*', 'cache_registry'); } @@ -72,7 +77,7 @@ function registry_get_parsed_files() { * Parse all files that have changed since the registry was last built, and save their function and class listings. * * @param $files - * The list of files to check and parse. + * The list of files to check and parse. */ function _registry_parse_files($files) { $changed_files = array(); @@ -83,7 +88,7 @@ function _registry_parse_files($files) { if ($new_file || $md5 != $file['md5']) { // We update the md5 after we've saved the files resources rather than here, so if we // don't make it through this rebuild, the next run will reparse the file. - _registry_parse_file($filename, $contents); + _registry_parse_file($filename, $contents, $file); $file['md5'] = $md5; if ($new_file) { db_query("INSERT INTO {registry_file} (md5, filename) VALUES ('%s', '%s')", $md5, $filename); @@ -99,11 +104,14 @@ function _registry_parse_files($files) { * Parse a file and save its function and class listings. * * @param $filename - * Name of the file we are going to parse. + * Name of the file we are going to parse. * @param $contents - * Contents of the file we are going to parse as a string. + * Contents of the file we are going to parse as a string. + * @param $file + * An array of information about the file. If key 'module' is present, it's + * a stdClass as returned by module_rebuild_cache. */ -function _registry_parse_file($filename, $contents) { +function _registry_parse_file($filename, $contents, $file = array()) { static $map = array(T_FUNCTION => 'function', T_CLASS => 'class', T_INTERFACE => 'interface'); // Delete registry entries for this file, so we can insert the new resources. db_query("DELETE FROM {registry} WHERE filename = '%s'", $filename); @@ -113,7 +121,18 @@ function _registry_parse_file($filename, if (is_array($token) && isset($map[$token[0]])) { $type = $map[$token[0]]; if ($resource_name = _registry_get_resource_name($tokens, $type)) { - db_query("INSERT INTO {registry} (name, type, filename) VALUES ('%s', '%s', '%s')", $resource_name, $type, $filename); + $hook = ''; + $module = ''; + $module_filename = ''; + if ($type == 'function' && isset($file['module'])) { + $module = $file['module']->name; + $module_filename = $file['module']->filename; + $n = strlen($module); + if (substr($resource_name, 0, $n) == $module) { + $hook = substr($resource_name, $n + 1); + } + } + db_query("INSERT INTO {registry} (name, type, filename, module_filename, module, hook) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')", $resource_name, $type, $filename, $module_filename, $module, $hook); // We skip the body because classes may contain functions. _registry_skip_body($tokens); } @@ -127,11 +146,11 @@ function _registry_parse_file($filename, * When called without arguments, it resets its static cache. * * @param $tokens - * The collection of tokens for the current file being parsed. + * The collection of tokens for the current file being parsed. * @param $type - * The human-readable token name, either: "function", "class", or "interface". + * The human-readable token name, either: "function", "class", or "interface". * @return - * The name of the resource, or FALSE if the resource has already been processed. + * The name of the resource, or FALSE if the resource has already been processed. */ function _registry_get_resource_name(&$tokens = NULL, $type = NULL) { // Keep a running list of all resources we've saved so far, so that we never @@ -166,6 +185,7 @@ function _registry_get_resource_name(&$t * of { from the current position. * * @param $tokens + * Array of tokens as returned by token_get_all. */ function _registry_skip_body(&$tokens) { $num_braces = 1; Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.430 diff -u -p -r1.430 theme.inc --- includes/theme.inc 11 Jul 2008 02:23:08 -0000 1.430 +++ includes/theme.inc 25 Jul 2008 01:13:36 -0000 @@ -277,7 +277,7 @@ function drupal_rebuild_theme_registry() */ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { $function = $name . '_theme'; - if (function_exists($function)) { + if (drupal_function_exists($function)) { $result = $function($cache, $type, $theme, $path); foreach ($result as $hook => $info) { @@ -1596,7 +1596,7 @@ function theme_closure($main = 0) { function theme_blocks($region) { $output = ''; - if ($list = block_list($region)) { + if ($list = module_invoke('block', 'list', $region)) { foreach ($list as $key => $block) { // $key == module_delta $output .= theme('block', $block); Index: modules/aggregator/aggregator.info =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.info,v retrieving revision 1.7 diff -u -p -r1.7 aggregator.info --- modules/aggregator/aggregator.info 15 May 2008 21:27:32 -0000 1.7 +++ modules/aggregator/aggregator.info 25 Jul 2008 01:13:36 -0000 @@ -8,3 +8,4 @@ core = 7.x files[] = aggregator.module files[] = aggregator.admin.inc files[] = aggregator.pages.inc +files[] = aggregator.install Index: modules/block/block.info =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.info,v retrieving revision 1.7 diff -u -p -r1.7 block.info --- modules/block/block.info 15 May 2008 21:30:02 -0000 1.7 +++ modules/block/block.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ version = VERSION core = 7.x files[] = block.module files[] = block.admin.inc +files[] = block.install Index: modules/blogapi/blogapi.info =================================================================== RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.info,v retrieving revision 1.7 diff -u -p -r1.7 blogapi.info --- modules/blogapi/blogapi.info 13 May 2008 18:13:43 -0000 1.7 +++ modules/blogapi/blogapi.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ package = Core - optional version = VERSION core = 7.x files[] = blogapi.module +files[] = blogapi.install Index: modules/book/book.info =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.info,v retrieving revision 1.8 diff -u -p -r1.8 book.info --- modules/book/book.info 15 May 2008 21:19:24 -0000 1.8 +++ modules/book/book.info 25 Jul 2008 01:13:36 -0000 @@ -8,3 +8,4 @@ core = 7.x files[] = book.module files[] = book.admin.inc files[] = book.pages.inc +files[] = book.install Index: modules/color/color.info =================================================================== RCS file: /cvs/drupal/drupal/modules/color/color.info,v retrieving revision 1.7 diff -u -p -r1.7 color.info --- modules/color/color.info 19 May 2008 19:36:41 -0000 1.7 +++ modules/color/color.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ package = Core - optional version = VERSION core = 7.x files[] = color.module +files[] = color.install Index: modules/contact/contact.info =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.info,v retrieving revision 1.6 diff -u -p -r1.6 contact.info --- modules/contact/contact.info 6 May 2008 12:18:47 -0000 1.6 +++ modules/contact/contact.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = contact.module files[] = contact.admin.inc files[] = contact.pages.inc +files[] = contact.install Index: modules/dblog/dblog.info =================================================================== RCS file: /cvs/drupal/drupal/modules/dblog/dblog.info,v retrieving revision 1.4 diff -u -p -r1.4 dblog.info --- modules/dblog/dblog.info 6 May 2008 12:18:47 -0000 1.4 +++ modules/dblog/dblog.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ version = VERSION core = 7.x files[] = dblog.module files[] = dblog.admin.inc +files[] = dblog.install Index: modules/filter/filter.info =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.info,v retrieving revision 1.6 diff -u -p -r1.6 filter.info --- modules/filter/filter.info 6 May 2008 12:18:47 -0000 1.6 +++ modules/filter/filter.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = filter.module files[] = filter.admin.inc files[] = filter.pages.inc +files[] = filter.install Index: modules/forum/forum.info =================================================================== RCS file: /cvs/drupal/drupal/modules/forum/forum.info,v retrieving revision 1.8 diff -u -p -r1.8 forum.info --- modules/forum/forum.info 6 May 2008 12:18:47 -0000 1.8 +++ modules/forum/forum.info 25 Jul 2008 01:13:36 -0000 @@ -9,3 +9,4 @@ core = 7.x files[] = forum.module files[] = forum.admin.inc files[] = forum.pages.inc +files[] = forum.install Index: modules/help/help.module =================================================================== RCS file: /cvs/drupal/drupal/modules/help/help.module,v retrieving revision 1.81 diff -u -p -r1.81 help.module --- modules/help/help.module 6 May 2008 12:18:47 -0000 1.81 +++ modules/help/help.module 25 Jul 2008 01:13:36 -0000 @@ -17,7 +17,7 @@ function help_menu() { 'weight' => 9, ); - foreach (module_implements('help', TRUE) as $module) { + foreach (module_implements('help') as $module) { $items['admin/help/' . $module] = array( 'title' => $module, 'page callback' => 'help_page', Index: modules/locale/locale.info =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.info,v retrieving revision 1.8 diff -u -p -r1.8 locale.info --- modules/locale/locale.info 6 May 2008 12:18:48 -0000 1.8 +++ modules/locale/locale.info 25 Jul 2008 01:13:36 -0000 @@ -5,3 +5,4 @@ package = Core - optional version = VERSION core = 7.x files[] = locale.module +files[] = locale.install Index: modules/menu/menu.info =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.info,v retrieving revision 1.6 diff -u -p -r1.6 menu.info --- modules/menu/menu.info 6 May 2008 12:18:48 -0000 1.6 +++ modules/menu/menu.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ version = VERSION core = 7.x files[] = menu.module files[] = menu.admin.inc +files[] = menu.install Index: modules/node/node.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v retrieving revision 1.24 diff -u -p -r1.24 node.admin.inc --- modules/node/node.admin.inc 19 Jul 2008 19:04:24 -0000 1.24 +++ modules/node/node.admin.inc 25 Jul 2008 01:13:36 -0000 @@ -528,7 +528,7 @@ function node_admin_nodes_submit($form, $operation = $operations[$form_state['values']['operation']]; // Filter out unchecked nodes $nodes = array_filter($form_state['values']['nodes']); - if ($function = $operation['callback']) { + if (($function = $operation['callback']) && drupal_function_exists($function)) { // Add in callback arguments if present. if (isset($operation['callback arguments'])) { $args = array_merge(array($nodes), $operation['callback arguments']); Index: modules/node/node.info =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.info,v retrieving revision 1.6 diff -u -p -r1.6 node.info --- modules/node/node.info 6 May 2008 12:18:48 -0000 1.6 +++ modules/node/node.info 25 Jul 2008 01:13:36 -0000 @@ -8,3 +8,4 @@ files[] = node.module files[] = content_types.inc files[] = node.admin.inc files[] = node.pages.inc +files[] = node.install Index: modules/openid/openid.info =================================================================== RCS file: /cvs/drupal/drupal/modules/openid/openid.info,v retrieving revision 1.4 diff -u -p -r1.4 openid.info --- modules/openid/openid.info 6 May 2008 12:18:48 -0000 1.4 +++ modules/openid/openid.info 25 Jul 2008 01:13:36 -0000 @@ -8,3 +8,4 @@ files[] = openid.module files[] = openid.inc files[] = openid.pages.inc files[] = xrds.inc +files[] = openid.install Index: modules/php/php.info =================================================================== RCS file: /cvs/drupal/drupal/modules/php/php.info,v retrieving revision 1.4 diff -u -p -r1.4 php.info --- modules/php/php.info 6 May 2008 12:18:48 -0000 1.4 +++ modules/php/php.info 25 Jul 2008 01:13:36 -0000 @@ -5,3 +5,4 @@ package = Core - optional version = VERSION core = 7.x files[] = php.module +files[] = php.install Index: modules/poll/poll.info =================================================================== RCS file: /cvs/drupal/drupal/modules/poll/poll.info,v retrieving revision 1.6 diff -u -p -r1.6 poll.info --- modules/poll/poll.info 6 May 2008 12:18:49 -0000 1.6 +++ modules/poll/poll.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ version = VERSION core = 7.x files[] = poll.module files[] = poll.pages.inc +files[] = poll.install Index: modules/profile/profile.info =================================================================== RCS file: /cvs/drupal/drupal/modules/profile/profile.info,v retrieving revision 1.6 diff -u -p -r1.6 profile.info --- modules/profile/profile.info 6 May 2008 12:18:49 -0000 1.6 +++ modules/profile/profile.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = profile.module files[] = profile.admin.inc files[] = profile.pages.inc +files[] = profile.install Index: modules/search/search.info =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.info,v retrieving revision 1.6 diff -u -p -r1.6 search.info --- modules/search/search.info 6 May 2008 12:18:49 -0000 1.6 +++ modules/search/search.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = search.module files[] = search.admin.inc files[] = search.pages.inc +files[] = search.install Index: modules/simpletest/simpletest.info =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.info,v retrieving revision 1.2 diff -u -p -r1.2 simpletest.info --- modules/simpletest/simpletest.info 6 May 2008 12:18:50 -0000 1.2 +++ modules/simpletest/simpletest.info 25 Jul 2008 01:13:36 -0000 @@ -5,3 +5,4 @@ package = Core - optional version = VERSION core = 7.x files[] = simpletest.module +files[] = simpletest.install Index: modules/statistics/statistics.info =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.info,v retrieving revision 1.6 diff -u -p -r1.6 statistics.info --- modules/statistics/statistics.info 6 May 2008 12:18:50 -0000 1.6 +++ modules/statistics/statistics.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = statistics.module files[] = statistics.admin.inc files[] = statistics.pages.inc +files[] = statistics.install Index: modules/system/system.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v retrieving revision 1.82 diff -u -p -r1.82 system.admin.inc --- modules/system/system.admin.inc 23 Jul 2008 07:37:06 -0000 1.82 +++ modules/system/system.admin.inc 25 Jul 2008 01:13:36 -0000 @@ -40,7 +40,7 @@ function system_main_admin_page($arg = N } $block = $item; $block['content'] = ''; - if ($item['block_callback'] && function_exists($item['block_callback'])) { + if ($item['block_callback'] && drupal_function_exists($item['block_callback'])) { $function = $item['block_callback']; $block['content'] .= $function(); } Index: modules/system/system.info =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.info,v retrieving revision 1.7 diff -u -p -r1.7 system.info --- modules/system/system.info 8 Jul 2008 01:08:15 -0000 1.7 +++ modules/system/system.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = system.module files[] = system.admin.inc files[] = image.gd.inc +files[] = system.install Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.256 diff -u -p -r1.256 system.install --- modules/system/system.install 1 Jul 2008 20:36:40 -0000 1.256 +++ modules/system/system.install 25 Jul 2008 01:13:36 -0000 @@ -1083,6 +1083,24 @@ function system_schema() { 'length' => 255, 'not null' => TRUE, ), + 'module_filename' => array( + 'description' => t('The filename of the module this file belongs to.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), + 'module' => array( + 'description' => t('The name of the module this file belongs to.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), + 'hook' => array( + 'description' => t('The hook this function could implement, if any.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), ), 'primary key' => array('name', 'type'), ); @@ -2919,16 +2937,19 @@ function system_update_7006() { db_drop_field($ret, 'menu_router', 'file'); $schema['registry'] = array( 'fields' => array( - 'name' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), - 'type' => array('type' => 'varchar', 'length' => 9, 'not null' => TRUE, 'default' => ''), - 'filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'name' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'type' => array('type' => 'varchar', 'length' => 9, 'not null' => TRUE, 'default' => ''), + 'filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'module_filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'module' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'hook' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), ), 'primary key' => array('name', 'type'), ); $schema['registry_file'] = array( 'fields' => array( - 'filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), - 'md5' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'filename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'md5' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), ), 'primary key' => array('filename'), ); Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.611 diff -u -p -r1.611 system.module --- modules/system/system.module 23 Jul 2008 07:37:06 -0000 1.611 +++ modules/system/system.module 25 Jul 2008 01:13:36 -0000 @@ -1658,7 +1658,7 @@ function system_actions_configure($form_ function system_actions_configure_validate($form, $form_state) { $function = actions_function_lookup($form_state['values']['actions_action']) . '_validate'; // Hand off validation to the action. - if (function_exists($function)) { + if (drupal_function_exists($function)) { $function($form, $form_state); } } Index: modules/taxonomy/taxonomy.info =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.info,v retrieving revision 1.6 diff -u -p -r1.6 taxonomy.info --- modules/taxonomy/taxonomy.info 6 May 2008 12:18:51 -0000 1.6 +++ modules/taxonomy/taxonomy.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = taxonomy.module files[] = taxonomy.admin.inc files[] = taxonomy.pages.inc +files[] = taxonomy.install Index: modules/trigger/trigger.info =================================================================== RCS file: /cvs/drupal/drupal/modules/trigger/trigger.info,v retrieving revision 1.3 diff -u -p -r1.3 trigger.info --- modules/trigger/trigger.info 6 May 2008 12:18:51 -0000 1.3 +++ modules/trigger/trigger.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ version = VERSION core = 7.x files[] = trigger.module files[] = trigger.admin.inc +files[] = trigger.install Index: modules/trigger/trigger.install =================================================================== RCS file: /cvs/drupal/drupal/modules/trigger/trigger.install,v retrieving revision 1.5 diff -u -p -r1.5 trigger.install --- modules/trigger/trigger.install 28 Dec 2007 12:02:52 -0000 1.5 +++ modules/trigger/trigger.install 25 Jul 2008 01:13:36 -0000 @@ -7,9 +7,9 @@ function trigger_install() { // Create tables. drupal_install_schema('trigger'); - - // Do initial synchronization of actions in code and the database. - actions_synchronize(actions_list()); + // Initial synchronization of actions in code and the database needs to be + // done once all modules are installed. install.php and + // drupal_web_test_case.php and system_modules does so. } /** Index: modules/update/update.info =================================================================== RCS file: /cvs/drupal/drupal/modules/update/update.info,v retrieving revision 1.3 diff -u -p -r1.3 update.info --- modules/update/update.info 6 May 2008 12:18:53 -0000 1.3 +++ modules/update/update.info 25 Jul 2008 01:13:36 -0000 @@ -9,3 +9,4 @@ files[] = update.compare.inc files[] = update.fetch.inc files[] = update.report.inc files[] = update.settings.inc +files[] = update.install Index: modules/upload/upload.info =================================================================== RCS file: /cvs/drupal/drupal/modules/upload/upload.info,v retrieving revision 1.6 diff -u -p -r1.6 upload.info --- modules/upload/upload.info 6 May 2008 12:18:53 -0000 1.6 +++ modules/upload/upload.info 25 Jul 2008 01:13:36 -0000 @@ -6,3 +6,4 @@ version = VERSION core = 7.x files[] = upload.module files[] = upload.admin.inc +files[] = upload.install Index: modules/user/user.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v retrieving revision 1.24 diff -u -p -r1.24 user.admin.inc --- modules/user/user.admin.inc 24 Jul 2008 16:28:52 -0000 1.24 +++ modules/user/user.admin.inc 25 Jul 2008 01:13:36 -0000 @@ -201,7 +201,7 @@ function user_admin_account_submit($form $operation = $operations[$form_state['values']['operation']]; // Filter out unchecked accounts. $accounts = array_filter($form_state['values']['accounts']); - if ($function = $operation['callback']) { + if (($function = $operation['callback']) && drupal_function_exists($function)) { // Add in callback arguments if present. if (isset($operation['callback arguments'])) { $args = array_merge(array($accounts), $operation['callback arguments']); Index: modules/user/user.info =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.info,v retrieving revision 1.6 diff -u -p -r1.6 user.info --- modules/user/user.info 6 May 2008 12:18:54 -0000 1.6 +++ modules/user/user.info 25 Jul 2008 01:13:36 -0000 @@ -7,3 +7,4 @@ core = 7.x files[] = user.module files[] = user.admin.inc files[] = user.pages.inc +files[] = user.install Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.912 diff -u -p -r1.912 user.module --- modules/user/user.module 16 Jul 2008 21:59:29 -0000 1.912 +++ modules/user/user.module 25 Jul 2008 01:13:36 -0000 @@ -23,11 +23,9 @@ define('EMAIL_MAX_LENGTH', 64); * be passed by reference. */ function user_module_invoke($type, &$array, &$user, $category = NULL) { - foreach (module_list() as $module) { + foreach (module_implements('user') as $module) { $function = $module . '_user'; - if (function_exists($function)) { - $function($type, $array, $user, $category); - } + $function($type, $array, $user, $category); } } Index: profiles/default/default.profile =================================================================== RCS file: /cvs/drupal/drupal/profiles/default/default.profile,v retrieving revision 1.26 diff -u -p -r1.26 default.profile --- profiles/default/default.profile 24 Jun 2008 21:26:48 -0000 1.26 +++ profiles/default/default.profile 25 Jul 2008 01:13:36 -0000 @@ -126,6 +126,7 @@ function default_profile_tasks(&$task, $ // Default page to not be promoted and have comments disabled. variable_set('node_options_page', array('status')); + drupal_load('module', 'comment'); variable_set('comment_page', COMMENT_NODE_DISABLED); // Don't display date and author information for page nodes by default. Index: scripts/run-tests.sh =================================================================== RCS file: /cvs/drupal/drupal/scripts/run-tests.sh,v retrieving revision 1.6 diff -u -p -r1.6 run-tests.sh --- scripts/run-tests.sh 24 Jul 2008 06:46:28 -0000 1.6 +++ scripts/run-tests.sh 25 Jul 2008 01:13:36 -0000 @@ -313,7 +313,7 @@ function simpletest_script_execute_batch * Run a single test (assume a Drupal bootstrapped environnement). */ function simpletest_script_run_one_test($test_id, $test_class) { - simpletest_get_all_tests(); + module_invoke('simpletest', 'get_all_tests'); $test = new $test_class($test_id); $test->run(); $info = $test->getInfo();