public function ModuleHandler::enable

Enables or installs a given list of modules.

Definitions:

  • "Enabling" is the process of activating a module for use by Drupal.
  • "Disabling" is the process of deactivating a module.
  • "Installing" is the process of enabling it for the first time or after it has been uninstalled.
  • "Uninstalling" is the process of removing all traces of a module.

Order of events:

  • Gather and add module dependencies to $module_list (if applicable).
  • For each module that is being enabled:
    • Install module schema and update system registries and caches.
    • If the module is being enabled for the first time or had been uninstalled, invoke hook_install() and add it to the list of installed modules.
    • Invoke hook_enable().
  • Invoke hook_modules_installed().
  • Invoke hook_modules_enabled().

Parameters

$module_list: An array of module names.

$enable_dependencies: If TRUE, dependencies will automatically be added and enabled in the correct order. This incurs a significant performance cost, so use FALSE if you know $module_list is already complete and in the correct order.

Return value

FALSE if one or more dependencies are missing, TRUE otherwise.

Overrides ModuleHandlerInterface::enable

See also

hook_install()

hook_enable()

hook_modules_installed()

hook_modules_enabled()

1 method overrides ModuleHandler::enable()
UpdateModuleHandler::enable in drupal/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
Enables or installs a given list of modules.

File

drupal/core/lib/Drupal/Core/Extension/ModuleHandler.php, line 532
Contains Drupal\Core\Extension\ModuleHandler.

Class

ModuleHandler
Class that manages enabled modules in a Drupal installation.

Namespace

Drupal\Core\Extension

Code

