summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2009-08-24 00:10:46 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2009-08-24 00:10:46 +0000
commite63e85020b6846c35624f04c60b40f1aa11db3b1 (patch)
tree908a1151a45ce37ae82dce00fffedb26b33ccde0 /includes
parent4ae238ea577ed0140df6fd034b06bfd7b0f0cdb4 (diff)
downloadbrdo-e63e85020b6846c35624f04c60b40f1aa11db3b1.tar.gz
brdo-e63e85020b6846c35624f04c60b40f1aa11db3b1.tar.bz2
Of all the patches to accidentally commit without a message. :( Rolling back registry rip. Let's try that again.
Diffstat (limited to 'includes')
-rw-r--r--includes/ajax.inc2
-rw-r--r--includes/bootstrap.inc101
-rw-r--r--includes/common.inc57
-rw-r--r--includes/file.inc4
-rw-r--r--includes/form.inc17
-rw-r--r--includes/image.inc4
-rw-r--r--includes/install.inc7
-rw-r--r--includes/mail.inc2
-rw-r--r--includes/menu.inc33
-rw-r--r--includes/module.inc159
-rw-r--r--includes/registry.inc131
-rw-r--r--includes/stream_wrappers.inc3
-rw-r--r--includes/theme.inc31
-rw-r--r--includes/theme.maintenance.inc2
-rw-r--r--includes/token.inc33
-rw-r--r--includes/xmlrpc.inc2
-rw-r--r--includes/xmlrpcs.inc2
17 files changed, 364 insertions, 226 deletions
diff --git a/includes/ajax.inc b/includes/ajax.inc
index 6a5a25e59..67f507a6c 100644
--- a/includes/ajax.inc
+++ b/includes/ajax.inc
@@ -211,7 +211,7 @@ function ajax_form_callback() {
// Get the callback function from the clicked button.
$ajax = $form_state['clicked_button']['#ajax'];
$callback = $ajax['callback'];
- if (function_exists($callback)) {
+ if (drupal_function_exists($callback)) {
$html = $callback($form, $form_state);
// If the returned value is a string, assume it is HTML and create
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 28c217b90..8508b85a2 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -654,7 +654,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
$mask = "/$name\.$type$/";
}
- if (function_exists('drupal_system_listing')) {
+ if (drupal_function_exists('drupal_system_listing')) {
$matches = drupal_system_listing($mask, $dir, 'name', 0);
if (!empty($matches[$name]->uri)) {
$files[$type][$name] = $matches[$name]->uri;
@@ -788,19 +788,6 @@ function drupal_page_is_cacheable($allow_caching = NULL) {
}
/**
- * 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) {
- drupal_load('module', $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.
*
@@ -1092,13 +1079,6 @@ function drupal_serve_page_from_cache(stdClass $cache) {
}
/**
- * Define the critical hooks that force modules to always be loaded.
- */
-function bootstrap_hooks() {
- return array('boot', 'exit', 'watchdog');
-}
-
-/**
* Unserializes and appends elements from a serialized string.
*
* @param $obj
@@ -1489,14 +1469,15 @@ function _drupal_bootstrap($phase) {
// If the skipping of the bootstrap hooks is not enforced, call
// hook_boot.
if (variable_get('page_cache_invoke_hooks', TRUE)) {
- bootstrap_invoke_all('boot');
+ require_once DRUPAL_ROOT . '/includes/module.inc';
+ module_invoke_all('boot');
}
header('X-Drupal-Cache: HIT');
drupal_serve_page_from_cache($cache);
// If the skipping of the bootstrap hooks is not enforced, call
// hook_exit.
if (variable_get('page_cache_invoke_hooks', TRUE)) {
- bootstrap_invoke_all('exit');
+ module_invoke_all('exit');
}
// We are done.
exit;
@@ -1523,9 +1504,6 @@ function _drupal_bootstrap($phase) {
case DRUPAL_BOOTSTRAP_VARIABLES:
// Load variables from the database, but do not overwrite variables set in settings.php.
$conf = variable_initialize(isset($conf) ? $conf : array());
- // Load bootstrap modules.
- require_once DRUPAL_ROOT . '/includes/module.inc';
- module_load_all(TRUE);
break;
case DRUPAL_BOOTSTRAP_SESSION:
@@ -1534,7 +1512,8 @@ function _drupal_bootstrap($phase) {
break;
case DRUPAL_BOOTSTRAP_PAGE_HEADER:
- bootstrap_invoke_all('boot');
+ require_once DRUPAL_ROOT . '/includes/module.inc';
+ module_invoke_all('boot');
if (!$cache && drupal_page_is_cacheable()) {
header('X-Drupal-Cache: MISS');
}
@@ -1772,7 +1751,7 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
// Load the .install files to get hook_schema.
// On some databases this function may be called before bootstrap has
// been completed, so we force the functions we need to load just in case.
- if (function_exists('module_load_all_includes')) {
+ if (drupal_function_exists('module_load_all_includes')) {
// There is currently a bug in module_list() where it caches what it
// was last called with, which is not always what you want.
@@ -1782,7 +1761,7 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
// "prime" module_list() here to to values we want, specifically
// "yes rebuild the list and don't limit to bootstrap".
// TODO: Remove this call after http://drupal.org/node/222109 is fixed.
- module_list(TRUE, FALSE);
+ module_list(TRUE);
module_load_all_includes('install');
}
@@ -1790,11 +1769,17 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
// Invoke hook_schema for all modules.
foreach (module_implements('schema') as $module) {
$current = module_invoke($module, 'schema');
- _drupal_schema_initialize($module, $current);
+ if (drupal_function_exists('_drupal_schema_initialize')) {
+ _drupal_schema_initialize($module, $current);
+ }
+
$schema = array_merge($schema, $current);
}
- drupal_alter('schema', $schema);
+ if (drupal_function_exists('drupal_alter')) {
+ drupal_alter('schema', $schema);
+ }
+
// If the schema is empty, avoid saving it: some database engines require
// the schema to perform queries, and this could lead to infinite loops.
if (!empty($schema) && (drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL)) {
@@ -1825,10 +1810,51 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
*/
/**
+ * Confirm that a function is available.
+ *
+ * If the function is already available, this function does nothing.
+ * If the function is not available, it tries to load the file where the
+ * function lives. If the file is not available, it returns false, so that it
+ * can be used as a drop-in replacement for function_exists().
+ *
+ * @param $function
+ * The name of the function to check or load.
+ * @return
+ * TRUE if the function is now available, FALSE otherwise.
+ */
+function drupal_function_exists($function) {
+ static $checked = array();
+ static $maintenance;
+
+ if (!isset($maintenance)) {
+ $maintenance = defined('MAINTENANCE_MODE');
+ }
+
+ if ($maintenance) {
+ return function_exists($function);
+ }
+
+ if (isset($checked[$function])) {
+ return $checked[$function];
+ }
+ $checked[$function] = FALSE;
+
+ if (function_exists($function)) {
+ $checked[$function] = TRUE;
+ return TRUE;
+ }
+
+ $checked[$function] = _registry_check_code('function', $function);
+
+ return $checked[$function];
+}
+
+/**
* Confirm that an interface is available.
*
- * This function is rarely called directly. Instead, it is registered as an
- * spl_autoload() handler, and PHP calls it for us when necessary.
+ * This function parallels drupal_function_exists(), but is rarely
+ * called directly. Instead, it is registered as an spl_autoload()
+ * handler, and PHP calls it for us when necessary.
*
* @param $interface
* The name of the interface to check or load.
@@ -1842,8 +1868,9 @@ function drupal_autoload_interface($interface) {
/**
* Confirm that a class is available.
*
- * This function is rarely called directly. Instead, it is registered as an
- * spl_autoload() handler, and PHP calls it for us when necessary.
+ * This function parallels drupal_function_exists(), but is rarely
+ * called directly. Instead, it is registered as an spl_autoload()
+ * handler, and PHP calls it for us when necessary.
*
* @param $class
* The name of the class to check or load.
@@ -1933,8 +1960,8 @@ function _registry_check_code($type, $name = NULL) {
/**
* Rescan all enabled modules and rebuild the registry.
*
- * Rescans all code in modules or includes directories, storing the location of
- * each interface or class in the database.
+ * Rescans all code in modules or includes directory, storing a mapping of
+ * each function, file, and hook implementation in the database.
*/
function registry_rebuild() {
require_once DRUPAL_ROOT . '/includes/registry.inc';
diff --git a/includes/common.inc b/includes/common.inc
index 56166cda8..caaa3f5a4 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -1219,7 +1219,7 @@ function t($string, array $args = array(), array $options = array()) {
$string = $custom_strings[$options['langcode']][$options['context']][$string];
}
// Translate with locale module if enabled.
- // We don't use function_exists() here, because it breaks the testing
+ // We don't use drupal_function_exists() here, because it breaks the testing
// framework if the locale module is enabled in the parent site (we cannot
// unload functions in PHP).
elseif (function_exists('locale') && $options['langcode'] != 'en') {
@@ -2319,6 +2319,7 @@ function drupal_page_footer() {
ob_flush();
}
+ module_implements(MODULE_IMPLEMENTS_WRITE_CACHE);
_registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE);
drupal_cache_system_paths();
}
@@ -2867,7 +2868,7 @@ function drupal_clear_css_cache() {
* - 'file': Path to the file relative to base_path().
* - 'inline': The JavaScript code that should be placed in the given scope.
* - 'external': The absolute path to an external JavaScript file that is not
- * hosted on the local server. These files will not be aggregated if
+ * hosted on the local server. These files will not be aggregated if
* JavaScript aggregation is enabled.
* - 'setting': An array with configuration options as associative array. The
* array is directly placed in Drupal.settings. All modules should wrap
@@ -3574,6 +3575,14 @@ function _drupal_bootstrap_full() {
set_error_handler('_drupal_error_handler');
set_exception_handler('_drupal_exception_handler');
+ if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'simpletest') !== FALSE) {
+ // Valid SimpleTest user-agent, log fatal errors to test specific file
+ // directory. The user-agent is validated in DRUPAL_BOOTSTRAP_DATABASE
+ // phase so as long as it is a SimpleTest user-agent it is valid.
+ ini_set('log_errors', 1);
+ ini_set('error_log', file_directory_path() . '/error.log');
+ }
+
// Emit the correct charset HTTP header.
drupal_set_header('Content-Type', 'text/html; charset=utf-8');
// Detect string handling method
@@ -3584,14 +3593,6 @@ function _drupal_bootstrap_full() {
module_load_all();
// Make sure all stream wrappers are registered.
file_get_stream_wrappers();
- if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'simpletest') !== FALSE) {
- // Valid SimpleTest user-agent, log fatal errors to test specific file
- // directory. The user-agent is validated in DRUPAL_BOOTSTRAP_DATABASE
- // phase so as long as it is a SimpleTest user-agent it is valid.
- ini_set('log_errors', 1);
- ini_set('error_log', file_directory_path() . '/error.log');
- }
-
// 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') {
@@ -3766,7 +3767,7 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
$searchdir[] = "$config/$directory";
}
- // If the database is not available, we can't use function_exists(), so
+ // If the database is not available, we can't use drupal_function_exists(), so
// we load the file_scan_directory function definition manually.
if (!function_exists('file_scan_directory')) {
require_once DRUPAL_ROOT . '/includes/file.inc';
@@ -3956,7 +3957,7 @@ function drupal_render(&$elements) {
// element is rendered into the final text.
if (isset($elements['#pre_render'])) {
foreach ($elements['#pre_render'] as $function) {
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
$elements = $function($elements);
}
}
@@ -3990,7 +3991,7 @@ function drupal_render(&$elements) {
// which allows the output'ed text to be filtered.
if (isset($elements['#post_render'])) {
foreach ($elements['#post_render'] as $function) {
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
$elements['#children'] = $function($elements['#children'], $elements);
}
}
@@ -4119,7 +4120,6 @@ function element_info($type) {
if (!isset($cache)) {
$basic_defaults = element_basic_defaults();
$cache = array();
-
foreach (module_implements('elements') as $module) {
$elements = module_invoke($module, 'elements');
if (isset($elements) && is_array($elements)) {
@@ -5055,32 +5055,3 @@ function drupal_check_incompatibility($v, $current_version) {
}
}
}
-
-/**
- * Performs one or more XML-RPC request(s).
- *
- * @param $url
- * An absolute URL of the XML-RPC endpoint.
- * Example:
- * http://www.example.com/xmlrpc.php
- * @param ...
- * For one request:
- * The method name followed by a variable number of arguments to the method.
- * For multiple requests (system.multicall):
- * An array of call arrays. Each call array follows the pattern of the single
- * request: method name followed by the arguments to the method.
- * @return
- * For one request:
- * Either the return value of the method on success, or FALSE.
- * If FALSE is returned, see xmlrpc_errno() and xmlrpc_error_msg().
- * For multiple requests:
- * An array of results. Each result will either be the result
- * returned by the method called, or an xmlrpc_error object if the call
- * failed. See xmlrpc_error().
- */
-function xmlrpc($url) {
- require_once DRUPAL_ROOT . '/includes/xmlrpc.inc';
- $args = func_get_args();
- return call_user_func_array('_xmlrpc', $args);
-}
-
diff --git a/includes/file.inc b/includes/file.inc
index 8047033be..c0e68f52e 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -320,7 +320,7 @@ function file_create_url($uri) {
return FALSE;
}
}
-
+
// @todo Implement CDN integration hook stuff in this function.
// @see http://drupal.org/node/499156
}
@@ -1250,7 +1250,7 @@ function file_validate(&$file, $validators = array()) {
// Call the validation functions specified by this function's caller.
$errors = array();
foreach ($validators as $function => $args) {
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
array_unshift($args, $file);
$errors = array_merge($errors, call_user_func_array($function, $args));
}
diff --git a/includes/form.inc b/includes/form.inc
index f36da73ab..bfacdad99 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -418,7 +418,7 @@ function drupal_retrieve_form($form_id, &$form_state) {
// We first check to see if there's a function named after the $form_id.
// If there is, we simply pass the arguments on to it to get the form.
- if (!function_exists($form_id)) {
+ if (!drupal_function_exists($form_id)) {
// In cases where many form_ids need to share a central constructor function,
// such as the node editing form, modules can implement hook_forms(). It
// maps one or more form_ids to the correct constructor functions.
@@ -439,6 +439,7 @@ function drupal_retrieve_form($form_id, &$form_state) {
}
if (isset($form_definition['callback'])) {
$callback = $form_definition['callback'];
+ drupal_function_exists($callback);
}
}
@@ -612,13 +613,13 @@ function drupal_prepare_form($form_id, &$form, &$form_state) {
$form += array('#tree' => FALSE, '#parents' => array());
if (!isset($form['#validate'])) {
- if (function_exists($form_id . '_validate')) {
+ if (drupal_function_exists($form_id . '_validate')) {
$form['#validate'] = array($form_id . '_validate');
}
}
if (!isset($form['#submit'])) {
- if (function_exists($form_id . '_submit')) {
+ if (drupal_function_exists($form_id . '_submit')) {
// We set submit here so that it can be altered.
$form['#submit'] = array($form_id . '_submit');
}
@@ -793,7 +794,7 @@ function _form_validate($elements, &$form_state, $form_id = NULL) {
// #value data.
elseif (isset($elements['#element_validate'])) {
foreach ($elements['#element_validate'] as $function) {
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
$function($elements, $form_state, $form_state['complete form']);
}
}
@@ -830,7 +831,7 @@ function form_execute_handlers($type, &$form, &$form_state) {
}
foreach ($handlers as $function) {
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
// Check to see if a previous _submit handler has set a batch, but
// make sure we do not react to a batch that is already being processed
// (for instance if a batch operation performs a drupal_form_submit()).
@@ -969,7 +970,7 @@ function form_builder($form_id, $element, &$form_state) {
// checkboxes and files.
if (isset($element['#process']) && !$element['#processed']) {
foreach ($element['#process'] as $process) {
- if (function_exists($process)) {
+ if (drupal_function_exists($process)) {
$element = $process($element, $form_state, $form_state['complete form']);
}
}
@@ -1096,7 +1097,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
// If we have input for the current element, assign it to the #value property.
if (!$form_state['programmed'] || isset($input)) {
// Call #type_value to set the form value;
- if (function_exists($value_callback)) {
+ if (drupal_function_exists($value_callback)) {
$element['#value'] = $value_callback($element, $input, $form_state);
}
if (!isset($element['#value']) && isset($input)) {
@@ -1111,7 +1112,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
// Load defaults.
if (!isset($element['#value'])) {
// Call #type_value without a second argument to request default_value handling.
- if (function_exists($value_callback)) {
+ if (drupal_function_exists($value_callback)) {
$element['#value'] = $value_callback($element, FALSE, $form_state);
}
// Final catch. If we haven't set a value yet, use the explicit default value.
diff --git a/includes/image.inc b/includes/image.inc
index dfc1d3002..e7734463d 100644
--- a/includes/image.inc
+++ b/includes/image.inc
@@ -65,7 +65,7 @@ function image_get_toolkit() {
if (!isset($toolkit)) {
$toolkits = image_get_available_toolkits();
$toolkit = variable_get('image_toolkit', 'gd');
- if (!isset($toolkits[$toolkit]) || !function_exists('image_' . $toolkit . '_load')) {
+ if (!isset($toolkits[$toolkit]) || !drupal_function_exists('image_' . $toolkit . '_load')) {
// The selected toolkit isn't available so return the first one found. If
// none are available this will return FALSE.
reset($toolkits);
@@ -90,7 +90,7 @@ function image_get_toolkit() {
*/
function image_toolkit_invoke($method, stdClass $image, array $params = array()) {
$function = 'image_' . $image->toolkit . '_' . $method;
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
array_unshift($params, $image);
return call_user_func_array($function, $params);
}
diff --git a/includes/install.inc b/includes/install.inc
index f66291bfb..60164b118 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -632,16 +632,15 @@ function drupal_install_system() {
$system_versions = drupal_get_schema_versions('system');
$system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED;
db_insert('system')
- ->fields(array('filename', 'name', 'type', 'owner', 'status', 'schema_version', 'bootstrap'))
+ ->fields(array('filename', 'name', 'type', 'owner', 'status', 'schema_version'))
->values(array(
'filename' => $system_path . '/system.module',
'name' => 'system',
'type' => 'module',
'owner' => '',
'status' => 1,
- 'schema_version' => $system_version,
- 'bootstrap' => 0,
- ))
+ 'schema_version' => $system_version
+ ))
->execute();
// Now that we've installed things properly, bootstrap the full Drupal environment
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
diff --git a/includes/mail.inc b/includes/mail.inc
index e2dbd15f6..58607c1e8 100644
--- a/includes/mail.inc
+++ b/includes/mail.inc
@@ -115,7 +115,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
// Build the e-mail (get subject and body, allow additional headers) by
// invoking hook_mail() on this module. We cannot use module_invoke() as
// we need to have $message by reference in hook_mail().
- if (function_exists($function = $module . '_mail')) {
+ if (drupal_function_exists($function = $module . '_mail')) {
$function($key, $message, $params);
}
diff --git a/includes/menu.inc b/includes/menu.inc
index c79b0f5ca..f80836cc7 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -411,10 +411,9 @@ function menu_execute_active_handler($path = NULL) {
}
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
- if ($router_item['file']) {
- require_once($router_item['file']);
+ if (drupal_function_exists($router_item['page_callback'])) {
+ return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
}
- return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
}
else {
return MENU_ACCESS_DENIED;
@@ -517,7 +516,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]);
}
- elseif (function_exists($callback)) {
+ elseif (drupal_function_exists($callback)) {
$item['access'] = call_user_func_array($callback, $arguments);
}
}
@@ -568,7 +567,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
$item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map));
}
}
- elseif ($callback && function_exists($callback)) {
+ elseif ($callback && drupal_function_exists($callback)) {
if (empty($item['title_arguments'])) {
$item['title'] = $callback($item['title']);
}
@@ -1906,7 +1905,7 @@ function menu_cache_clear_all() {
function menu_rebuild() {
if (!lock_acquire('menu_rebuild')) {
// Wait for another request that is already doing this work.
- // We choose to block here since otherwise the router item may not
+ // We choose to block here since otherwise the router item may not
// be available in menu_execute_active_handler() resulting in a 404.
lock_wait('menu_rebuild');
return FALSE;
@@ -2607,12 +2606,12 @@ function _menu_router_build($callbacks) {
$load_functions[$k] = NULL;
}
else {
- if (function_exists($matches[1] . '_to_arg')) {
+ if (drupal_function_exists($matches[1] . '_to_arg')) {
$to_arg_functions[$k] = $matches[1] . '_to_arg';
$load_functions[$k] = NULL;
$match = TRUE;
}
- if (function_exists($matches[1] . '_load')) {
+ if (drupal_function_exists($matches[1] . '_load')) {
$function = $matches[1] . '_load';
// Create an array of arguments that will be passed to the _load
// function when this menu path is checked, if 'load arguments'
@@ -2698,12 +2697,6 @@ function _menu_router_build($callbacks) {
if (!isset($item['page arguments']) && isset($parent['page arguments'])) {
$item['page arguments'] = $parent['page arguments'];
}
- if (!isset($item['file']) && isset($parent['file'])) {
- $item['file'] = $parent['file'];
- }
- if (!isset($item['file path']) && isset($parent['file path'])) {
- $item['file path'] = $parent['file path'];
- }
}
}
}
@@ -2731,17 +2724,7 @@ function _menu_router_build($callbacks) {
'tab_parent' => '',
'tab_root' => $path,
'path' => $path,
- 'file' => '',
- 'file path' => '',
- 'include file' => '',
- 'module' => '',
);
-
- // Calculate out the file to be included for each callback, if any.
- if ($item['file']) {
- $file_path = $item['file path'] ? $item['file path'] : drupal_get_path('module', $item['module']);
- $item['include file'] = $file_path . '/' . $item['file'];
- }
}
// Sort the masks so they are in order of descending fit.
@@ -2780,7 +2763,6 @@ function _menu_router_save($menu, $masks) {
'description',
'position',
'weight',
- 'file',
));
foreach ($menu as $path => $item) {
@@ -2805,7 +2787,6 @@ function _menu_router_save($menu, $masks) {
'description' => $item['description'],
'position' => $item['position'],
'weight' => $item['weight'],
- 'file' => $item['include file'],
));
}
// Execute insert object.
diff --git a/includes/module.inc b/includes/module.inc
index 3a5609a00..0c3f9202d 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -6,15 +6,24 @@
* API for loading and interacting with Drupal modules.
*/
+/**
+ * Pass this to module_implements when its cache needs to be written.
+ */
+define('MODULE_IMPLEMENTS_WRITE_CACHE', -1);
+
+/**
+ * Pass this to module_implements when its cache needs to be cleared.
+ */
+define('MODULE_IMPLEMENTS_CLEAR_CACHE', -2);
+
/**
* Load all the modules that have been enabled in the system table.
*/
-function module_load_all($bootstrap = FALSE) {
- foreach (module_list(TRUE, $bootstrap) as $module) {
+function module_load_all() {
+ foreach (module_list(TRUE) as $module) {
drupal_load('module', $module);
}
- module_implements('', FALSE, TRUE);
}
/**
@@ -24,9 +33,6 @@ function module_load_all($bootstrap = FALSE) {
* @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 module name. Set this option
* to TRUE to return a module list ordered only by module name.
@@ -37,7 +43,7 @@ function module_load_all($bootstrap = FALSE) {
* An associative array whose keys and values are the names of all loaded
* modules.
*/
-function module_list($refresh = FALSE, $bootstrap = FALSE, $sort = FALSE, $fixed_list = NULL) {
+function module_list($refresh = FALSE, $sort = FALSE, $fixed_list = NULL) {
static $list = array(), $sorted_list;
if (empty($list) || $refresh || $fixed_list) {
@@ -55,12 +61,7 @@ function module_list($refresh = FALSE, $bootstrap = FALSE, $sort = FALSE, $fixed
// Drupal installations, which might have modules installed in different
// locations in the file system. The ordering here must also be
// consistent with the one used in module_implements().
- if ($bootstrap) {
- $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, name ASC");
- }
- else {
- $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, name ASC");
- }
+ $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, name ASC");
foreach ($result as $module) {
if (file_exists($module->filename)) {
drupal_get_filename('module', $module->name, $module->filename);
@@ -163,7 +164,7 @@ function module_load_include($type, $module, $name = NULL) {
$name = $module;
}
- if (function_exists('drupal_get_path')) {
+ if (drupal_function_exists('drupal_get_path')) {
$file = DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . "/$name.$type";
if (is_file($file)) {
require_once $file;
@@ -217,9 +218,8 @@ function module_enable($module_list, $disable_modules_installed_hook = FALSE) {
}
if (!empty($invoke_modules)) {
- // Refresh the module list to exclude the disabled modules.
+ // Refresh the module list to include the new enabled module.
module_list(TRUE);
- module_implements('', FALSE, TRUE);
// Force to regenerate the stored list of hook implementations.
registry_rebuild();
@@ -235,7 +235,7 @@ function module_enable($module_list, $disable_modules_installed_hook = FALSE) {
// We check for the existence of node_access_needs_rebuild() since
// at install time, module_enable() could be called while node.module
// is not enabled yet.
- if (function_exists('node_access_needs_rebuild') && !node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
+ if (drupal_function_exists('node_access_needs_rebuild') && !node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
node_access_needs_rebuild(TRUE);
}
}
@@ -275,12 +275,11 @@ function module_disable($module_list) {
}
if (!empty($invoke_modules)) {
- // Refresh the module list to exclude the disabled modules.
- module_list(TRUE);
- module_implements('', FALSE, TRUE);
// Invoke hook_module_disable before disabling modules,
// so we can still call module hooks to get information.
module_invoke_all('modules_disabled', $invoke_modules);
+ // Refresh the module list to exclude the disabled modules.
+ module_list(TRUE);
// Force to regenerate the stored list of hook implementations.
registry_rebuild();
}
@@ -325,49 +324,119 @@ function module_disable($module_list) {
* implemented in that module.
*/
function module_hook($module, $hook) {
- return function_exists($module . '_' . $hook);
+ $function = $module . '_' . $hook;
+ return function_exists($function) || drupal_function_exists($function);
}
/**
* Determine which modules are implementing a 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
+ * The name of the hook (e.g. "help" or "menu"). Special cases:
+ * MODULE_IMPLEMENTS_CLEAR_CACHE: Force the stored list of hook
* implementations to be regenerated (such as after enabling a new module,
- * before processing hook_enable).
+ * before processing hook_enable).
+ * MODULE_IMPLEMENTS_WRITE_CACHE: Write the stored list of hook
+ * implementations into the cache_registry table.
+ * @param $sort
+ * By default, modules are ordered by weight and module name. By setting this
+ * option to TRUE, modules will be ordered by module name.
* @return
* An array with the names of the modules which are implementing this hook.
+ * All enabled modules are taken into consideration and the files containing
+ * the implementations are loaded as necessary.
*/
-function module_implements($hook, $sort = FALSE, $refresh = FALSE) {
- static $implementations;
+function module_implements($hook, $sort = FALSE) {
+ static $implementations = array(), $sorted_implementations = array(), $loaded = array(), $cached_hooks = 0, $maintenance;
+
+ // Use a static variable for maintenance mode to avoid the overhead of
+ // calling defined() each time the function is called.
+ if (!isset($maintenance)) {
+ $maintenance = defined('MAINTENANCE_MODE');
+ }
- if ($refresh) {
+ if ($maintenance) {
+ return _module_implements_maintenance($hook, $sort);
+ }
+ if ($hook === MODULE_IMPLEMENTS_CLEAR_CACHE) {
$implementations = array();
+ $sorted_implementations = array();
+ $loaded = array();
+ $cached_hooks = 0;
+ cache_clear_all('hooks', 'cache_registry');
+ return;
+ }
+ if ($hook === MODULE_IMPLEMENTS_WRITE_CACHE) {
+ // Only write this to cache if we loaded new implementations.
+ if (count($implementations) > $cached_hooks) {
+ cache_set('hooks', $implementations, 'cache_registry');
+ }
return;
}
- if (!isset($implementations[$hook])) {
- $implementations[$hook] = array();
- $list = module_list(FALSE, FALSE, $sort);
- foreach ($list as $module) {
- if (module_hook($module, $hook)) {
- $implementations[$hook][] = $module;
+ if (!isset($loaded[$hook])) {
+ if (empty($implementations) && ($cache = cache_get('hooks', 'cache_registry'))) {
+ $implementations = $cache->data;
+ $cached_hooks = count($implementations);
+ }
+ if (!isset($implementations[$hook])) {
+ // The module name (rather than the filename) is used as the fallback
+ // weighting in order to guarantee consistent behavior across different
+ // Drupal installations, which might have modules installed in different
+ // locations in the file system. The ordering here must also be
+ // consistent with the one used in module_list().
+ $implementations[$hook] = db_query("SELECT module FROM {registry} WHERE type = 'function' AND suffix = :hook ORDER BY weight, module", array(':hook' => $hook))->fetchCol();
+ }
+ foreach ($implementations[$hook] as $module) {
+ $function = $module . '_' . $hook;
+ if (!function_exists($function)) {
+ drupal_function_exists($function);
}
}
+ $loaded[$hook] = TRUE;
}
- // The explicit cast forces a copy to be made. This is needed because
- // $implementations[$hook] is only a reference to an element of
- // $implementations and if there are nested foreaches (due to nested node
- // API calls, for example), they would both manipulate the same array's
- // references, which causes some modules' hooks not to be called.
- // See also http://www.zend.com/zend/art/ref-count.php.
- return (array)$implementations[$hook];
+ if ($sort) {
+ if (!isset($sorted_implementations[$hook])) {
+ $sorted_implementations[$hook] = $implementations[$hook];
+ sort($sorted_implementations[$hook]);
+ }
+ return $sorted_implementations[$hook];
+ }
+ else {
+ return $implementations[$hook];
+ }
+}
+
+/**
+ * This is the maintenance version of module_implements for internal use only.
+ *
+ * This function is called whenever MAINTENANCE_MODE is defined and is a
+ * safe code path for Drupal installation or upgrade because it does not use
+ * the database, instead it uses module_list. @see module_list $fixed_list on
+ * how to make module_list also DB independent.
+ *
+ * @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.
+ * @return
+ * An array with the names of the modules which are implementing this hook.
+ * Only enabled and already loaded modules are taken into consideration.
+ */
+function _module_implements_maintenance($hook, $sort = FALSE) {
+ $implementations = array();
+ foreach (module_list() as $module) {
+ $function = $module . '_' . $hook;
+ if (function_exists($function)) {
+ $implementations[] = $module;
+ }
+ if ($sort) {
+ sort($implementations);
+ }
+ }
+ return $implementations;
}
/**
@@ -409,7 +478,7 @@ function module_invoke_all() {
$return = array();
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
- if (function_exists($function)) {
+ if (drupal_function_exists($function)) {
$result = call_user_func_array($function, $args);
if (isset($result) && is_array($result)) {
$return = array_merge_recursive($return, $result);
diff --git a/includes/registry.inc b/includes/registry.inc
index cf2c09757..117de9881 100644
--- a/includes/registry.inc
+++ b/includes/registry.inc
@@ -13,7 +13,7 @@
*
* Drupal maintains an internal registry of all functions or classes in the
* system, allowing it to lazy-load code files as needed (reducing the amount
- * of code that must be parsed on each request).
+ * of code that must be parsed on each request).
*/
/**
@@ -34,6 +34,9 @@ function _registry_rebuild() {
require_once DRUPAL_ROOT . '/includes/database/select.inc';
require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
+ // Reset the resources cache.
+ _registry_get_resource_name();
+
// Get current list of modules and their files.
$modules = system_get_module_data();
// Get the list of files we are going to parse.
@@ -93,9 +96,9 @@ function _registry_rebuild() {
$unchanged_resources[$key] = $file;
}
}
- module_implements('', FALSE, TRUE);
_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
+ module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE);
cache_clear_all('*', 'cache_registry', TRUE);
// We have some unchanged resources, warm up the cache - no need to pay
@@ -160,23 +163,123 @@ function _registry_parse_files($files) {
* (optional) Weight of the module.
*/
function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
- static $map = array(T_CLASS => 'class', T_INTERFACE => 'interface');
+ $map = &drupal_static(__FUNCTION__, array(T_FUNCTION => 'function', T_CLASS => 'class', T_INTERFACE => 'interface'));
// Delete registry entries for this file, so we can insert the new resources.
db_delete('registry')
->condition('filename', $filename)
->execute();
- if (preg_match_all('/^\s*(?:abstract)?\s*(class|interface)\s+([a-zA-Z0-9_]+)/m', $contents, $matches)) {
- $query = db_insert('registry')->fields(array('name', 'type', 'filename', 'module', 'weight'));
- foreach ($matches[2] as $key => $name) {
- $query->values(array(
- 'name' => $name,
- 'type' => $matches[1][$key],
- 'filename' => $filename,
- 'module' => $module,
- 'weight' => $weight,
- ));
+ $tokens = token_get_all($contents);
+ while ($token = next($tokens)) {
+ // Ignore all tokens except for those we are specifically saving.
+ if (is_array($token) && isset($map[$token[0]])) {
+ $type = $map[$token[0]];
+ if ($resource_name = _registry_get_resource_name($tokens, $type)) {
+ $suffix = '';
+ // Collect the part of the function name after the module name,
+ // so that we can query the registry for possible hook implementations.
+ if ($type == 'function' && !empty($module)) {
+ $n = strlen($module);
+ if (substr($resource_name, 0, $n) == $module) {
+ $suffix = substr($resource_name, $n + 1);
+ }
+ }
+ $fields = array(
+ 'filename' => $filename,
+ 'module' => $module,
+ 'suffix' => $suffix,
+ 'weight' => $weight,
+ );
+ // Because some systems, such as cache, currently use duplicate function
+ // names in separate files an insert query cannot be used here as it
+ // would cause a key constraint violation. Instead we use a merge query.
+ // In practice this should not be an issue as those systems all initialize
+ // pre-registry and therefore are never loaded by the registry so it
+ // doesn't matter if those records in the registry table point to one
+ // filename instead of another.
+ // TODO: Convert this back to an insert query after all duplicate
+ // function names have been purged from Drupal.
+ db_merge('registry')
+ ->key(array('name' => $resource_name, 'type' => $type))
+ ->fields($fields)
+ ->execute();
+
+ // We skip the body because classes may contain functions.
+ _registry_skip_body($tokens);
+ }
+ }
+ }
+}
+
+/**
+ * Derive the name of the next resource in the token stream.
+ *
+ * When called without arguments, it resets its static cache.
+ *
+ * @param $tokens
+ * The collection of tokens for the current file being parsed.
+ * @param $type
+ * 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.
+ */
+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
+ // save one more than once.
+ $resources = &drupal_static(__FUNCTION__);
+
+ if (!isset($tokens)) {
+ $resources = array();
+ return;
+ }
+ // Determine the name of the resource.
+ next($tokens); // Eat a space.
+ $token = next($tokens);
+ if ($token == '&') {
+ $token = next($tokens);
+ }
+ $resource_name = $token[1];
+
+ // Ensure that we never save it more than once.
+ if (isset($resources[$type][$resource_name])) {
+ return FALSE;
+ }
+ $resources[$type][$resource_name] = TRUE;
+
+ return $resource_name;
+}
+
+/**
+ * Skip the body of a code block, as defined by { and }.
+ *
+ * This function assumes that the body starts at the next instance
+ * of { from the current position.
+ *
+ * @param $tokens
+ */
+function _registry_skip_body(&$tokens) {
+ $num_braces = 1;
+
+ $token = '';
+ // Get to the first open brace.
+ while ($token != '{' && ($token = next($tokens)));
+
+ // Scan through the rest of the tokens until we reach the matching
+ // end brace.
+ while ($num_braces && ($token = next($tokens))) {
+ // PHP is really logical to have three different tokens for { with
+ // inconsistent names and only one for a closing brace.
+ if ($token == '{' || (is_array($token) && ($token[0] == T_DOLLAR_OPEN_CURLY_BRACES || $token[0] == T_CURLY_OPEN))) {
+ ++$num_braces;
+ }
+ elseif ($token == '}') {
+ --$num_braces;
+ }
+ // Consume strings manually as workaround for a bug in PHP < 5.2.3 (see
+ // http://drupal.org/node/368116).
+ elseif ($token == '"' || $token == '`' || (is_array($token) && $token[0] == T_START_HEREDOC)) {
+ $stop = is_array($token) ? T_END_HEREDOC : $token;
+ while (($token = next($tokens)) && (is_array($token) ? $token[0] : $token) != $stop);
}
- $query->execute();
}
}
diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc
index cb642d979..6841325cc 100644
--- a/includes/stream_wrappers.inc
+++ b/includes/stream_wrappers.inc
@@ -194,8 +194,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
static function getMimeType($uri, $mapping = NULL) {
if (!isset($mapping)) {
$mapping = variable_get('mime_extension_mapping', NULL);
- if (!isset($mapping)) {
- include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc';
+ if (!isset($mapping) && drupal_function_exists('file_default_mimetype_mapping')) {
// The default file map, defined in file.mimetypes.inc is quite big.
// We only load it when necessary.
$mapping = file_default_mimetype_mapping();
diff --git a/includes/theme.inc b/includes/theme.inc
index 0ad132f10..32feb595a 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -189,7 +189,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb
}
}
- if (function_exists($registry_callback)) {
+ if (drupal_function_exists($registry_callback)) {
$registry_callback($theme, $base_theme, $theme_engine);
}
}
@@ -322,6 +322,7 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
if (function_exists($function)) {
$result = $function($cache, $type, $theme, $path);
+
foreach ($result as $hook => $info) {
$result[$hook]['type'] = $type;
$result[$hook]['theme path'] = $path;
@@ -335,14 +336,12 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) {
// functions on behalf of core .include files.
// All files are included to be safe. Conditionally included
// files can prevent them from getting registered.
- if (isset($cache[$hook]['includes'])) {
- $result[$hook]['includes'] = $cache[$hook]['includes'];
+ if (isset($info['file']) && !isset($info['path'])) {
+ $result[$hook]['file'] = $path . '/' . $info['file'];
+ include_once DRUPAL_ROOT . '/' . $result[$hook]['file'];
}
- if (isset($info['file'])) {
- $include_file = isset($info['path']) ? $info['path'] : $path;
- $include_file .= '/' . $info['file'];
- include_once DRUPAL_ROOT . '/' . $include_file;
- $result[$hook]['includes'][] = $include_file;
+ elseif (isset($info['file']) && isset($info['path'])) {
+ include_once DRUPAL_ROOT . '/' . $info['path'] . '/' . $info['file'];
}
// If 'arguments' have been defined previously, carry them forward.
@@ -761,10 +760,12 @@ function theme() {
$theme_path = $info['theme path'];
// Include a file if the theme function or variable processor is held elsewhere.
- if (!empty($info['includes'])) {
- foreach ($info['includes'] as $include_file) {
- include_once DRUPAL_ROOT . '/' . $include_file;
+ if (!empty($info['file'])) {
+ $include_file = $info['file'];
+ if (isset($info['path'])) {
+ $include_file = $info['path'] . '/' . $include_file;
}
+ include_once DRUPAL_ROOT . '/' . $include_file;
}
if (isset($info['function'])) {
// The theme call is a function.
@@ -803,7 +804,7 @@ function theme() {
foreach (array('preprocess functions', 'process functions') as $phase) {
if (!empty($info[$phase])) {
foreach ($info[$phase] as $processor_function) {
- if (function_exists($processor_function)) {
+ if (drupal_function_exists($processor_function)) {
$processor_function($variables, $hook_clone);
}
}
@@ -829,7 +830,7 @@ function theme() {
$suggestions[] = $variables['theme_function'];
}
foreach (array_reverse($suggestions) as $suggestion) {
- if (function_exists($suggestion)) {
+ if (drupal_function_exists($suggestion)) {
$info['function'] = $suggestion;
break;
}
@@ -841,7 +842,7 @@ function theme() {
}
// Call the function.
- if (function_exists($info['function'])) {
+ if (drupal_function_exists($info['function'])) {
$output = call_user_func_array($info['function'], $args);
}
}
@@ -884,7 +885,7 @@ function theme() {
foreach (array('preprocess functions', 'process functions') as $phase) {
if (!empty($info[$phase])) {
foreach ($info[$phase] as $processor_function) {
- if (function_exists($processor_function)) {
+ if (drupal_function_exists($processor_function)) {
call_user_func_array($processor_function, $args);
}
}
diff --git a/includes/theme.maintenance.inc b/includes/theme.maintenance.inc
index 69e675e04..20b2f6505 100644
--- a/includes/theme.maintenance.inc
+++ b/includes/theme.maintenance.inc
@@ -41,7 +41,7 @@ function _drupal_maintenance_theme() {
// bootstrap just enough to allow hook invocations to work.
$module_list['system']['filename'] = 'modules/system/system.module';
$module_list['filter']['filename'] = 'modules/filter/filter.module';
- module_list(TRUE, FALSE, FALSE, $module_list);
+ module_list(TRUE, FALSE, $module_list);
drupal_load('module', 'system');
drupal_load('module', 'filter');
}
diff --git a/includes/token.inc b/includes/token.inc
index 91325d3fb..7f786121d 100644
--- a/includes/token.inc
+++ b/includes/token.inc
@@ -81,14 +81,14 @@ function token_replace($text, array $data = array(), array $options = array()) {
}
// Optionally alter the list of replacement values.
- if (!empty($options['callback']) && function_exists($options['callback'])) {
+ if (!empty($options['callback']) && drupal_function_exists($options['callback'])) {
$function = $options['callback'];
$function($replacements, $data, $options);
}
$tokens = array_keys($replacements);
$values = array_values($replacements);
-
+
return str_replace($tokens, $values, $text);
}
@@ -153,11 +153,15 @@ function token_scan($text) {
function token_generate($type, array $tokens, array $data = array(), array $options = array()) {
$results = array();
$options += array('sanitize' => TRUE);
- _token_initialize();
- $result = module_invoke_all('tokens', $type, $tokens, $data, $options);
- foreach ($result as $original => $replacement) {
- $results[$original] = $replacement;
+ foreach (module_implements('tokens') as $module) {
+ $function = $module . '_tokens';
+ if (drupal_function_exists($function)) {
+ $result = $function($type, $tokens, $data, $options);
+ foreach ($result as $original => $replacement) {
+ $results[$original] = $replacement;
+ }
+ }
}
return $results;
@@ -227,25 +231,8 @@ function token_find_with_prefix(array $tokens, $prefix, $delimiter = ':') {
function token_info() {
$data = &drupal_static(__FUNCTION__);
if (!isset($data)) {
- _token_initialize();
$data = module_invoke_all('token_info');
drupal_alter('token_info', $data);
}
return $data;
}
-
-/**
- * Load modulename.tokens.inc for all enabled modules.
- */
-function _token_initialize() {
- $initialized = drupal_static(__FUNCTION__);
- if (!$initialized) {
- foreach (module_list() as $module) {
- $filename = DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . "/$module.tokens.inc";
- if (file_exists($filename)) {
- include_once $filename;
- }
- }
- $initialized = TRUE;
- }
-}
diff --git a/includes/xmlrpc.inc b/includes/xmlrpc.inc
index cdf3f227d..767ca101f 100644
--- a/includes/xmlrpc.inc
+++ b/includes/xmlrpc.inc
@@ -438,7 +438,7 @@ function xmlrpc_base64_get_xml($xmlrpc_base64) {
* returned by the method called, or an xmlrpc_error object if the call
* failed. See xmlrpc_error().
*/
-function _xmlrpc() {
+function xmlrpc() {
$args = func_get_args();
$url = array_shift($args);
if (is_array($args[0])) {
diff --git a/includes/xmlrpcs.inc b/includes/xmlrpcs.inc
index 76ccd8895..8588680ec 100644
--- a/includes/xmlrpcs.inc
+++ b/includes/xmlrpcs.inc
@@ -200,7 +200,7 @@ function xmlrpc_server_call($xmlrpc_server, $methodname, $args) {
}
}
- if (!function_exists($method)) {
+ if (!drupal_function_exists($method)) {
return xmlrpc_error(-32601, t('Server error. Requested function @method does not exist.', array("@method" => $method)));
}
// Call the mapped function