[ Index ] |
|
Code source de Drupal 5.3 |
1 <?php 2 // $Id: module.inc,v 1.93.2.2 2007/07/21 00:54:18 drumm Exp $ 3 4 /** 5 * @file 6 * API for loading and interacting with Drupal modules. 7 */ 8 9 /** 10 * Load all the modules that have been enabled in the system table. 11 */ 12 function module_load_all() { 13 foreach (module_list(TRUE, FALSE) as $module) { 14 drupal_load('module', $module); 15 } 16 } 17 18 /** 19 * Call a function repeatedly with each module in turn as an argument. 20 */ 21 function module_iterate($function, $argument = '') { 22 foreach (module_list() as $name) { 23 $function($name, $argument); 24 } 25 } 26 27 /** 28 * Collect a list of all loaded modules. During the bootstrap, return only 29 * vital modules. See bootstrap.inc 30 * 31 * @param $refresh 32 * Whether to force the module list to be regenerated (such as after the 33 * administrator has changed the system settings). 34 * @param $bootstrap 35 * Whether to return the reduced set of modules loaded in "bootstrap mode" 36 * for cached pages. See bootstrap.inc. 37 * @param $sort 38 * By default, modules are ordered by weight and filename, settings this option 39 * to TRUE, module list will be ordered by module name. 40 * @param $fixed_list 41 * (Optional) Override the module list with the given modules. Stays until the 42 * next call with $refresh = TRUE. 43 * @return 44 * An associative array whose keys and values are the names of all loaded 45 * modules. 46 */ 47 function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_list = NULL) { 48 static $list, $sorted_list; 49 50 if ($refresh || $fixed_list) { 51 unset($sorted_list); 52 $list = array(); 53 if ($fixed_list) { 54 foreach ($fixed_list as $name => $module) { 55 drupal_get_filename('module', $name, $module['filename']); 56 $list[$name] = $name; 57 } 58 } 59 else { 60 if ($bootstrap) { 61 $result = db_query("SELECT name, filename, throttle FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, filename ASC"); 62 } 63 else { 64 $result = db_query("SELECT name, filename, throttle FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, filename ASC"); 65 } 66 while ($module = db_fetch_object($result)) { 67 if (file_exists($module->filename)) { 68 // Determine the current throttle status and see if the module should be 69 // loaded based on server load. We have to directly access the throttle 70 // variables, since throttle.module may not be loaded yet. 71 $throttle = ($module->throttle && variable_get('throttle_level', 0) > 0); 72 if (!$throttle) { 73 drupal_get_filename('module', $module->name, $module->filename); 74 $list[$module->name] = $module->name; 75 } 76 } 77 } 78 } 79 } 80 if ($sort) { 81 if (!isset($sorted_list)) { 82 $sorted_list = $list; 83 ksort($sorted_list); 84 } 85 return $sorted_list; 86 } 87 return $list; 88 } 89 90 /** 91 * Rebuild the database cache of module files. 92 * 93 * @return 94 * The array of filesystem objects used to rebuild the cache. 95 */ 96 function module_rebuild_cache() { 97 // Get current list of modules 98 $files = drupal_system_listing('\.module$', 'modules', 'name', 0); 99 100 // Extract current files from database. 101 system_get_files_database($files, 'module'); 102 103 ksort($files); 104 105 foreach ($files as $filename => $file) { 106 $file->info = _module_parse_info_file(dirname($file->filename) .'/'. $file->name .'.info'); 107 // Skip modules that don't provide info. 108 if (empty($file->info)) { 109 unset($files[$filename]); 110 continue; 111 } 112 $files[$filename]->info = $file->info; 113 114 // log the critical hooks implemented by this module 115 $bootstrap = 0; 116 foreach (bootstrap_hooks() as $hook) { 117 if (module_hook($file->name, $hook)) { 118 $bootstrap = 1; 119 break; 120 } 121 } 122 123 // Update the contents of the system table: 124 // TODO: We shouldn't actually need this description field anymore. Remove me next release. 125 if (isset($file->status) || (isset($file->old_filename) && $file->old_filename != $file->filename)) { 126 db_query("UPDATE {system} SET description = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", $file->info['description'], $file->name, $file->filename, $bootstrap, $file->old_filename); 127 } 128 else { 129 // This is a new module. 130 db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->info['description'], 'module', $file->filename, $file->status, $file->throttle, $bootstrap); 131 } 132 } 133 $files = _module_build_dependents($files); 134 return $files; 135 } 136 137 /** 138 * Find dependents; modules that are required by other modules. 139 * Adds an array of dependents to the $file->info array. 140 * 141 * @return 142 * The list of files array with dependents added where applicable. 143 */ 144 function _module_build_dependents($files) { 145 foreach ($files as $filename => $file) { 146 if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { 147 foreach ($file->info['dependencies'] as $dependency) { 148 if (!empty($files[$dependency]) && is_array($files[$dependency]->info)) { 149 if (!isset($files[$dependency]->info['dependents'])) { 150 $files[$dependency]->info['dependents'] = array(); 151 } 152 $files[$dependency]->info['dependents'][] = $filename; 153 } 154 } 155 } 156 } 157 return $files; 158 } 159 160 /** 161 * Parse Drupal info file format. 162 * Uses ini parser provided by php's parse_ini_file(). 163 * 164 * Files should use the ini format to specify values. 165 * e.g. 166 * key = "value" 167 * key2 = value2 168 * 169 * Some things to be aware of: 170 * - This function is NOT for placing arbitrary module-specific settings. Use variable_get() 171 * and variable_set() for that. 172 * - You may not use double-quotes in a value. 173 * 174 * Information stored in the module.info file: 175 * name - The real name of the module for display purposes. 176 * description - A brief description of the module. 177 * dependencies - A space delimited list of the short names (shortname) of other modules this module depends on. 178 * package - The name of the package of modules this module belongs to. 179 * 180 * Example of .info file: 181 * name = Forum 182 * description = Enables threaded discussions about general topics. 183 * dependencies = taxonomy comment 184 * package = Core - optional 185 * 186 * @param $filename 187 * The file we are parsing. Accepts file with relative or absolute path. 188 * @return 189 * The info array. 190 */ 191 function _module_parse_info_file($filename) { 192 $info = array(); 193 194 if (file_exists($filename)) { 195 $info = parse_ini_file($filename); 196 197 if (isset($info['dependencies'])) { 198 $info['dependencies'] = explode(" ", $info['dependencies']); 199 } 200 else { 201 $info['dependencies'] = NULL; 202 } 203 } 204 return $info; 205 } 206 207 /** 208 * Determine whether a given module exists. 209 * 210 * @param $module 211 * The name of the module (without the .module extension). 212 * @return 213 * TRUE if the module is both installed and enabled. 214 */ 215 function module_exists($module) { 216 $list = module_list(); 217 return array_key_exists($module, $list); 218 } 219 220 /** 221 * Load a module's installation hooks. 222 */ 223 function module_load_install($module) { 224 // Make sure the installation API is available 225 include_once './includes/install.inc'; 226 227 $install_file = './'. drupal_get_path('module', $module) .'/'. $module .'.install'; 228 if (is_file($install_file)) { 229 include_once $install_file; 230 } 231 } 232 233 /** 234 * Enable a given list of modules. 235 * 236 * @param $module_list 237 * An array of module names. 238 */ 239 function module_enable($module_list) { 240 $invoke_modules = array(); 241 foreach ($module_list as $module) { 242 $existing = db_fetch_object(db_query("SELECT status FROM {system} WHERE type = 'module' AND name = '%s'", $module)); 243 if ($existing->status === '0') { 244 module_load_install($module); 245 db_query("UPDATE {system} SET status = 1, throttle = 0 WHERE type = 'module' AND name = '%s'", $module); 246 drupal_load('module', $module); 247 $invoke_modules[] = $module; 248 } 249 } 250 251 if (!empty($invoke_modules)) { 252 // Refresh the module list to include the new enabled module. 253 module_list(TRUE, FALSE); 254 // Force to regenerate the stored list of hook implementations. 255 module_implements('', FALSE, TRUE); 256 cache_clear_all('*', 'cache_menu', TRUE); 257 } 258 259 foreach ($invoke_modules as $module) { 260 module_invoke($module, 'enable'); 261 } 262 } 263 264 /** 265 * Disable a given set of modules. 266 * 267 * @param $module_list 268 * An array of module names. 269 */ 270 function module_disable($module_list) { 271 $invoke_modules = array(); 272 foreach ($module_list as $module) { 273 if (module_exists($module)) { 274 module_load_install($module); 275 module_invoke($module, 'disable'); 276 db_query("UPDATE {system} SET status = 0, throttle = 0 WHERE type = 'module' AND name = '%s'", $module); 277 $invoke_modules[] = $module; 278 } 279 } 280 281 if (!empty($invoke_modules)) { 282 // Refresh the module list to exclude the disabled modules. 283 module_list(TRUE, FALSE); 284 // Force to regenerate the stored list of hook implementations. 285 module_implements('', FALSE, TRUE); 286 cache_clear_all('*', 'cache_menu', TRUE); 287 } 288 } 289 290 /** 291 * @defgroup hooks Hooks 292 * @{ 293 * Allow modules to interact with the Drupal core. 294 * 295 * Drupal's module system is based on the concept of "hooks". A hook is a PHP 296 * function that is named foo_bar(), where "foo" is the name of the module (whose 297 * filename is thus foo.module) and "bar" is the name of the hook. Each hook has 298 * a defined set of parameters and a specified result type. 299 * 300 * To extend Drupal, a module need simply implement a hook. When Drupal wishes to 301 * allow intervention from modules, it determines which modules implement a hook 302 * and call that hook in all enabled modules that implement it. 303 * 304 * The available hooks to implement are explained here in the Hooks section of 305 * the developer documentation. The string "hook" is used as a placeholder for 306 * the module name is the hook definitions. For example, if the module file is 307 * called example.module, then hook_help() as implemented by that module would be 308 * defined as example_help(). 309 */ 310 311 /** 312 * Determine whether a module implements a hook. 313 * 314 * @param $module 315 * The name of the module (without the .module extension). 316 * @param $hook 317 * The name of the hook (e.g. "help" or "menu"). 318 * @return 319 * TRUE if the module is both installed and enabled, and the hook is 320 * implemented in that module. 321 */ 322 function module_hook($module, $hook) { 323 return function_exists($module .'_'. $hook); 324 } 325 326 /** 327 * Determine which modules are implementing a hook. 328 * 329 * @param $hook 330 * The name of the hook (e.g. "help" or "menu"). 331 * @param $sort 332 * By default, modules are ordered by weight and filename, settings this option 333 * to TRUE, module list will be ordered by module name. 334 * @param $refresh 335 * For internal use only: Whether to force the stored list of hook 336 * implementations to be regenerated (such as after enabling a new module, 337 * before processing hook_enable). 338 * @return 339 * An array with the names of the modules which are implementing this hook. 340 */ 341 function module_implements($hook, $sort = FALSE, $refresh = FALSE) { 342 static $implementations; 343 344 if ($refresh) { 345 $implementations = array(); 346 return; 347 } 348 349 if (!isset($implementations[$hook])) { 350 $implementations[$hook] = array(); 351 $list = module_list(FALSE, TRUE, $sort); 352 foreach ($list as $module) { 353 if (module_hook($module, $hook)) { 354 $implementations[$hook][] = $module; 355 } 356 } 357 } 358 359 // The explicit cast forces a copy to be made. This is needed because 360 // $implementations[$hook] is only a reference to an element of 361 // $implementations and if there are nested foreaches (due to nested node 362 // API calls, for example), they would both manipulate the same array's 363 // references, which causes some modules' hooks not to be called. 364 // See also http://www.zend.com/zend/art/ref-count.php. 365 return (array)$implementations[$hook]; 366 } 367 368 /** 369 * Invoke a hook in a particular module. 370 * 371 * @param $module 372 * The name of the module (without the .module extension). 373 * @param $hook 374 * The name of the hook to invoke. 375 * @param ... 376 * Arguments to pass to the hook implementation. 377 * @return 378 * The return value of the hook implementation. 379 */ 380 function module_invoke() { 381 $args = func_get_args(); 382 $module = array_shift($args); 383 $hook = array_shift($args); 384 $function = $module .'_'. $hook; 385 if (module_hook($module, $hook)) { 386 return call_user_func_array($function, $args); 387 } 388 } 389 /** 390 * Invoke a hook in all enabled modules that implement it. 391 * 392 * @param $hook 393 * The name of the hook to invoke. 394 * @param ... 395 * Arguments to pass to the hook. 396 * @return 397 * An array of return values of the hook implementations. If modules return 398 * arrays from their implementations, those are merged into one array. 399 */ 400 function module_invoke_all() { 401 $args = func_get_args(); 402 $hook = array_shift($args); 403 $return = array(); 404 foreach (module_implements($hook) as $module) { 405 $function = $module .'_'. $hook; 406 $result = call_user_func_array($function, $args); 407 if (isset($result) && is_array($result)) { 408 $return = array_merge($return, $result); 409 } 410 else if (isset($result)) { 411 $return[] = $result; 412 } 413 } 414 415 return $return; 416 } 417 418 /** 419 * @} End of "defgroup hooks". 420 */ 421 422
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Nov 30 16:20:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |