diff -u b/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php --- b/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -502,150 +502,161 @@ * {@inheritdoc} */ public function install(array $module_list, $enable_dependencies = TRUE) { - // Get all module data so we can find dependencies and sort. - $module_data = system_rebuild_module_data(); - $module_list = $module_list ? array_combine($module_list, $module_list) : array(); - if (array_diff_key($module_list, $module_data)) { - // One or more of the given modules doesn't exist. - return FALSE; - } - - // Only process currently uninstalled modules. $module_config = \Drupal::config('system.module'); - $installed_modules = $module_config->get('enabled') ?: array(); - if (!$module_list = array_diff_key($module_list, $installed_modules)) { - // Nothing to do. All modules already installed. - return TRUE; - } - - // Conditionally add the dependencies to the list of modules. if ($enable_dependencies) { - // Add dependencies to the list. The new modules will be processed as the - // while loop continues. - while (list($module) = each($module_list)) { - foreach (array_keys($module_data[$module]->requires) as $dependency) { - if (!isset($module_data[$dependency])) { - // The dependency does not exist. - return FALSE; - } + // Get all module data so we can find dependencies and sort. + $module_data = system_rebuild_module_data(); + $module_list = $module_list ? array_combine($module_list, $module_list) : array(); + if (array_diff_key($module_list, $module_data)) { + // One or more of the given modules doesn't exist. + return FALSE; + } + + // Only process currently uninstalled modules. + $installed_modules = $module_config->get('enabled') ?: array(); + if (!$module_list = array_diff_key($module_list, $installed_modules)) { + // Nothing to do. All modules already installed. + return TRUE; + } + + // Conditionally add the dependencies to the list of modules. + if ($enable_dependencies) { + // Add dependencies to the list. The new modules will be processed as the + // while loop continues. + while (list($module) = each($module_list)) { + foreach (array_keys($module_data[$module]->requires) as $dependency) { + if (!isset($module_data[$dependency])) { + // The dependency does not exist. + return FALSE; + } - // Skip already installed modules. - if (!isset($module_list[$dependency]) && !isset($installed_modules[$dependency])) { - $module_list[$dependency] = $dependency; + // Skip already installed modules. + if (!isset($module_list[$dependency]) && !isset($installed_modules[$dependency])) { + $module_list[$dependency] = $dependency; + } } } } - } - - // Set the actual module weights. - $module_list = array_map(function ($module) use ($module_data) { - return $module_data[$module]->sort; - }, $module_list); - // Sort the module list by their weights (reverse). - arsort($module_list); - $module_list = array_keys($module_list); + // Set the actual module weights. + $module_list = array_map(function ($module) use ($module_data) { + return $module_data[$module]->sort; + }, $module_list); + + // Sort the module list by their weights (reverse). + 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(); foreach ($module_list as $module) { - // Throw an exception if the module name is too long. - if (strlen($module) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) { - throw new ExtensionNameLengthException(format_string('Module name %name is over the maximum allowed length of @max characters.', array( - '%name' => $module, - '@max' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, - ))); - } - - $module_config - ->set("enabled.$module", 0) - ->set('enabled', module_config_sort($module_config->get('enabled'))) - ->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])) { - $module_filenames[$name] = $current_module_filenames[$name]; - } - else { - $module_filenames[$name] = drupal_get_filename('module', $name); + $enabled = $module_config->get("enabled.$module") !== NULL; + if (!$enabled) { + // Throw an exception if the module name is too long. + if (strlen($module) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) { + throw new ExtensionNameLengthException(format_string('Module name %name is over the maximum allowed length of @max characters.', array( + '%name' => $module, + '@max' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, + ))); } - } - - // 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(); + $module_config + ->set("enabled.$module", 0) + ->set('enabled', module_config_sort($module_config->get('enabled'))) + ->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])) { + $module_filenames[$name] = $current_module_filenames[$name]; + } + else { + $module_filenames[$name] = drupal_get_filename('module', $name); + } + } - // 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::service('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { - $kernel->updateModules($module_filenames, $module_filenames); - } + // 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::service('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { + $kernel->updateModules($module_filenames, $module_filenames); + } // 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('module_preinstall', array($module)); + // Allow modules to react prior to the installation of a module. + $this->invokeAll('module_preinstall', array($module)); - // Clear the entity info cache before importing new configuration. - entity_info_cache_clear(); + // Clear the entity info cache before importing new configuration. + entity_info_cache_clear(); - // Now install the module's schema if necessary. - drupal_install_schema($module); + // Now install the module's schema if necessary. + 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); + // 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. - watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO); + // Record the fact that it was installed. + $modules_installed[] = $module; + + // Allow the module to perform install tasks. + $this->invoke($module, 'install'); + // Record the fact that it was installed. + watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO); + } } // If any modules were newly installed, invoke hook_modules_installed(). - $this->invokeAll('modules_installed', array($module_list)); + if (!empty($modules_installed)) { + $this->invokeAll('modules_installed', array($modules_installed)); + } return TRUE; }