public function enable($module_list, $enable_dependencies = TRUE) {
  if ($enable_dependencies) {

    // Get all module data so we can find dependencies and sort.
    $module_data = system_rebuild_module_data();

    // Create an associative array with weights as values.
    $module_list = array_flip(array_values($module_list));
    while (list($module) = each($module_list)) {
      if (!isset($module_data[$module])) {

        // This module is not found in the filesystem, abort.
        return FALSE;
      }
      if ($module_data[$module]->status) {

        // Skip already enabled modules.
        unset($module_list[$module]);
        continue;
      }
      $module_list[$module] = $module_data[$module]->sort;

      // Add dependencies to the list, with a placeholder weight.
      // The new modules will be processed as the while loop continues.
      foreach (array_keys($module_data[$module]->requires) as $dependency) {
        if (!isset($module_list[$dependency])) {
          $module_list[$dependency] = 0;
        }
      }
    }
    if (!$module_list) {

      // Nothing to do. All modules already enabled.
      return TRUE;
    }

    // Sort the module list by pre-calculated weights.
    arsort($module_list);
    $module_list = array_keys($module_list);
  }

  // Required for module installation checks.
  include_once DRUPAL_ROOT . '/core/includes/install.inc';
  $modules_installed = array();
  $modules_enabled = array();
  $module_config = config('system.module');
  $disabled_config = config('system.module.disabled');
  foreach ($module_list as $module) {

    // Only process modules that are not already enabled.
    // A module is only enabled if it is configured as enabled. Custom or
    // overridden module handlers might contain the module already, which means
    // that it might be loaded, but not necessarily installed or enabled.
    $enabled = $module_config
      ->get("enabled.{$module}") !== NULL;
    if (!$enabled) {
      $weight = $disabled_config
        ->get($module);
      if ($weight === NULL) {
        $weight = 0;
      }
      $module_config
        ->set("enabled.{$module}", $weight)
        ->set('enabled', module_config_sort($module_config
        ->get('enabled')))
        ->save();
      $disabled_config
        ->clear($module)
        ->save();

      // Prepare the new module list, sorted by weight, including filenames.
      // This list is used for both the ModuleHandler and DrupalKernel. It needs
      // to be kept in sync between both. A DrupalKernel reboot or rebuild will
      // automatically re-instantiate a new ModuleHandler that uses the new
      // module list of the kernel. However, DrupalKernel does not cause any
      // modules to be loaded.
      // Furthermore, the currently active (fixed) module list can be different
      // from the configured list of enabled modules. For all active modules not
      // contained in the configured enabled modules, we assume a weight of 0.
      $current_module_filenames = $this
        ->getModuleList();
      $current_modules = array_fill_keys(array_keys($current_module_filenames), 0);
      $current_modules = module_config_sort(array_merge($current_modules, $module_config
        ->get('enabled')));
      $module_filenames = array();
      foreach ($current_modules as $name => $weight) {
        if (isset($current_module_filenames[$name])) {
          $filename = $current_module_filenames[$name];
        }
        else {
          $filename = drupal_get_filename('module', $name);
        }
        $module_filenames[$name] = $filename;
      }

      // Update the module handler in order to load the module's code.
      // This allows the module to participate in hooks and its existence to be
      // discovered by other modules.
      // The current ModuleHandler instance is obsolete with the kernel rebuild
      // below.
      $this
        ->setModuleList($module_filenames);
      $this
        ->load($module);
      module_load_install($module);

      // Flush theme info caches, since (testing) modules can implement
      // hook_system_theme_info() to register additional themes.
      system_list_reset();

      // Update the kernel to include it.
      // This reboots the kernel to register the module's bundle and its
      // services in the service container. The $module_filenames argument is
      // taken over as %container.modules% parameter, which is passed to a fresh
      // ModuleHandler instance upon first retrieval.
      // @todo install_begin_request() creates a container without a kernel.
      if ($kernel = drupal_container()
        ->get('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
        $kernel
          ->updateModules($module_filenames, $module_filenames);
      }

      // Refresh the list of modules that implement bootstrap hooks.
      // @see bootstrap_hooks()
      _system_update_bootstrap_status();

      // Refresh the schema to include it.
      drupal_get_schema(NULL, TRUE);

      // Update the theme registry to include it.
      drupal_theme_rebuild();

      // Allow modules to react prior to the installation of a module.
      $this
        ->invokeAll('modules_preinstall', array(
        array(
          $module,
        ),
      ));

      // Clear the entity info cache before importing new configuration.
      entity_info_cache_clear();

      // Now install the module if necessary.
      if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
        drupal_install_schema($module);

        // Set the schema version to the number of the last update provided
        // by the module.
        $versions = drupal_get_schema_versions($module);
        $version = $versions ? max($versions) : SCHEMA_INSTALLED;

        // Install default configuration of the module.
        config_install_default_config('module', $module);

        // If the module has no current updates, but has some that were
        // previously removed, set the version to the value of
        // hook_update_last_removed().
        if ($last_removed = $this
          ->invoke($module, 'update_last_removed')) {
          $version = max($version, $last_removed);
        }
        drupal_set_installed_schema_version($module, $version);

        // Allow the module to perform install tasks.
        $this
          ->invoke($module, 'install');

        // Record the fact that it was installed.
        $modules_installed[] = $module;
        watchdog('system', '%module module installed.', array(
          '%module' => $module,
        ), WATCHDOG_INFO);
      }

      // Allow modules to react prior to the enabling of a module.
      entity_info_cache_clear();
      $this
        ->invokeAll('modules_preenable', array(
        array(
          $module,
        ),
      ));

      // Enable the module.
      $this
        ->invoke($module, 'enable');

      // Record the fact that it was enabled.
      $modules_enabled[] = $module;
      watchdog('system', '%module module enabled.', array(
        '%module' => $module,
      ), WATCHDOG_INFO);
    }
  }

  // If any modules were newly installed, invoke hook_modules_installed().
  if (!empty($modules_installed)) {
    $this
      ->invokeAll('modules_installed', array(
      $modules_installed,
    ));
  }

  // If any modules were newly enabled, invoke hook_modules_enabled().
  if (!empty($modules_enabled)) {
    $this
      ->invokeAll('modules_enabled', array(
      $modules_enabled,
    ));
  }
  return TRUE;
}