[ Index ]
 

Code source de Drupal 5.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/includes/ -> module.inc (source)

   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  


Généré le : Fri Nov 30 16:20:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics