diff --git a/core/core.services.yml b/core/core.services.yml index ee98820..6954b56 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -288,7 +288,10 @@ services: arguments: ['@container.namespaces', '@cache.discovery', '@module_handler'] module_handler: class: Drupal\Core\Extension\ModuleHandler - arguments: ['@app.root', '%container.modules%', '@kernel', '@cache.bootstrap'] + arguments: ['@app.root', '%container.modules%', '@cache.bootstrap'] + module_installer: + class: Drupal\Core\Extension\ModuleInstaller + arguments: ['@app.root', '@module_handler', '@kernel'] theme_handler: class: Drupal\Core\Extension\ThemeHandler arguments: ['@app.root', '@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator'] diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 70ea333..968192e 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -978,7 +978,7 @@ function install_base_system(&$install_state) { // Enable the user module so that sessions can be recorded during the // upcoming bootstrap step. - \Drupal::moduleHandler()->install(array('user'), FALSE); + \Drupal::service('module_installer')->install(array('user'), FALSE); // Save the list of other modules to install for the upcoming tasks. // State can be set to the database now that system.module is installed. @@ -1797,7 +1797,7 @@ function _install_module_batch($module, $module_name, &$context) { // loaded by drupal_bootstrap in subsequent batch requests, and other // modules possibly depending on it can safely perform their installation // steps. - \Drupal::moduleHandler()->install(array($module), FALSE); + \Drupal::service('module_installer')->install(array($module), FALSE); $context['results'][] = $module; $context['message'] = t('Installed %module module.', array('%module' => $module_name)); } diff --git a/core/includes/install.inc b/core/includes/install.inc index ead2104..1038818 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -615,7 +615,7 @@ function drupal_install_system($install_state) { \Drupal::service('config.installer')->installDefaultConfig('core', 'core'); // Install System module and rebuild the newly available routes. - $kernel->getContainer()->get('module_handler')->install(array('system'), FALSE); + $kernel->getContainer()->get('module_installer')->install(array('system'), FALSE); \Drupal::service('router.builder')->rebuild(); // Ensure default language is saved. diff --git a/core/includes/module.inc b/core/includes/module.inc index 606d813..ff11244 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -157,10 +157,10 @@ function module_load_include($type, $module, $name = NULL) { * @see \Drupal\Core\Extension\ModuleHandlerInterface::install() * * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. Use - * \Drupal::moduleHandler()->install($module_list, $enable_dependencies = TRUE). + * \Drupal::service('module_installer')->install($module_list, $enable_dependencies = TRUE). */ function module_install($module_list, $enable_dependencies = TRUE) { - return \Drupal::moduleHandler()->install($module_list, $enable_dependencies); + return \Drupal::service('module_installer')->install($module_list, $enable_dependencies); } /** @@ -169,10 +169,10 @@ function module_install($module_list, $enable_dependencies = TRUE) { * @see \Drupal\Core\Extension\ModuleHandlerInterface::module_install() * * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. Use - * \Drupal::moduleHandler()->uninstall($module_list, $enable_dependencies = TRUE). + * \Drupal::service('module_installer')->uninstall($module_list, $enable_dependencies = TRUE). */ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE) { - return \Drupal::moduleHandler()->uninstall($module_list, $uninstall_dependents); + return \Drupal::service('module_installer')->uninstall($module_list, $uninstall_dependents); } /** diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php index a13a414..007282e 100644 --- a/core/lib/Drupal/Core/Config/ConfigImporter.php +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Config; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ModuleInstallerInterface; use Drupal\Core\Extension\ThemeHandlerInterface; use Drupal\Component\Utility\String; use Drupal\Core\Config\Entity\ImportableEntityStorageInterface; @@ -156,6 +157,13 @@ class ConfigImporter { protected $totalConfigurationToProcess = 0; /** + * The module installer. + * + * @var \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected $moduleInstaller; + + /** * Constructs a configuration import object. * * @param \Drupal\Core\Config\StorageComparerInterface $storage_comparer @@ -171,18 +179,21 @@ class ConfigImporter { * The typed configuration manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler + * @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer + * The module installer. * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler * The theme handler * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation * The string translation service. */ - public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, LockBackendInterface $lock, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, TranslationInterface $string_translation) { + public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, LockBackendInterface $lock, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler, TranslationInterface $string_translation) { $this->storageComparer = $storage_comparer; $this->eventDispatcher = $event_dispatcher; $this->configManager = $config_manager; $this->lock = $lock; $this->typedConfigManager = $typed_config; $this->moduleHandler = $module_handler; + $this->moduleInstaller = $module_installer; $this->themeHandler = $theme_handler; $this->stringTranslation = $string_translation; foreach ($this->storageComparer->getAllCollectionNames() as $collection) { @@ -750,7 +761,7 @@ protected function processExtension($type, $op, $name) { ->setSyncing(TRUE) ->setSourceStorage($this->storageComparer->getSourceStorage()); if ($type == 'module') { - $this->moduleHandler->$op(array($name), FALSE); + $this->moduleInstaller->$op(array($name), FALSE); // Installing a module can cause a kernel boot therefore reinject all the // services. $this->reInjectMe(); diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index 12d2805..c24b9f4 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -8,11 +8,9 @@ namespace Drupal\Core\Extension; use Drupal\Component\Graph\Graph; -use Drupal\Component\Serialization\Yaml; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\String; use Drupal\Core\Cache\CacheBackendInterface; -use Drupal\Core\DrupalKernelInterface; /** * Class that manages modules in a Drupal installation. @@ -65,13 +63,6 @@ class ModuleHandler implements ModuleHandlerInterface { protected $hookInfo; /** - * The drupal kernel. - * - * @var \Drupal\Core\DrupalKernelInterface - */ - protected $kernel; - - /** * Cache backend for storing module hook implementation information. * * @var \Drupal\Core\Cache\CacheBackendInterface @@ -108,21 +99,18 @@ class ModuleHandler implements ModuleHandlerInterface { * An associative array whose keys are the names of installed modules and * whose values are Extension class parameters. This is normally the * %container.modules% parameter being set up by DrupalKernel. - * @param \Drupal\Core\DrupalKernelInterface $kernel - * The drupal kernel. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend for storing module hook implementation information. * * @see \Drupal\Core\DrupalKernel * @see \Drupal\Core\CoreServiceProvider */ - public function __construct($root, array $module_list = array(), DrupalKernelInterface $kernel, CacheBackendInterface $cache_backend) { + public function __construct($root, array $module_list = array(), CacheBackendInterface $cache_backend) { $this->root = $root; $this->moduleList = array(); foreach ($module_list as $name => $module) { $this->moduleList[$name] = new Extension($this->root, $module['type'], $module['pathname'], $module['filename']); } - $this->kernel = $kernel; $this->cacheBackend = $cache_backend; } @@ -701,388 +689,6 @@ public static function parseDependency($dependency) { /** * {@inheritdoc} */ - public function install(array $module_list, $enable_dependencies = TRUE) { - $extension_config = \Drupal::config('core.extension'); - if ($enable_dependencies) { - // 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 = $extension_config->get('module') ?: array(); - if (!$module_list = array_diff_key($module_list, $installed_modules)) { - // Nothing to do. All modules already installed. - return TRUE; - } - - // 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; - } - } - } - - // 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 $this->root . '/core/includes/install.inc'; - - /** @var \Drupal\Core\Config\ConfigInstaller $config_installer */ - $config_installer = \Drupal::service('config.installer'); - $sync_status = $config_installer->isSyncing(); - if ($sync_status) { - $source_storage = $config_installer->getSourceStorage(); - } - $modules_installed = array(); - foreach ($module_list as $module) { - $enabled = $extension_config->get("module.$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, - ))); - } - - $extension_config - ->set("module.$module", 0) - ->set('module', module_config_sort($extension_config->get('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, $extension_config->get('module'))); - $module_filenames = array(); - foreach ($current_modules as $name => $weight) { - if (isset($current_module_filenames[$name])) { - $module_filenames[$name] = $current_module_filenames[$name]; - } - else { - $module_path = drupal_get_path('module', $name); - $pathname = "$module_path/$name.info.yml"; - $filename = file_exists($module_path . "/$name.module") ? "$name.module" : NULL; - $module_filenames[$name] = new Extension($this->root, 'module', $pathname, $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); - - // Clear the static cache of system_rebuild_module_data() to pick up the - // new module, since it merges the installation status of modules into - // its statically cached list. - drupal_static_reset('system_rebuild_module_data'); - - // Update the kernel to include it. - $this->updateKernel($module_filenames); - - // Refresh the schema to include it. - drupal_get_schema(NULL, TRUE); - - // Allow modules to react prior to the installation of a module. - $this->invokeAll('module_preinstall', array($module)); - - // Now install the module's schema if necessary. - drupal_install_schema($module); - - // Clear plugin manager caches and flag router to rebuild if requested. - \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions(); - \Drupal::service('router.builder_indicator')->setRebuildNeeded(); - - // Set the schema version to the number of the last update provided by - // the module, or the minimum core schema version. - $version = \Drupal::CORE_MINIMUM_SCHEMA_VERSION; - $versions = drupal_get_schema_versions($module); - if ($versions) { - $version = max(max($versions), $version); - } - - // Notify interested components that this module's entity types are new. - // For example, a SQL-based storage handler can use this as an - // opportunity to create the necessary database tables. - // @todo Clean this up in https://www.drupal.org/node/2350111. - $entity_manager = \Drupal::entityManager(); - foreach ($entity_manager->getDefinitions() as $entity_type) { - if ($entity_type->getProvider() == $module) { - $entity_manager->onEntityTypeCreate($entity_type); - } - } - - // Install default configuration of the module. - $config_installer = \Drupal::service('config.installer'); - if ($sync_status) { - $config_installer - ->setSyncing(TRUE) - ->setSourceStorage($source_storage); - } - else { - // If we're not in a config synchronisation reset the source storage - // so that the extension install storage will pick up the new - // configuration. - $config_installer->resetSourceStorage(); - } - \Drupal::service('config.installer')->installDefaultConfig('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); - - // Record the fact that it was installed. - $modules_installed[] = $module; - - // file_get_stream_wrappers() needs to re-register Drupal's stream - // wrappers in case a module-provided stream wrapper is used later in - // the same request. In particular, this happens when installing Drupal - // via Drush, as the 'translations' stream wrapper is provided by - // Interface Translation module and is later used to import - // translations. - \Drupal::service('stream_wrapper_manager')->register(); - - // Update the theme registry to include it. - drupal_theme_rebuild(); - - // Modules can alter theme info, so refresh theme data. - // @todo ThemeHandler cannot be injected into ModuleHandler, since that - // causes a circular service dependency. - // @see https://drupal.org/node/2208429 - \Drupal::service('theme_handler')->refreshInfo(); - - // Allow the module to perform install tasks. - $this->invoke($module, 'install'); - - // Record the fact that it was installed. - \Drupal::logger('system')->info('%module module installed.', array('%module' => $module)); - } - } - - // If any modules were newly installed, invoke hook_modules_installed(). - if (!empty($modules_installed)) { - $this->invokeAll('modules_installed', array($modules_installed)); - } - - return TRUE; - } - - /** - * {@inheritdoc} - */ - public function uninstall(array $module_list, $uninstall_dependents = 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 installed modules. - $extension_config = \Drupal::config('core.extension'); - $installed_modules = $extension_config->get('module') ?: array(); - if (!$module_list = array_intersect_key($module_list, $installed_modules)) { - // Nothing to do. All modules already uninstalled. - return TRUE; - } - - if ($uninstall_dependents) { - // Add dependent modules to the list. The new modules will be processed as - // the while loop continues. - $profile = drupal_get_profile(); - while (list($module) = each($module_list)) { - foreach (array_keys($module_data[$module]->required_by) as $dependent) { - if (!isset($module_data[$dependent])) { - // The dependent module does not exist. - return FALSE; - } - - // Skip already uninstalled modules. - if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) { - $module_list[$dependent] = $dependent; - } - } - } - } - - // 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. - asort($module_list); - $module_list = array_keys($module_list); - - // Only process modules that are 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. - $schema_store = \Drupal::keyValue('system.schema'); - $entity_manager = \Drupal::entityManager(); - foreach ($module_list as $module) { - - // Clean up all entity bundles (including fields) of every entity type - // provided by the module that is being uninstalled. - // @todo Clean this up in https://www.drupal.org/node/2350111. - foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) { - if ($entity_type->getProvider() == $module) { - foreach (array_keys($entity_manager->getBundleInfo($entity_type_id)) as $bundle) { - $entity_manager->onBundleDelete($bundle, $entity_type_id); - } - } - } - - // Allow modules to react prior to the uninstallation of a module. - $this->invokeAll('module_preuninstall', array($module)); - - // Uninstall the module. - module_load_install($module); - $this->invoke($module, 'uninstall'); - - // Remove all configuration belonging to the module. - \Drupal::service('config.manager')->uninstall('module', $module); - - // Notify interested components that this module's entity types are being - // deleted. For example, a SQL-based storage handler can use this as an - // opportunity to drop the corresponding database tables. - // @todo Clean this up in https://www.drupal.org/node/2350111. - foreach ($entity_manager->getDefinitions() as $entity_type) { - if ($entity_type->getProvider() == $module) { - $entity_manager->onEntityTypeDelete($entity_type); - } - } - - // Remove the schema. - drupal_uninstall_schema($module); - - // Remove the module's entry from the config. - $extension_config->clear("module.$module")->save(); - - // Update the module handler to remove the module. - // The current ModuleHandler instance is obsolete with the kernel rebuild - // below. - $module_filenames = $this->getModuleList(); - unset($module_filenames[$module]); - $this->setModuleList($module_filenames); - - // Remove any potential cache bins provided by the module. - $this->removeCacheBins($module); - - // Clear the static cache of system_rebuild_module_data() to pick up the - // new module, since it merges the installation status of modules into - // its statically cached list. - drupal_static_reset('system_rebuild_module_data'); - - // Clear plugin manager caches and flag router to rebuild if requested. - \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions(); - \Drupal::service('router.builder_indicator')->setRebuildNeeded(); - - // Update the kernel to exclude the uninstalled modules. - $this->updateKernel($module_filenames); - - // Update the theme registry to remove the newly uninstalled module. - drupal_theme_rebuild(); - - // Modules can alter theme info, so refresh theme data. - // @todo ThemeHandler cannot be injected into ModuleHandler, since that - // causes a circular service dependency. - // @see https://drupal.org/node/2208429 - \Drupal::service('theme_handler')->refreshInfo(); - - \Drupal::logger('system')->info('%module module uninstalled.', array('%module' => $module)); - - $schema_store->delete($module); - } - drupal_get_installed_schema_version(NULL, TRUE); - - // Let other modules react. - $this->invokeAll('modules_uninstalled', array($module_list)); - - return TRUE; - } - - /** - * Helper method for removing all cache bins registered by a given module. - * - * @param string $module - * The name of the module for which to remove all registered cache bins. - */ - protected function removeCacheBins($module) { - // Remove any cache bins defined by a module. - $service_yaml_file = drupal_get_path('module', $module) . "/$module.services.yml"; - if (file_exists($service_yaml_file)) { - $definitions = Yaml::decode(file_get_contents($service_yaml_file)); - if (isset($definitions['services'])) { - foreach ($definitions['services'] as $id => $definition) { - if (isset($definition['tags'])) { - foreach ($definition['tags'] as $tag) { - // This works for the default cache registration and even in some - // cases when a non-default "super" factory is used. That should - // be extremely rare. - if ($tag['name'] == 'cache.bin' && isset($definition['factory_service']) && isset($definition['factory_method']) && !empty($definition['arguments'])) { - try { - $factory = \Drupal::service($definition['factory_service']); - if (method_exists($factory, $definition['factory_method'])) { - $backend = call_user_func_array(array($factory, $definition['factory_method']), $definition['arguments']); - if ($backend instanceof CacheBackendInterface) { - $backend->removeBin(); - } - } - } - catch (\Exception $e) { - watchdog_exception('system', $e, 'Failed to remove cache bin defined by the service %id.', array('%id' => $id)); - } - } - } - } - } - } - } - } - - /** - * {@inheritdoc} - */ public function getModuleDirectories() { $dirs = array(); foreach ($this->getModuleList() as $name => $module) { @@ -1099,22 +705,4 @@ public function getName($module) { return $module_data[$module]->info['name']; } - /** - * Updates the kernel module list. - * - * @param string $module_filenames - * The list of installed modules. - */ - protected function updateKernel($module_filenames) { - // 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. - $this->kernel->updateModules($module_filenames, $module_filenames); - // After rebuilding the container we need to update the injected - // dependencies. - $container = $this->kernel->getContainer(); - $this->cacheBackend = $container->get('cache.bootstrap'); - } - } diff --git a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php index 48b5760..f6c7be5 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php @@ -293,52 +293,6 @@ public function invokeAll($hook, array $args = array()); public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL); /** - * Installs a given list of modules. - * - * Order of events: - * - Gather and add module dependencies to $module_list (if applicable). - * - For each module that is being installed: - * - Invoke hook_module_preinstall(). - * - Install module schema and update system registries and caches. - * - Invoke hook_install() and add it to the list of installed modules. - * - Invoke hook_modules_installed(). - * - * @param array $module_list - * An array of module names. - * @param bool $enable_dependencies - * (optional) If TRUE, dependencies will automatically be installed in the - * correct order. This incurs a significant performance cost, so use FALSE - * if you know $module_list is already complete. - * - * @return bool - * FALSE if one or more dependencies are missing, TRUE otherwise. - * - * @see hook_module_preinstall() - * @see hook_install() - * @see hook_modules_installed() - */ - public function install(array $module_list, $enable_dependencies = TRUE); - - /** - * Uninstalls a given list of disabled modules. - * - * @param array $module_list - * The modules to uninstall. - * @param bool $uninstall_dependents - * (optional) If TRUE, dependent modules will automatically be uninstalled - * in the correct order. This incurs a significant performance cost, so use - * FALSE if you know $module_list is already complete. - * - * @return bool - * FALSE if one or more dependencies are missing, TRUE otherwise. - * - * @see hook_module_preuninstall() - * @see hook_uninstall() - * @see hook_modules_uninstalled() - */ - public function uninstall(array $module_list, $uninstall_dependents = TRUE); - - /** * Returns an array of directories for all enabled modules. Useful for * tasks such as finding a file that exists in all module directories. * diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php new file mode 100644 index 0000000..f074ed3 --- /dev/null +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php @@ -0,0 +1,463 @@ +root = $root; + $this->moduleHandler = $module_handler; + $this->kernel = $kernel; + } + + /** + * {@inheritdoc} + */ + public function install(array $module_list, $enable_dependencies = TRUE) { + $extension_config = \Drupal::config('core.extension'); + if ($enable_dependencies) { + // 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 = $extension_config->get('module') ?: array(); + if (!$module_list = array_diff_key($module_list, $installed_modules)) { + // Nothing to do. All modules already installed. + return TRUE; + } + + // 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; + } + } + } + + // 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 $this->root . '/core/includes/install.inc'; + + /** @var \Drupal\Core\Config\ConfigInstaller $config_installer */ + $config_installer = \Drupal::service('config.installer'); + $sync_status = $config_installer->isSyncing(); + if ($sync_status) { + $source_storage = $config_installer->getSourceStorage(); + } + $modules_installed = array(); + foreach ($module_list as $module) { + $enabled = $extension_config->get("module.$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, + ))); + } + + $extension_config + ->set("module.$module", 0) + ->set('module', module_config_sort($extension_config->get('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->moduleHandler->getModuleList(); + $current_modules = array_fill_keys(array_keys($current_module_filenames), 0); + $current_modules = module_config_sort(array_merge($current_modules, $extension_config->get('module'))); + $module_filenames = array(); + foreach ($current_modules as $name => $weight) { + if (isset($current_module_filenames[$name])) { + $module_filenames[$name] = $current_module_filenames[$name]; + } + else { + $module_path = drupal_get_path('module', $name); + $pathname = "$module_path/$name.info.yml"; + $filename = file_exists($module_path . "/$name.module") ? "$name.module" : NULL; + $module_filenames[$name] = new Extension($this->root, 'module', $pathname, $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->moduleHandler->setModuleList($module_filenames); + $this->moduleHandler->load($module); + module_load_install($module); + + // Clear the static cache of system_rebuild_module_data() to pick up the + // new module, since it merges the installation status of modules into + // its statically cached list. + drupal_static_reset('system_rebuild_module_data'); + + // Update the kernel to include it. + $this->updateKernel($module_filenames); + + // Refresh the schema to include it. + drupal_get_schema(NULL, TRUE); + + // Allow modules to react prior to the installation of a module. + $this->moduleHandler->invokeAll('module_preinstall', array($module)); + + // Now install the module's schema if necessary. + drupal_install_schema($module); + + // Clear plugin manager caches and flag router to rebuild if requested. + \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions(); + \Drupal::service('router.builder_indicator')->setRebuildNeeded(); + + // Set the schema version to the number of the last update provided by + // the module, or the minimum core schema version. + $version = \Drupal::CORE_MINIMUM_SCHEMA_VERSION; + $versions = drupal_get_schema_versions($module); + if ($versions) { + $version = max(max($versions), $version); + } + + // Notify interested components that this module's entity types are new. + // For example, a SQL-based storage handler can use this as an + // opportunity to create the necessary database tables. + // @todo Clean this up in https://www.drupal.org/node/2350111. + $entity_manager = \Drupal::entityManager(); + foreach ($entity_manager->getDefinitions() as $entity_type) { + if ($entity_type->getProvider() == $module) { + $entity_manager->onEntityTypeCreate($entity_type); + } + } + + // Install default configuration of the module. + $config_installer = \Drupal::service('config.installer'); + if ($sync_status) { + $config_installer + ->setSyncing(TRUE) + ->setSourceStorage($source_storage); + } + else { + // If we're not in a config synchronisation reset the source storage + // so that the extension install storage will pick up the new + // configuration. + $config_installer->resetSourceStorage(); + } + \Drupal::service('config.installer')->installDefaultConfig('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->moduleHandler->invoke($module, 'update_last_removed')) { + $version = max($version, $last_removed); + } + drupal_set_installed_schema_version($module, $version); + + // Record the fact that it was installed. + $modules_installed[] = $module; + + // file_get_stream_wrappers() needs to re-register Drupal's stream + // wrappers in case a module-provided stream wrapper is used later in + // the same request. In particular, this happens when installing Drupal + // via Drush, as the 'translations' stream wrapper is provided by + // Interface Translation module and is later used to import + // translations. + \Drupal::service('stream_wrapper_manager')->register(); + + // Update the theme registry to include it. + drupal_theme_rebuild(); + + // Modules can alter theme info, so refresh theme data. + // @todo ThemeHandler cannot be injected into ModuleHandler, since that + // causes a circular service dependency. + // @see https://drupal.org/node/2208429 + \Drupal::service('theme_handler')->refreshInfo(); + + // Allow the module to perform install tasks. + $this->moduleHandler->invoke($module, 'install'); + + // Record the fact that it was installed. + \Drupal::logger('system')->info('%module module installed.', array('%module' => $module)); + } + } + + // If any modules were newly installed, invoke hook_modules_installed(). + if (!empty($modules_installed)) { + $this->moduleHandler->invokeAll('modules_installed', array($modules_installed)); + } + + return TRUE; + } + + /** + * {@inheritdoc} + */ + public function uninstall(array $module_list, $uninstall_dependents = 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 installed modules. + $extension_config = \Drupal::config('core.extension'); + $installed_modules = $extension_config->get('module') ?: array(); + if (!$module_list = array_intersect_key($module_list, $installed_modules)) { + // Nothing to do. All modules already uninstalled. + return TRUE; + } + + if ($uninstall_dependents) { + // Add dependent modules to the list. The new modules will be processed as + // the while loop continues. + $profile = drupal_get_profile(); + while (list($module) = each($module_list)) { + foreach (array_keys($module_data[$module]->required_by) as $dependent) { + if (!isset($module_data[$dependent])) { + // The dependent module does not exist. + return FALSE; + } + + // Skip already uninstalled modules. + if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) { + $module_list[$dependent] = $dependent; + } + } + } + } + + // 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. + asort($module_list); + $module_list = array_keys($module_list); + + // Only process modules that are 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. + foreach ($module_list as $module) { + + // Clean up all entity bundles (including fields) of every entity type + // provided by the module that is being uninstalled. + // @todo Clean this up in https://www.drupal.org/node/2350111. + $entity_manager = \Drupal::entityManager(); + foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) { + if ($entity_type->getProvider() == $module) { + foreach (array_keys($entity_manager->getBundleInfo($entity_type_id)) as $bundle) { + $entity_manager->onBundleDelete($bundle, $entity_type_id); + } + } + } + + // Allow modules to react prior to the uninstallation of a module. + $this->moduleHandler->invokeAll('module_preuninstall', array($module)); + + // Uninstall the module. + module_load_install($module); + $this->moduleHandler->invoke($module, 'uninstall'); + + // Remove all configuration belonging to the module. + \Drupal::service('config.manager')->uninstall('module', $module); + + // Notify interested components that this module's entity types are being + // deleted. For example, a SQL-based storage handler can use this as an + // opportunity to drop the corresponding database tables. + // @todo Clean this up in https://www.drupal.org/node/2350111. + foreach ($entity_manager->getDefinitions() as $entity_type) { + if ($entity_type->getProvider() == $module) { + $entity_manager->onEntityTypeDelete($entity_type); + } + } + + // Remove the schema. + drupal_uninstall_schema($module); + + // Remove the module's entry from the config. + $extension_config = \Drupal::config('core.extension'); + $extension_config->clear("module.$module")->save(); + + // Update the module handler to remove the module. + // The current ModuleHandler instance is obsolete with the kernel rebuild + // below. + $module_filenames = $this->moduleHandler->getModuleList(); + unset($module_filenames[$module]); + $this->moduleHandler->setModuleList($module_filenames); + + // Remove any potential cache bins provided by the module. + $this->removeCacheBins($module); + + // Clear the static cache of system_rebuild_module_data() to pick up the + // new module, since it merges the installation status of modules into + // its statically cached list. + drupal_static_reset('system_rebuild_module_data'); + + // Clear plugin manager caches and flag router to rebuild if requested. + \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions(); + \Drupal::service('router.builder_indicator')->setRebuildNeeded(); + + // Update the kernel to exclude the uninstalled modules. + $this->updateKernel($module_filenames); + + // Update the theme registry to remove the newly uninstalled module. + drupal_theme_rebuild(); + + // Modules can alter theme info, so refresh theme data. + // @todo ThemeHandler cannot be injected into ModuleHandler, since that + // causes a circular service dependency. + // @see https://drupal.org/node/2208429 + \Drupal::service('theme_handler')->refreshInfo(); + + \Drupal::logger('system')->info('%module module uninstalled.', array('%module' => $module)); + + $schema_store = \Drupal::keyValue('system.schema'); + $schema_store->delete($module); + } + drupal_get_installed_schema_version(NULL, TRUE); + + // Let other modules react. + $this->moduleHandler->invokeAll('modules_uninstalled', array($module_list)); + + return TRUE; + } + + /** + * Helper method for removing all cache bins registered by a given module. + * + * @param string $module + * The name of the module for which to remove all registered cache bins. + */ + protected function removeCacheBins($module) { + // Remove any cache bins defined by a module. + $service_yaml_file = drupal_get_path('module', $module) . "/$module.services.yml"; + if (file_exists($service_yaml_file)) { + $definitions = Yaml::decode(file_get_contents($service_yaml_file)); + if (isset($definitions['services'])) { + foreach ($definitions['services'] as $id => $definition) { + if (isset($definition['tags'])) { + foreach ($definition['tags'] as $tag) { + // This works for the default cache registration and even in some + // cases when a non-default "super" factory is used. That should + // be extremely rare. + if ($tag['name'] == 'cache.bin' && isset($definition['factory_service']) && isset($definition['factory_method']) && !empty($definition['arguments'])) { + try { + $factory = \Drupal::service($definition['factory_service']); + if (method_exists($factory, $definition['factory_method'])) { + $backend = call_user_func_array(array($factory, $definition['factory_method']), $definition['arguments']); + if ($backend instanceof CacheBackendInterface) { + $backend->removeBin(); + } + } + } + catch (\Exception $e) { + watchdog_exception('system', $e, 'Failed to remove cache bin defined by the service %id.', array('%id' => $id)); + } + } + } + } + } + } + } + } + + /** + * Updates the kernel module list. + * + * @param string $module_filenames + * The list of installed modules. + */ + protected function updateKernel($module_filenames) { + // 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. + $this->kernel->updateModules($module_filenames, $module_filenames); + // After rebuilding the container we need to update the injected + // dependencies. + $container = $this->kernel->getContainer(); + $this->moduleHandler = $container->get('module_handler'); + } + +} diff --git a/core/lib/Drupal/Core/Extension/ModuleInstallerInterface.php b/core/lib/Drupal/Core/Extension/ModuleInstallerInterface.php new file mode 100644 index 0000000..246af4b --- /dev/null +++ b/core/lib/Drupal/Core/Extension/ModuleInstallerInterface.php @@ -0,0 +1,62 @@ +root = $root; $this->userStorage = $user_storage; $this->state = $state; - $this->moduleHandler = $module_handler; + $this->moduleInstaller = $module_installer; $this->countryManager = $country_manager; } @@ -85,7 +85,7 @@ public static function create(ContainerInterface $container) { $container->get('app.root'), $container->get('entity.manager')->getStorage('user'), $container->get('state'), - $container->get('module_handler'), + $container->get('module_installer'), $container->get('country_manager') ); } @@ -264,7 +264,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Enable update.module if this option was selected. $update_status_module = $form_state->getValue('update_status_module'); if ($update_status_module[1]) { - $this->moduleHandler->install(array('file', 'update'), FALSE); + $this->moduleInstaller->install(array('file', 'update'), FALSE); // Add the site maintenance account's email address to the list of // addresses to be notified when updates are available, if selected. diff --git a/core/modules/action/src/Tests/ActionUninstallTest.php b/core/modules/action/src/Tests/ActionUninstallTest.php index de8e4e6..bec61d1 100644 --- a/core/modules/action/src/Tests/ActionUninstallTest.php +++ b/core/modules/action/src/Tests/ActionUninstallTest.php @@ -28,7 +28,7 @@ class ActionUninstallTest extends WebTestBase { * Tests Action uninstall. */ public function testActionUninstall() { - \Drupal::moduleHandler()->uninstall(array('action')); + \Drupal::service('module_installer')->uninstall(array('action')); $this->assertTrue(entity_load('action', 'user_block_user_action', TRUE), 'Configuration entity \'user_block_user_action\' still exists after uninstalling action module.' ); diff --git a/core/modules/aggregator/src/Tests/AggregatorConfigurationTest.php b/core/modules/aggregator/src/Tests/AggregatorConfigurationTest.php index b791d20..7e1b6ef 100644 --- a/core/modules/aggregator/src/Tests/AggregatorConfigurationTest.php +++ b/core/modules/aggregator/src/Tests/AggregatorConfigurationTest.php @@ -54,7 +54,7 @@ function testSettingsPage() { // Make sure settings form is still accessible even after uninstalling a module // that provides the selected plugins. - $this->container->get('module_handler')->uninstall(array('aggregator_test')); + $this->container->get('module_installer')->uninstall(array('aggregator_test')); $this->resetAll(); $this->drupalGet('admin/config/services/aggregator/settings'); $this->assertResponse(200); diff --git a/core/modules/aggregator/src/Tests/UpdateFeedItemTest.php b/core/modules/aggregator/src/Tests/UpdateFeedItemTest.php index b929249..046fd70 100644 --- a/core/modules/aggregator/src/Tests/UpdateFeedItemTest.php +++ b/core/modules/aggregator/src/Tests/UpdateFeedItemTest.php @@ -67,7 +67,7 @@ function testUpdateFeedItem() { // Make sure updating items works even after uninstalling a module // that provides the selected plugins. $this->enableTestPlugins(); - $this->container->get('module_handler')->uninstall(array('aggregator_test')); + $this->container->get('module_installer')->uninstall(array('aggregator_test')); $this->updateFeedItems($feed); $this->assertResponse(200); } diff --git a/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php b/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php index 7a0fd65..c49cf78 100644 --- a/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php +++ b/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php @@ -160,7 +160,7 @@ function testExistingFormat() { // Now enable the ckeditor_test module, which provides one configurable // CKEditor plugin — this should not affect the Editor config entity. - \Drupal::moduleHandler()->install(array('ckeditor_test')); + \Drupal::service('module_installer')->install(array('ckeditor_test')); $this->resetAll(); $this->container->get('plugin.manager.ckeditor.plugin')->clearCachedDefinitions(); $this->drupalGet('admin/config/content/formats/manage/filtered_html'); diff --git a/core/modules/ckeditor/src/Tests/CKEditorLoadingTest.php b/core/modules/ckeditor/src/Tests/CKEditorLoadingTest.php index 7f51130..ba2fa4b 100644 --- a/core/modules/ckeditor/src/Tests/CKEditorLoadingTest.php +++ b/core/modules/ckeditor/src/Tests/CKEditorLoadingTest.php @@ -115,7 +115,7 @@ function testLoading() { // NOTE: the tests in CKEditorTest already ensure that changing the // configuration also results in modified CKEditor configuration, so we // don't test that here. - \Drupal::moduleHandler()->install(array('ckeditor_test')); + \Drupal::service('module_installer')->install(array('ckeditor_test')); $this->resetAll(); $this->container->get('plugin.manager.ckeditor.plugin')->clearCachedDefinitions(); $editor_settings = $editor->getSettings(); diff --git a/core/modules/comment/src/Tests/CommentTitleTest.php b/core/modules/comment/src/Tests/CommentTitleTest.php index 6d8c96f..6d64378 100644 --- a/core/modules/comment/src/Tests/CommentTitleTest.php +++ b/core/modules/comment/src/Tests/CommentTitleTest.php @@ -19,7 +19,7 @@ class CommentTitleTest extends CommentTestBase { */ public function testCommentEmptyTitles() { // Enables module that sets comments to an empty string. - \Drupal::moduleHandler()->install(array('comment_empty_title_test')); + \Drupal::service('module_installer')->install(array('comment_empty_title_test')); // Set comments to have a subject with preview disabled. $this->setCommentPreview(DRUPAL_DISABLED); diff --git a/core/modules/comment/src/Tests/CommentUninstallTest.php b/core/modules/comment/src/Tests/CommentUninstallTest.php index 00796dc..53db75e 100644 --- a/core/modules/comment/src/Tests/CommentUninstallTest.php +++ b/core/modules/comment/src/Tests/CommentUninstallTest.php @@ -42,7 +42,7 @@ function testCommentUninstallWithField() { $this->assertNotNull($field_storage, 'The comment_body field exists.'); // Uninstall the comment module which should trigger field deletion. - $this->container->get('module_handler')->uninstall(array('comment')); + $this->container->get('module_installer')->uninstall(array('comment')); // Check that the field is now deleted. $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body'); @@ -65,7 +65,7 @@ function testCommentUninstallWithoutField() { // Ensure that uninstallation succeeds even if the field has already been // deleted manually beforehand. - $this->container->get('module_handler')->uninstall(array('comment')); + $this->container->get('module_installer')->uninstall(array('comment')); } } diff --git a/core/modules/config/src/Form/ConfigSync.php b/core/modules/config/src/Form/ConfigSync.php index b99c290..dd271a3 100644 --- a/core/modules/config/src/Form/ConfigSync.php +++ b/core/modules/config/src/Form/ConfigSync.php @@ -13,6 +13,7 @@ use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ModuleInstallerInterface; use Drupal\Core\Extension\ThemeHandlerInterface; use Drupal\Core\Config\ConfigManagerInterface; use Drupal\Core\Form\FormBase; @@ -93,6 +94,13 @@ class ConfigSync extends FormBase { protected $themeHandler; /** + * The module installer. + * + * @var \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected $moduleInstaller; + + /** * Constructs the object. * * @param \Drupal\Core\Config\StorageInterface $staging_storage @@ -111,10 +119,12 @@ class ConfigSync extends FormBase { * The typed configuration manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler + * @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer + * The module installer. * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler * The theme handler */ - public function __construct(StorageInterface $staging_storage, StorageInterface $active_storage, StorageInterface $snapshot_storage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) { + public function __construct(StorageInterface $staging_storage, StorageInterface $active_storage, StorageInterface $snapshot_storage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler) { $this->stagingStorage = $staging_storage; $this->activeStorage = $active_storage; $this->snapshotStorage = $snapshot_storage; @@ -123,6 +133,7 @@ public function __construct(StorageInterface $staging_storage, StorageInterface $this->configManager = $config_manager; $this->typedConfigManager = $typed_config; $this->moduleHandler = $module_handler; + $this->moduleInstaller = $module_installer; $this->themeHandler = $theme_handler; } @@ -139,6 +150,7 @@ public static function create(ContainerInterface $container) { $container->get('config.manager'), $container->get('config.typed'), $container->get('module_handler'), + $container->get('module_installer'), $container->get('theme_handler') ); } @@ -300,6 +312,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->lock, $this->typedConfigManager, $this->moduleHandler, + $this->moduleInstaller, $this->themeHandler, $this->getStringTranslation() ); diff --git a/core/modules/config/src/Tests/ConfigCRUDTest.php b/core/modules/config/src/Tests/ConfigCRUDTest.php index 39f790e..9ed6d94 100644 --- a/core/modules/config/src/Tests/ConfigCRUDTest.php +++ b/core/modules/config/src/Tests/ConfigCRUDTest.php @@ -213,7 +213,7 @@ function testValueValidation() { * Tests data type handling. */ public function testDataTypes() { - \Drupal::moduleHandler()->install(array('config_test')); + \Drupal::service('module_installer')->install(array('config_test')); $storage = new DatabaseStorage($this->container->get('database'), 'config'); $name = 'config_test.types'; $config = $this->container->get('config.factory')->get($name); diff --git a/core/modules/config/src/Tests/ConfigImportAllTest.php b/core/modules/config/src/Tests/ConfigImportAllTest.php index bc801c3..238f948 100644 --- a/core/modules/config/src/Tests/ConfigImportAllTest.php +++ b/core/modules/config/src/Tests/ConfigImportAllTest.php @@ -53,7 +53,7 @@ public function testInstallUninstall() { }); // Install every module possible. - \Drupal::moduleHandler()->install(array_keys($all_modules)); + \Drupal::service('module_installer')->install(array_keys($all_modules)); $this->assertModules(array_keys($all_modules), TRUE); foreach($all_modules as $module => $info) { @@ -100,7 +100,7 @@ public function testInstallUninstall() { $this->assertTrue(isset($modules_to_uninstall['comment']), 'The comment module will be disabled'); // Uninstall all modules that can be uninstalled. - \Drupal::moduleHandler()->uninstall(array_keys($modules_to_uninstall)); + \Drupal::service('module_installer')->uninstall(array_keys($modules_to_uninstall)); $this->assertModules(array_keys($modules_to_uninstall), FALSE); foreach($modules_to_uninstall as $module => $info) { diff --git a/core/modules/config/src/Tests/ConfigImportRecreateTest.php b/core/modules/config/src/Tests/ConfigImportRecreateTest.php index 19affec..65fd799 100644 --- a/core/modules/config/src/Tests/ConfigImportRecreateTest.php +++ b/core/modules/config/src/Tests/ConfigImportRecreateTest.php @@ -54,6 +54,7 @@ protected function setUp() { $this->container->get('lock'), $this->container->get('config.typed'), $this->container->get('module_handler'), + $this->container->get('module_installer'), $this->container->get('theme_handler'), $this->container->get('string_translation') ); diff --git a/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php b/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php index cefe093..6639d5b 100644 --- a/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php +++ b/core/modules/config/src/Tests/ConfigImportRenameValidationTest.php @@ -59,6 +59,7 @@ protected function setUp() { $this->container->get('lock.persistent'), $this->container->get('config.typed'), $this->container->get('module_handler'), + $this->container->get('module_installer'), $this->container->get('theme_handler'), $this->container->get('string_translation') ); diff --git a/core/modules/config/src/Tests/ConfigImportUITest.php b/core/modules/config/src/Tests/ConfigImportUITest.php index e2e2118..4d448cd 100644 --- a/core/modules/config/src/Tests/ConfigImportUITest.php +++ b/core/modules/config/src/Tests/ConfigImportUITest.php @@ -95,7 +95,7 @@ function testImport() { // handled correctly. Options depends on Text so Text should be installed // first. Since they were enabled during the test setup the core.extension // file in staging will already contain them. - \Drupal::moduleHandler()->uninstall(array('text', 'options')); + \Drupal::service('module_installer')->uninstall(array('text', 'options')); // Set the state system to record installations and uninstallations. \Drupal::state()->set('ConfigImportUITest.core.extension.modules_installed', array()); diff --git a/core/modules/config/src/Tests/ConfigImporterTest.php b/core/modules/config/src/Tests/ConfigImporterTest.php index fd69055..8907fc2 100644 --- a/core/modules/config/src/Tests/ConfigImporterTest.php +++ b/core/modules/config/src/Tests/ConfigImporterTest.php @@ -58,6 +58,7 @@ protected function setUp() { $this->container->get('lock'), $this->container->get('config.typed'), $this->container->get('module_handler'), + $this->container->get('module_installer'), $this->container->get('theme_handler'), $this->container->get('string_translation') ); diff --git a/core/modules/config/src/Tests/ConfigInstallWebTest.php b/core/modules/config/src/Tests/ConfigInstallWebTest.php index f847d01..131f185 100644 --- a/core/modules/config/src/Tests/ConfigInstallWebTest.php +++ b/core/modules/config/src/Tests/ConfigInstallWebTest.php @@ -34,7 +34,7 @@ function testIntegrationModuleReinstallation() { $default_configuration_entity = 'config_test.dynamic.config_integration_test'; // Install the config_test module we're integrating with. - \Drupal::moduleHandler()->install(array('config_test')); + \Drupal::service('module_installer')->install(array('config_test')); // Verify the configuration does not exist prior to installation. $config_static = \Drupal::config($default_config); @@ -43,7 +43,7 @@ function testIntegrationModuleReinstallation() { $this->assertIdentical($config_entity->isNew(), TRUE); // Install the integration module. - \Drupal::moduleHandler()->install(array('config_integration_test')); + \Drupal::service('module_installer')->install(array('config_integration_test')); // Verify that default module config exists. \Drupal::configFactory()->reset($default_config); @@ -66,7 +66,7 @@ function testIntegrationModuleReinstallation() { $this->container->get('config.factory')->reset(); // Disable and uninstall the integration module. - $this->container->get('module_handler')->uninstall(array('config_integration_test')); + $this->container->get('module_installer')->uninstall(array('config_integration_test')); // Verify the integration module's config was uninstalled. $config_static = \Drupal::config($default_config); @@ -78,7 +78,7 @@ function testIntegrationModuleReinstallation() { $this->assertIdentical($config_entity->get('label'), 'Customized integration config label'); // Reinstall the integration module. - \Drupal::moduleHandler()->install(array('config_integration_test')); + \Drupal::service('module_installer')->install(array('config_integration_test')); // Verify the integration module's config was re-installed. \Drupal::configFactory()->reset($default_config); @@ -132,14 +132,14 @@ function testInstallProfileConfigOverwrite() { // Turn on the test module, which will attempt to replace the // configuration data. This attempt to replace the active configuration // should be ignored. - \Drupal::moduleHandler()->install(array('config_existing_default_config_test')); + \Drupal::service('module_installer')->install(array('config_existing_default_config_test')); // Verify that the test module has not been able to change the data. $config = \Drupal::config($config_name); $this->assertIdentical($config->get(), $expected_profile_data); // Disable and uninstall the test module. - \Drupal::moduleHandler()->uninstall(array('config_existing_default_config_test')); + \Drupal::service('module_installer')->uninstall(array('config_existing_default_config_test')); // Verify that the data hasn't been altered by removing the test module. $config = \Drupal::config($config_name); diff --git a/core/modules/config/src/Tests/ConfigOtherModuleTest.php b/core/modules/config/src/Tests/ConfigOtherModuleTest.php index ba497ab..72a332e 100644 --- a/core/modules/config/src/Tests/ConfigOtherModuleTest.php +++ b/core/modules/config/src/Tests/ConfigOtherModuleTest.php @@ -93,7 +93,7 @@ public function testUninstall() { * The module name. */ protected function installModule($module) { - $this->container->get('module_handler')->install(array($module)); + $this->container->get('module_installer')->install(array($module)); $this->container = \Drupal::getContainer(); } @@ -104,7 +104,7 @@ protected function installModule($module) { * The module name. */ protected function uninstallModule($module) { - $this->container->get('module_handler')->uninstall(array($module)); + $this->container->get('module_installer')->uninstall(array($module)); $this->container = \Drupal::getContainer(); } diff --git a/core/modules/editor/src/Tests/EditorAdminTest.php b/core/modules/editor/src/Tests/EditorAdminTest.php index cdc62ab..26fb9d1 100644 --- a/core/modules/editor/src/Tests/EditorAdminTest.php +++ b/core/modules/editor/src/Tests/EditorAdminTest.php @@ -98,7 +98,7 @@ public function testAddEditorToNewFormat() { * Enables the unicorn editor. */ protected function enableUnicornEditor() { - \Drupal::moduleHandler()->install(array('editor_test')); + \Drupal::service('module_installer')->install(array('editor_test')); $this->rebuildContainer(); $this->resetAll(); } diff --git a/core/modules/field/src/Tests/FieldHelpTest.php b/core/modules/field/src/Tests/FieldHelpTest.php index f4f9323..3f646f0 100644 --- a/core/modules/field/src/Tests/FieldHelpTest.php +++ b/core/modules/field/src/Tests/FieldHelpTest.php @@ -49,7 +49,7 @@ public function testFieldHelp() { $this->drupalGet('admin/help/field'); // Enable the Options, Email and Field API Test modules. - \Drupal::moduleHandler()->install(array('options', 'field_test')); + \Drupal::service('module_installer')->install(array('options', 'field_test')); $this->resetAll(); \Drupal::service('plugin.manager.field.widget')->clearCachedDefinitions(); \Drupal::service('plugin.manager.field.field_type')->clearCachedDefinitions(); diff --git a/core/modules/field/src/Tests/FieldImportCreateTest.php b/core/modules/field/src/Tests/FieldImportCreateTest.php index c07d8bf..9aa4b16 100644 --- a/core/modules/field/src/Tests/FieldImportCreateTest.php +++ b/core/modules/field/src/Tests/FieldImportCreateTest.php @@ -38,7 +38,7 @@ function testImportCreateDefault() { // Enable field_test_config module and check that the field and storage // shipped in the module's default config were created. - \Drupal::moduleHandler()->install(array('field_test_config')); + \Drupal::service('module_installer')->install(array('field_test_config')); // A field storage with one single field. $field_storage = entity_load('field_storage_config', $field_storage_id); diff --git a/core/modules/field_ui/src/Tests/ManageDisplayTest.php b/core/modules/field_ui/src/Tests/ManageDisplayTest.php index 1252239..9f4e712 100644 --- a/core/modules/field_ui/src/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/src/Tests/ManageDisplayTest.php @@ -136,7 +136,7 @@ function testFormatterUI() { $this->assertFieldByName('field_test_settings_edit'); // Uninstall the module providing third party settings and ensure the button // is no longer there. - \Drupal::moduleHandler()->uninstall(array('field_third_party_test')); + \Drupal::service('module_installer')->uninstall(array('field_third_party_test')); $this->drupalGet($manage_display); $this->assertNoFieldByName('field_test_settings_edit'); } diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php index 255c940..2264ce0 100644 --- a/core/modules/forum/src/Tests/ForumTest.php +++ b/core/modules/forum/src/Tests/ForumTest.php @@ -233,7 +233,7 @@ function testAddOrphanTopic() { $this->assertEqual(0, $nid_count, 'A forum node was not created when missing a forum vocabulary.'); // Reset the defaults for future tests. - \Drupal::moduleHandler()->install(array('forum')); + \Drupal::service('module_installer')->install(array('forum')); } /** diff --git a/core/modules/forum/src/Tests/ForumUninstallTest.php b/core/modules/forum/src/Tests/ForumUninstallTest.php index 70983fd..904ac9d 100644 --- a/core/modules/forum/src/Tests/ForumUninstallTest.php +++ b/core/modules/forum/src/Tests/ForumUninstallTest.php @@ -145,7 +145,7 @@ public function testForumUninstallWithoutFieldStorage() { // Ensure that uninstallation succeeds even if the field has already been // deleted manually beforehand. - $this->container->get('module_handler')->uninstall(array('forum')); + $this->container->get('module_installer')->uninstall(array('forum')); } } diff --git a/core/modules/language/src/Tests/LanguageConfigOverrideImportTest.php b/core/modules/language/src/Tests/LanguageConfigOverrideImportTest.php index 8e2f00e..a39899d 100644 --- a/core/modules/language/src/Tests/LanguageConfigOverrideImportTest.php +++ b/core/modules/language/src/Tests/LanguageConfigOverrideImportTest.php @@ -36,7 +36,7 @@ public function testConfigOverrideImport() { // Uninstall the language module and its dependencies so we can test // enabling the language module and creating overrides at the same time // during a configuration synchronisation. - \Drupal::moduleHandler()->uninstall(array('language')); + \Drupal::service('module_installer')->uninstall(array('language')); // Ensure that the current site has no overrides registered to the // ConfigFactory. $this->rebuildContainer(); @@ -66,7 +66,7 @@ public function testConfigOverrideImport() { */ public function testConfigOverrideImportEvents() { // Enable the config_events_test module so we can record events occurring. - \Drupal::moduleHandler()->install(array('config_events_test')); + \Drupal::service('module_installer')->install(array('config_events_test')); $this->rebuildContainer(); ConfigurableLanguage::createFromLangcode('fr')->save(); diff --git a/core/modules/language/src/Tests/LanguageNegotiationInfoTest.php b/core/modules/language/src/Tests/LanguageNegotiationInfoTest.php index 9125d05..60fc384 100644 --- a/core/modules/language/src/Tests/LanguageNegotiationInfoTest.php +++ b/core/modules/language/src/Tests/LanguageNegotiationInfoTest.php @@ -75,7 +75,7 @@ function testInfoAlterations() { // Alter LanguageInterface::TYPE_CONTENT to be configurable. 'language_test.content_language_type' => TRUE, )); - $this->container->get('module_handler')->install(array('language_test')); + $this->container->get('module_installer')->install(array('language_test')); $this->resetAll(); // Check that fixed language types are properly configured without the need @@ -135,7 +135,7 @@ function testInfoAlterations() { // Uninstall language_test and check that everything is set back to the // original status. - $this->container->get('module_handler')->uninstall(array('language_test')); + $this->container->get('module_installer')->uninstall(array('language_test')); $this->rebuildContainer(); // Check that only the core language types are available. diff --git a/core/modules/menu_link_content/src/Tests/LinksTest.php b/core/modules/menu_link_content/src/Tests/LinksTest.php index b012bff..fff3fd9 100644 --- a/core/modules/menu_link_content/src/Tests/LinksTest.php +++ b/core/modules/menu_link_content/src/Tests/LinksTest.php @@ -199,7 +199,7 @@ function testMenuLinkReparenting($module = 'menu_test') { * Tests uninstalling a module providing default links. */ public function testModuleUninstalledMenuLinks() { - \Drupal::moduleHandler()->install(array('menu_test')); + \Drupal::service('module_installer')->install(array('menu_test')); \Drupal::service('router.builder')->rebuild(); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test'); @@ -208,7 +208,7 @@ public function testModuleUninstalledMenuLinks() { $this->assertEqual($menu_link->getPluginId(), 'menu_test'); // Uninstall the module and ensure the menu link got removed. - \Drupal::moduleHandler()->uninstall(array('menu_test')); + \Drupal::service('module_installer')->uninstall(array('menu_test')); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test'); $this->assertEqual(count($menu_links), 0); diff --git a/core/modules/menu_ui/src/Tests/MenuUninstallTest.php b/core/modules/menu_ui/src/Tests/MenuUninstallTest.php index abacfd6..3281171 100644 --- a/core/modules/menu_ui/src/Tests/MenuUninstallTest.php +++ b/core/modules/menu_ui/src/Tests/MenuUninstallTest.php @@ -28,7 +28,7 @@ class MenuUninstallTest extends WebTestBase { * Tests Menu uninstall. */ public function testMenuUninstall() { - \Drupal::moduleHandler()->uninstall(array('menu_ui')); + \Drupal::service('module_installer')->uninstall(array('menu_ui')); \Drupal::entityManager()->getStorage('menu')->resetCache(array('admin')); diff --git a/core/modules/node/src/Tests/Config/NodeImportCreateTest.php b/core/modules/node/src/Tests/Config/NodeImportCreateTest.php index ac19c64..209c8af 100644 --- a/core/modules/node/src/Tests/Config/NodeImportCreateTest.php +++ b/core/modules/node/src/Tests/Config/NodeImportCreateTest.php @@ -46,7 +46,7 @@ public function testImportCreateDefault() { // Enable node_test_config module and check that the content type // shipped in the module's default config is created. - $this->container->get('module_handler')->install(array('node_test_config')); + $this->container->get('module_installer')->install(array('node_test_config')); $node_type = entity_load('node_type', $node_type_id); $this->assertTrue($node_type, 'The default content type was created.'); } diff --git a/core/modules/node/src/Tests/NodeBodyFieldStorageTest.php b/core/modules/node/src/Tests/NodeBodyFieldStorageTest.php index 1ee3781..bdfa24c 100644 --- a/core/modules/node/src/Tests/NodeBodyFieldStorageTest.php +++ b/core/modules/node/src/Tests/NodeBodyFieldStorageTest.php @@ -54,7 +54,7 @@ public function testFieldOverrides() { $field->delete(); $field_storage = FieldStorageConfig::loadByName('node', 'body'); $this->assertTrue(count($field_storage->getBundles()) == 0, 'Node body field storage exists after deleting the only instance of a field.'); - \Drupal::moduleHandler()->uninstall(array('node')); + \Drupal::service('module_installer')->uninstall(array('node')); $field_storage = FieldStorageConfig::loadByName('node', 'body'); $this->assertFalse($field_storage, 'Node body field storage does not exist after uninstalling the Node module.'); } diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php index b5fd27a..cb5ffe3 100644 --- a/core/modules/node/src/Tests/NodeTranslationUITest.php +++ b/core/modules/node/src/Tests/NodeTranslationUITest.php @@ -244,7 +244,7 @@ function testTranslationRendering() { $node->save(); // Test that the frontpage view displays the correct translations. - \Drupal::moduleHandler()->install(array('views'), TRUE); + \Drupal::service('module_installer')->install(array('views'), TRUE); $this->rebuildContainer(); $this->doTestTranslations('node', $values); diff --git a/core/modules/node/src/Tests/NodeTypeTest.php b/core/modules/node/src/Tests/NodeTypeTest.php index 23b692d..63cf7ad 100644 --- a/core/modules/node/src/Tests/NodeTypeTest.php +++ b/core/modules/node/src/Tests/NodeTypeTest.php @@ -127,7 +127,7 @@ function testNodeTypeEditing() { */ function testNodeTypeStatus() { // Enable all core node modules, and all types should be active. - $this->container->get('module_handler')->install(array('book'), FALSE); + $this->container->get('module_installer')->install(array('book'), FALSE); $types = node_type_get_types(); foreach (array('book', 'article', 'page') as $type) { $this->assertTrue(isset($types[$type]), format_string('%type is found in node types.', array('%type' => $type))); @@ -136,14 +136,14 @@ function testNodeTypeStatus() { // Disable book module and the respective type should still be active, since // it is not provided by shipped configuration entity. - $this->container->get('module_handler')->uninstall(array('book'), FALSE); + $this->container->get('module_installer')->uninstall(array('book'), FALSE); $types = node_type_get_types(); $this->assertFalse($types['book']->isLocked(), "Book module's node type still active."); $this->assertFalse($types['article']->isLocked(), 'Article node type still active.'); $this->assertFalse($types['page']->isLocked(), 'Basic page node type still active.'); // Re-install the modules and verify that the types are active again. - $this->container->get('module_handler')->install(array('book'), FALSE); + $this->container->get('module_installer')->install(array('book'), FALSE); $types = node_type_get_types(); foreach (array('book', 'article', 'page') as $type) { $this->assertTrue(isset($types[$type]), format_string('%type is found in node types.', array('%type' => $type))); @@ -186,7 +186,7 @@ function testNodeTypeDeletion() { $this->assertText(t('This action cannot be undone.'), 'The node type deletion confirmation form is available.'); // Test that a locked node type could not be deleted. - $this->container->get('module_handler')->install(array('node_test_config')); + $this->container->get('module_installer')->install(array('node_test_config')); // Lock the default node type. $locked = \Drupal::state()->get('node.type.locked'); $locked['default'] = 'default'; @@ -198,7 +198,7 @@ function testNodeTypeDeletion() { $this->assertNoLink(t('Delete')); $this->drupalGet('admin/structure/types/manage/default/delete'); $this->assertResponse(403); - $this->container->get('module_handler')->uninstall(array('node_test_config')); + $this->container->get('module_installer')->uninstall(array('node_test_config')); $this->container = \Drupal::getContainer(); unset($locked['default']); \Drupal::state()->set('node.type.locked', $locked); diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/src/Tests/Views/FrontPageTest.php index ebb7347..0760231 100644 --- a/core/modules/node/src/Tests/Views/FrontPageTest.php +++ b/core/modules/node/src/Tests/Views/FrontPageTest.php @@ -150,7 +150,7 @@ protected function assertNotInResultSet(ViewExecutable $view, array $not_expecte public function testAdminFrontPage() { // When a user with sufficient permissions is logged in, views_ui adds // contextual links to the homepage view. This verifies there are no errors. - \Drupal::moduleHandler()->install(array('views_ui')); + \Drupal::service('module_installer')->install(array('views_ui')); // Login root user with sufficient permissions. $this->drupalLogin($this->root_user); // Test frontpage view. diff --git a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php index 15b6668..682f2cd 100644 --- a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php +++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php @@ -379,7 +379,7 @@ public function testTitleBaseField() { * editable. */ public function testPseudoFields() { - \Drupal::moduleHandler()->install(array('quickedit_test')); + \Drupal::service('module_installer')->install(array('quickedit_test')); $this->drupalLogin($this->author_user); $this->drupalGet('node/1'); @@ -406,7 +406,7 @@ public function testDisplayOptions() { * Tests that Quick Edit works with custom render pipelines. */ public function testCustomPipeline() { - \Drupal::moduleHandler()->install(array('quickedit_test')); + \Drupal::service('module_installer')->install(array('quickedit_test')); $custom_render_url = 'quickedit/form/node/1/body/en/quickedit_test-custom-render-data'; $this->drupalLogin($this->editor_user); diff --git a/core/modules/rdf/src/Tests/GetRdfNamespacesTest.php b/core/modules/rdf/src/Tests/GetRdfNamespacesTest.php index bf38c6b..d5bb87f 100644 --- a/core/modules/rdf/src/Tests/GetRdfNamespacesTest.php +++ b/core/modules/rdf/src/Tests/GetRdfNamespacesTest.php @@ -36,7 +36,7 @@ function testGetRdfNamespaces() { // Enable rdf_conflicting_namespaces to ensure that an exception is thrown // when RDF namespaces are conflicting. - \Drupal::moduleHandler()->install(array('rdf_conflicting_namespaces'), TRUE); + \Drupal::service('module_installer')->install(array('rdf_conflicting_namespaces'), TRUE); try { $ns = rdf_get_namespaces(); $this->fail('Expected exception not thrown for conflicting namespace declaration.'); diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php index e822adb..a766d63 100644 --- a/core/modules/simpletest/src/TestBase.php +++ b/core/modules/simpletest/src/TestBase.php @@ -1484,6 +1484,7 @@ public function configImporter() { $this->container->get('lock'), $this->container->get('config.typed'), $this->container->get('module_handler'), + $this->container->get('module_installer'), $this->container->get('theme_handler'), $this->container->get('string_translation') ); diff --git a/core/modules/simpletest/src/Tests/KernelTestBaseTest.php b/core/modules/simpletest/src/Tests/KernelTestBaseTest.php index 6e2d216..62612dd 100644 --- a/core/modules/simpletest/src/Tests/KernelTestBaseTest.php +++ b/core/modules/simpletest/src/Tests/KernelTestBaseTest.php @@ -93,7 +93,7 @@ function testEnableModulesInstall() { $this->assertFalse($schema, "'$table' table schema not found."); // Install the module. - \Drupal::moduleHandler()->install(array($module)); + \Drupal::service('module_installer')->install(array($module)); // Verify that the enabled module exists. $this->assertTrue(\Drupal::moduleHandler()->moduleExists($module), "$module module found."); @@ -215,7 +215,7 @@ function testInstallConfig() { */ function testEnableModulesFixedList() { // Install system module. - $this->container->get('module_handler')->install(array('system', 'menu_link_content')); + $this->container->get('module_installer')->install(array('system', 'menu_link_content')); $entity_manager = \Drupal::entityManager(); // entity_test is loaded via $modules; its entity type should exist. @@ -228,12 +228,12 @@ function testEnableModulesFixedList() { $this->assertTrue(TRUE == $entity_manager->getDefinition('entity_test')); // Install some other modules; entity_test should still exist. - $this->container->get('module_handler')->install(array('user', 'field', 'field_test'), FALSE); + $this->container->get('module_installer')->install(array('user', 'field', 'field_test'), FALSE); $this->assertEqual($this->container->get('module_handler')->moduleExists('entity_test'), TRUE); $this->assertTrue(TRUE == $entity_manager->getDefinition('entity_test')); // Uninstall one of those modules; entity_test should still exist. - $this->container->get('module_handler')->uninstall(array('field_test')); + $this->container->get('module_installer')->uninstall(array('field_test')); $this->assertEqual($this->container->get('module_handler')->moduleExists('entity_test'), TRUE); $this->assertTrue(TRUE == $entity_manager->getDefinition('entity_test')); diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 809a145..9350dfa 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -913,7 +913,7 @@ protected function setUp() { } if ($modules) { $modules = array_unique($modules); - $success = $container->get('module_handler')->install($modules, TRUE); + $success = $container->get('module_installer')->install($modules, TRUE); $this->assertTrue($success, String::format('Enabled modules: %modules', array('%modules' => implode(', ', $modules)))); $this->rebuildContainer(); } diff --git a/core/modules/system/src/Form/ModulesListConfirmForm.php b/core/modules/system/src/Form/ModulesListConfirmForm.php index c04a030..2a31dbe 100644 --- a/core/modules/system/src/Form/ModulesListConfirmForm.php +++ b/core/modules/system/src/Form/ModulesListConfirmForm.php @@ -8,6 +8,7 @@ namespace Drupal\system\Form; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ModuleInstallerInterface; use Drupal\Core\Form\ConfirmFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface; @@ -41,15 +42,25 @@ class ModulesListConfirmForm extends ConfirmFormBase { protected $modules = array(); /** + * The module installer. + * + * @var \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected $moduleInstaller; + + /** * Constructs a ModulesListConfirmForm object. * * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. + * @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer + * The module installer. * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable * The key value expirable factory. */ - public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable) { + public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable) { $this->moduleHandler = $module_handler; + $this->moduleInstaller = $module_installer; $this->keyValueExpirable = $key_value_expirable; } @@ -59,6 +70,7 @@ public function __construct(ModuleHandlerInterface $module_handler, KeyValueStor public static function create(ContainerInterface $container) { return new static( $container->get('module_handler'), + $container->get('module_installer'), $container->get('keyvalue.expirable')->get('module_list') ); } @@ -141,7 +153,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Install the given modules. if (!empty($this->modules['install'])) { - $this->moduleHandler->install(array_keys($this->modules['install'])); + $this->moduleInstaller->install(array_keys($this->modules['install'])); } // Gets module list after install process, flushes caches and displays a diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php index 5f85624..2486ca4 100644 --- a/core/modules/system/src/Form/ModulesListForm.php +++ b/core/modules/system/src/Form/ModulesListForm.php @@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Extension\Extension; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ModuleInstallerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface; @@ -93,11 +94,19 @@ class ModulesListForm extends FormBase { protected $menuLinkManager; /** + * The module installer. + * + * @var \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected $moduleInstaller; + + /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('module_handler'), + $container->get('module_installer'), $container->get('keyvalue.expirable')->get('module_list'), $container->get('access_manager'), $container->get('entity.manager'), @@ -114,6 +123,8 @@ public static function create(ContainerInterface $container) { * * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. + * @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer + * The module installer. * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable * The key value expirable factory. * @param \Drupal\Core\Access\AccessManagerInterface $access_manager @@ -131,8 +142,9 @@ public static function create(ContainerInterface $container) { * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager * The menu link manager. */ - public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable, AccessManagerInterface $access_manager, EntityManagerInterface $entity_manager, AccountInterface $current_user, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider, MenuLinkManagerInterface $menu_link_manager) { + public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, AccessManagerInterface $access_manager, EntityManagerInterface $entity_manager, AccountInterface $current_user, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider, MenuLinkManagerInterface $menu_link_manager) { $this->moduleHandler = $module_handler; + $this->moduleInstaller = $module_installer; $this->keyValueExpirable = $key_value_expirable; $this->accessManager = $access_manager; $this->entityManager = $entity_manager; @@ -505,7 +517,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // There seem to be no dependencies that would need approval. if (!empty($modules['install'])) { - $this->moduleHandler->install(array_keys($modules['install'])); + $this->moduleInstaller->install(array_keys($modules['install'])); } // Gets module list after install process, flushes caches and displays a diff --git a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php index 5a0e0fe..d2974b3 100644 --- a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php +++ b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php @@ -9,13 +9,13 @@ use Drupal\Core\Config\ConfigManagerInterface; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Extension\ModuleInstallerInterface; use Drupal\Core\Form\ConfirmFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; /** * Builds a confirmation form to uninstall selected modules. @@ -23,11 +23,11 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase { /** - * The module handler service. + * The module installer service. * - * @var \Drupal\Core\Extension\ModuleHandlerInterface + * @var \Drupal\Core\Extension\ModuleInstallerInterface */ - protected $moduleHandler; + protected $moduleInstaller; /** * The expirable key value store. @@ -60,8 +60,8 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase { /** * Constructs a ModulesUninstallConfirmForm object. * - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler. + * @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer + * The module installer. * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable * The key value expirable factory. * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager @@ -69,8 +69,8 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase { * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. */ - public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable, ConfigManagerInterface $config_manager, EntityManagerInterface $entity_manager) { - $this->moduleHandler = $module_handler; + public function __construct(ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, ConfigManagerInterface $config_manager, EntityManagerInterface $entity_manager) { + $this->moduleInstaller = $module_installer; $this->keyValueExpirable = $key_value_expirable; $this->configManager = $config_manager; $this->entityManager = $entity_manager; @@ -81,7 +81,7 @@ public function __construct(ModuleHandlerInterface $module_handler, KeyValueStor */ public static function create(ContainerInterface $container) { return new static( - $container->get('module_handler'), + $container->get('module_installer'), $container->get('keyvalue.expirable')->get('modules_uninstall'), $container->get('config.manager'), $container->get('entity.manager') @@ -198,7 +198,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->keyValueExpirable->delete($account); // Uninstall the modules. - $this->moduleHandler->uninstall($this->modules); + $this->moduleInstaller->uninstall($this->modules); drupal_set_message($this->t('The selected modules have been uninstalled.')); $form_state->setRedirectUrl($this->getCancelUrl()); diff --git a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php index 1b4dc6b..aa2d800 100644 --- a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php +++ b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php @@ -100,7 +100,7 @@ public function testFieldItemAttributes() { // Enable the RDF module to ensure that two modules can add attributes to // the same field item. - \Drupal::moduleHandler()->install(array('rdf')); + \Drupal::service('module_installer')->install(array('rdf')); $this->resetAll(); // Set an RDF mapping for the field_test_text field. This RDF mapping will diff --git a/core/modules/system/src/Tests/Extension/ModuleHandlerTest.php b/core/modules/system/src/Tests/Extension/ModuleHandlerTest.php index 69f5627..83cd5fc 100644 --- a/core/modules/system/src/Tests/Extension/ModuleHandlerTest.php +++ b/core/modules/system/src/Tests/Extension/ModuleHandlerTest.php @@ -52,7 +52,7 @@ function testModuleList() { $this->assertModuleList($module_list, 'Testing profile'); // Try to install a new module. - $this->moduleHandler()->install(array('ban')); + $this->moduleInstaller()->install(array('ban')); $module_list[] = 'ban'; sort($module_list); $this->assertModuleList($module_list, 'After adding a module'); @@ -116,7 +116,7 @@ function testDependencyResolution() { \Drupal::state()->set('module_test.dependency', 'missing dependency'); drupal_static_reset('system_rebuild_module_data'); - $result = $this->moduleHandler()->install(array('color')); + $result = $this->moduleInstaller()->install(array('color')); $this->assertFalse($result, 'ModuleHandler::install() returns FALSE if dependencies are missing.'); $this->assertFalse($this->moduleHandler()->moduleExists('color'), 'ModuleHandler::install() aborts if dependencies are missing.'); @@ -125,7 +125,7 @@ function testDependencyResolution() { \Drupal::state()->set('module_test.dependency', 'dependency'); drupal_static_reset('system_rebuild_module_data'); - $result = $this->moduleHandler()->install(array('color')); + $result = $this->moduleInstaller()->install(array('color')); $this->assertTrue($result, 'ModuleHandler::install() returns the correct value.'); // Verify that the fake dependency chain was installed. @@ -141,7 +141,7 @@ function testDependencyResolution() { // Uninstall all three modules explicitly, but in the incorrect order, // and make sure that ModuleHandler::uninstall() uninstalled them in the // correct sequence. - $result = $this->moduleHandler()->uninstall(array('config', 'help', 'color')); + $result = $this->moduleInstaller()->uninstall(array('config', 'help', 'color')); $this->assertTrue($result, 'ModuleHandler::uninstall() returned TRUE.'); foreach (array('color', 'config', 'help') as $module) { @@ -157,7 +157,7 @@ function testDependencyResolution() { \Drupal::state()->set('module_test.dependency', 'version dependency'); drupal_static_reset('system_rebuild_module_data'); - $result = $this->moduleHandler()->install(array('color')); + $result = $this->moduleInstaller()->install(array('color')); $this->assertTrue($result, 'ModuleHandler::install() returns the correct value.'); // Verify that the fake dependency chain was installed. @@ -184,11 +184,11 @@ function testUninstallProfileDependency() { $data = system_rebuild_module_data(); $this->assertTrue(isset($data[$profile]->requires[$dependency])); - $this->moduleHandler()->install(array($dependency)); + $this->moduleInstaller()->install(array($dependency)); $this->assertTrue($this->moduleHandler()->moduleExists($dependency)); // Uninstall the profile module "dependency". - $result = $this->moduleHandler()->uninstall(array($dependency)); + $result = $this->moduleInstaller()->uninstall(array($dependency)); $this->assertTrue($result, 'ModuleHandler::uninstall() returns TRUE.'); $this->assertFalse($this->moduleHandler()->moduleExists($dependency)); $this->assertEqual(drupal_get_installed_schema_version($dependency), SCHEMA_UNINSTALLED, "$dependency module was uninstalled."); @@ -221,7 +221,7 @@ public function testModuleStreamWrappers() { // Verify that it is not registered yet to prevent false positives. $stream_wrappers = file_get_stream_wrappers(); $this->assertFalse(isset($stream_wrappers['dummy'])); - $this->moduleHandler()->install(['file_test']); + $this->moduleInstaller()->install(['file_test']); // Verify that the stream wrapper is available even without calling // file_get_stream_wrappers() again. If the stream wrapper is not available // file_exists() will raise a notice. @@ -253,4 +253,13 @@ protected function moduleHandler() { return $this->container->get('module_handler'); } + /** + * Returns the ModuleInstaller. + * + * @return \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected function moduleInstaller() { + return $this->container->get('module_installer'); + } + } diff --git a/core/modules/system/src/Tests/Extension/ThemeHandlerTest.php b/core/modules/system/src/Tests/Extension/ThemeHandlerTest.php index 619736b..1d382c7 100644 --- a/core/modules/system/src/Tests/Extension/ThemeHandlerTest.php +++ b/core/modules/system/src/Tests/Extension/ThemeHandlerTest.php @@ -310,15 +310,14 @@ function testUninstallNotInstalled() { function testThemeInfoAlter() { $name = 'seven'; $this->container->get('state')->set('module_test.hook_system_info_alter', TRUE); - $module_handler = $this->container->get('module_handler'); $this->themeHandler()->install(array($name)); $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name]->info['regions']['test_region'])); - $module_handler->install(array('module_test'), FALSE); - $this->assertTrue($module_handler->moduleExists('module_test')); + $this->moduleInstaller()->install(array('module_test'), FALSE); + $this->assertTrue($this->moduleHandler()->moduleExists('module_test')); $themes = $this->themeHandler()->listInfo(); $this->assertTrue(isset($themes[$name]->info['regions']['test_region'])); @@ -333,8 +332,8 @@ function testThemeInfoAlter() { $system_list = system_list('theme'); $this->assertTrue(isset($system_list[$name]->info['regions']['test_region'])); - $module_handler->uninstall(array('module_test')); - $this->assertFalse($module_handler->moduleExists('module_test')); + $this->moduleInstaller()->uninstall(array('module_test')); + $this->assertFalse($this->moduleHandler()->moduleExists('module_test')); $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name]->info['regions']['test_region'])); @@ -389,4 +388,22 @@ protected function configStorage() { return $this->container->get('config.storage'); } + /** + * Returns the ModuleHandler. + * + * @return \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected function moduleHandler() { + return $this->container->get('module_handler'); + } + + /** + * Returns the ModuleInstaller. + * + * @return \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected function moduleInstaller() { + return $this->container->get('module_installer'); + } + } diff --git a/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php b/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php index 1ebed3b..a058801 100644 --- a/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php +++ b/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php @@ -76,7 +76,7 @@ function testLanguageSelectElementOptions() { function testHiddenLanguageSelectElement() { // Disable the language module, so that the language select field will not // be rendered. - $this->container->get('module_handler')->uninstall(array('language')); + $this->container->get('module_installer')->uninstall(array('language')); $this->drupalGet('form-test/language_select'); // Check that the language fields were rendered on the page. $ids = array('edit-languages-all', 'edit-languages-configurable', 'edit-languages-locked', 'edit-languages-config-and-locked'); diff --git a/core/modules/system/src/Tests/Menu/MenuRouterTest.php b/core/modules/system/src/Tests/Menu/MenuRouterTest.php index 48c7500..caeaddf 100644 --- a/core/modules/system/src/Tests/Menu/MenuRouterTest.php +++ b/core/modules/system/src/Tests/Menu/MenuRouterTest.php @@ -178,7 +178,7 @@ protected function doTestMenuOptionalPlaceholders() { * Tests a menu on a router page. */ protected function doTestMenuOnRoute() { - \Drupal::moduleHandler()->install(array('router_test')); + \Drupal::service('module_installer')->install(array('router_test')); \Drupal::service('router.builder')->rebuild(); $this->resetAll(); diff --git a/core/modules/system/src/Tests/Module/ClassLoaderTest.php b/core/modules/system/src/Tests/Module/ClassLoaderTest.php index ffbda53..cfea56d 100644 --- a/core/modules/system/src/Tests/Module/ClassLoaderTest.php +++ b/core/modules/system/src/Tests/Module/ClassLoaderTest.php @@ -28,7 +28,7 @@ class ClassLoaderTest extends WebTestBase { */ function testClassLoading() { // Enable the module_test and module_autoload_test modules. - \Drupal::moduleHandler()->install(array('module_test', 'module_autoload_test'), FALSE); + \Drupal::service('module_installer')->install(array('module_test', 'module_autoload_test'), FALSE); $this->resetAll(); // Check twice to test an unprimed and primed system_list() cache. for ($i=0; $i<2; $i++) { @@ -44,7 +44,7 @@ function testClassLoading() { */ function testClassLoadingDisabledModules() { // Ensure that module_autoload_test is disabled. - $this->container->get('module_handler')->uninstall(array('module_autoload_test'), FALSE); + $this->container->get('module_installer')->uninstall(array('module_autoload_test'), FALSE); $this->resetAll(); // Check twice to test an unprimed and primed system_list() cache. for ($i=0; $i<2; $i++) { diff --git a/core/modules/system/src/Tests/Module/DependencyTest.php b/core/modules/system/src/Tests/Module/DependencyTest.php index 3f537a5..6454baf 100644 --- a/core/modules/system/src/Tests/Module/DependencyTest.php +++ b/core/modules/system/src/Tests/Module/DependencyTest.php @@ -84,7 +84,7 @@ function testIncompatibleCoreVersionDependency() { * Tests enabling a module that depends on a module which fails hook_requirements(). */ function testEnableRequirementsFailureDependency() { - \Drupal::moduleHandler()->install(array('comment')); + \Drupal::service('module_installer')->install(array('comment')); $this->assertModules(array('requirements1_test'), FALSE); $this->assertModules(array('requirements2_test'), FALSE); @@ -111,7 +111,7 @@ function testEnableRequirementsFailureDependency() { * Dependencies should be enabled before their dependents. */ function testModuleEnableOrder() { - \Drupal::moduleHandler()->install(array('module_test'), FALSE); + \Drupal::service('module_installer')->install(array('module_test'), FALSE); $this->resetAll(); $this->assertModules(array('module_test'), TRUE); \Drupal::state()->set('module_test.dependency', 'dependency'); diff --git a/core/modules/system/src/Tests/Module/InstallTest.php b/core/modules/system/src/Tests/Module/InstallTest.php index 476f25d..df1dcb0 100644 --- a/core/modules/system/src/Tests/Module/InstallTest.php +++ b/core/modules/system/src/Tests/Module/InstallTest.php @@ -41,7 +41,7 @@ public function testGetSchemaAtInstallTime() { * be an array. */ public function testEnableUserTwice() { - \Drupal::moduleHandler()->install(array('user'), FALSE); + \Drupal::service('module_installer')->install(array('user'), FALSE); $this->assertIdentical(\Drupal::config('core.extension')->get('module.user'), 0); } @@ -62,7 +62,7 @@ public function testModuleNameLength() { $module_name = 'invalid_module_name_over_the_maximum_allowed_character_length'; $message = format_string('Exception thrown when enabling module %name with a name length over the allowed maximum', array('%name' => $module_name)); try { - $this->container->get('module_handler')->install(array($module_name)); + $this->container->get('module_installer')->install(array($module_name)); $this->fail($message); } catch (ExtensionNameLengthException $e) { @@ -72,7 +72,7 @@ public function testModuleNameLength() { // Since for the UI, the submit callback uses FALSE, test that too. $message = format_string('Exception thrown when enabling as if via the UI the module %name with a name length over the allowed maximum', array('%name' => $module_name)); try { - $this->container->get('module_handler')->install(array($module_name), FALSE); + $this->container->get('module_installer')->install(array($module_name), FALSE); $this->fail($message); } catch (ExtensionNameLengthException $e) { diff --git a/core/modules/system/src/Tests/Module/InstallUninstallTest.php b/core/modules/system/src/Tests/Module/InstallUninstallTest.php index 43e16f4..66db3e0 100644 --- a/core/modules/system/src/Tests/Module/InstallUninstallTest.php +++ b/core/modules/system/src/Tests/Module/InstallUninstallTest.php @@ -28,9 +28,9 @@ public function testInstallUninstall() { // Install and uninstall module_test to ensure hook_preinstall_module and // hook_preuninstall_module are fired as expected. - $this->container->get('module_handler')->install(array('module_test')); + $this->container->get('module_installer')->install(array('module_test')); $this->assertEqual($this->container->get('state')->get('system_test_preinstall_module'), 'module_test'); - $this->container->get('module_handler')->uninstall(array('module_test')); + $this->container->get('module_installer')->uninstall(array('module_test')); $this->assertEqual($this->container->get('state')->get('system_test_preuninstall_module'), 'module_test'); $this->resetAll(); diff --git a/core/modules/system/src/Tests/Module/ModuleImplementsAlterTest.php b/core/modules/system/src/Tests/Module/ModuleImplementsAlterTest.php index 8d5d229..2a34c20 100644 --- a/core/modules/system/src/Tests/Module/ModuleImplementsAlterTest.php +++ b/core/modules/system/src/Tests/Module/ModuleImplementsAlterTest.php @@ -32,7 +32,7 @@ function testModuleImplementsAlter() { 'Module handler instance is still the same.'); // Install the module_test module. - \Drupal::moduleHandler()->install(array('module_test')); + \Drupal::service('module_installer')->install(array('module_test')); // Assert that the \Drupal::moduleHandler() instance has been replaced. $this->assertFalse($module_handler === \Drupal::moduleHandler(), @@ -76,7 +76,7 @@ function testModuleImplementsAlter() { function testModuleImplementsAlterNonExistingImplementation() { // Install the module_test module. - \Drupal::moduleHandler()->install(array('module_test')); + \Drupal::service('module_installer')->install(array('module_test')); try { // Trigger hook discovery. diff --git a/core/modules/system/src/Tests/Module/UninstallTest.php b/core/modules/system/src/Tests/Module/UninstallTest.php index e57bff0..1b1cd70 100644 --- a/core/modules/system/src/Tests/Module/UninstallTest.php +++ b/core/modules/system/src/Tests/Module/UninstallTest.php @@ -30,7 +30,7 @@ class UninstallTest extends WebTestBase { function testUserPermsUninstalled() { // Uninstalls the module_test module, so hook_modules_uninstalled() // is executed. - $this->container->get('module_handler')->uninstall(array('module_test')); + $this->container->get('module_installer')->uninstall(array('module_test')); // Are the perms defined by module_test removed? $this->assertFalse(user_roles(FALSE, 'module_test perm'), 'Permissions were all removed.'); diff --git a/core/modules/system/src/Tests/Plugin/PluginTestBase.php b/core/modules/system/src/Tests/Plugin/PluginTestBase.php index 618c4ef..b4d6c1d 100644 --- a/core/modules/system/src/Tests/Plugin/PluginTestBase.php +++ b/core/modules/system/src/Tests/Plugin/PluginTestBase.php @@ -47,7 +47,7 @@ protected function setUp() { // as derivatives and ReflectionFactory. $this->testPluginManager = new TestPluginManager(); $this->mockBlockManager = new MockBlockManager(); - $module_handler = new ModuleHandler(\Drupal::root(), array(), $this->container->get('kernel'), new MemoryBackend('plugin')); + $module_handler = new ModuleHandler(\Drupal::root(), array(), new MemoryBackend('plugin'), $this->container->get('event_dispatcher')); $this->defaultsTestPluginManager = new DefaultsTestPluginManager($module_handler); // The expected plugin definitions within each manager. Several tests assert diff --git a/core/modules/system/src/Tests/Routing/RouterTest.php b/core/modules/system/src/Tests/Routing/RouterTest.php index 4fd44bf..5651768 100644 --- a/core/modules/system/src/Tests/Routing/RouterTest.php +++ b/core/modules/system/src/Tests/Routing/RouterTest.php @@ -191,7 +191,7 @@ public function testControllerResolutionAjax() { * Tests that routes no longer exist for a module that has been uninstalled. */ public function testRouterUninstallInstall() { - \Drupal::moduleHandler()->uninstall(array('router_test')); + \Drupal::service('module_installer')->uninstall(array('router_test')); try { \Drupal::service('router.route_provider')->getRouteByName('router_test.1'); $this->fail('Route was delete on uninstall.'); @@ -200,7 +200,7 @@ public function testRouterUninstallInstall() { $this->pass('Route was delete on uninstall.'); } // Install the module again. - \Drupal::moduleHandler()->install(array('router_test')); + \Drupal::service('module_installer')->install(array('router_test')); $route = \Drupal::service('router.route_provider')->getRouteByName('router_test.1'); $this->assertNotNull($route, 'Route exists after module installation'); } diff --git a/core/modules/system/src/Tests/ServiceProvider/ServiceProviderTest.php b/core/modules/system/src/Tests/ServiceProvider/ServiceProviderTest.php index 11dc736..9b67692 100644 --- a/core/modules/system/src/Tests/ServiceProvider/ServiceProviderTest.php +++ b/core/modules/system/src/Tests/ServiceProvider/ServiceProviderTest.php @@ -41,11 +41,11 @@ function testServiceProviderRegistration() { */ function testServiceProviderRegistrationDynamic() { // Uninstall the module and ensure the service provider's service is not registered. - \Drupal::moduleHandler()->uninstall(array('service_provider_test')); + \Drupal::service('module_installer')->uninstall(array('service_provider_test')); $this->assertFalse(\Drupal::hasService('service_provider_test_class'), 'The service_provider_test_class service does not exist in the DIC.'); // Install the module and ensure the service provider's service is registered. - \Drupal::moduleHandler()->install(array('service_provider_test')); + \Drupal::service('module_installer')->install(array('service_provider_test')); $this->assertTrue(\Drupal::hasService('service_provider_test_class'), 'The service_provider_test_class service exists in the DIC.'); } diff --git a/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php b/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php index 28228b0..2960064 100644 --- a/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php +++ b/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php @@ -37,7 +37,7 @@ public function testDefaultMetaTagsExist() { * Verifies that the default mobile meta tags can be removed. */ public function testRemovingDefaultMetaTags() { - \Drupal::moduleHandler()->install(array('system_module_test')); + \Drupal::service('module_installer')->install(array('system_module_test')); $this->drupalGet(''); foreach ($this->default_metatags as $name => $metatag) { $this->assertNoRaw($metatag, String::format('Default Mobile meta tag "@name" removed properly.', array('@name' => $name)), 'System'); diff --git a/core/modules/system/src/Tests/System/InfoAlterTest.php b/core/modules/system/src/Tests/System/InfoAlterTest.php index b9a5030..2930f33 100644 --- a/core/modules/system/src/Tests/System/InfoAlterTest.php +++ b/core/modules/system/src/Tests/System/InfoAlterTest.php @@ -31,7 +31,7 @@ function testSystemInfoAlter() { $this->assertFalse(isset($info['node']->info['required']), 'Before the module_test is installed the node module is not required.'); // Enable the test module. - \Drupal::moduleHandler()->install(array('module_test'), FALSE); + \Drupal::service('module_installer')->install(array('module_test'), FALSE); $this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_test'), 'Test module is enabled.'); $info = system_rebuild_module_data(); diff --git a/core/modules/system/src/Tests/System/ThemeTest.php b/core/modules/system/src/Tests/System/ThemeTest.php index 1534675..e4fef7e 100644 --- a/core/modules/system/src/Tests/System/ThemeTest.php +++ b/core/modules/system/src/Tests/System/ThemeTest.php @@ -260,7 +260,7 @@ function testSwitchDefaultTheme() { */ function testInvalidTheme() { // theme_page_test_system_info_alter() un-hides all hidden themes. - $this->container->get('module_handler')->install(array('theme_page_test')); + $this->container->get('module_installer')->install(array('theme_page_test')); // Clear the system_list() and theme listing cache to pick up the change. $this->container->get('theme_handler')->reset(); $this->drupalGet('admin/appearance'); diff --git a/core/modules/system/src/Tests/Theme/ThemeSuggestionsAlterTest.php b/core/modules/system/src/Tests/Theme/ThemeSuggestionsAlterTest.php index 6bf00f4..5ac8bed 100644 --- a/core/modules/system/src/Tests/Theme/ThemeSuggestionsAlterTest.php +++ b/core/modules/system/src/Tests/Theme/ThemeSuggestionsAlterTest.php @@ -62,7 +62,7 @@ function testGeneralSuggestionsAlter() { // Enable the theme_suggestions_test module to test modules implementing // suggestions alter hooks. - \Drupal::moduleHandler()->install(array('theme_suggestions_test')); + \Drupal::service('module_installer')->install(array('theme_suggestions_test')); $this->resetAll(); $this->drupalGet('theme-test/general-suggestion-alter'); $this->assertText('Template overridden based on new theme suggestion provided by a module via hook_theme_suggestions_alter().'); @@ -84,7 +84,7 @@ function testTemplateSuggestionsAlter() { // Enable the theme_suggestions_test module to test modules implementing // suggestions alter hooks. - \Drupal::moduleHandler()->install(array('theme_suggestions_test')); + \Drupal::service('module_installer')->install(array('theme_suggestions_test')); $this->resetAll(); $this->drupalGet('theme-test/suggestion-alter'); $this->assertText('Template overridden based on new theme suggestion provided by a module via hook_theme_suggestions_HOOK_alter().'); @@ -108,7 +108,7 @@ function testSpecificSuggestionsAlter() { $this->assertText('theme_test_specific_suggestions__variant', 'Specific theme call is added to the suggestions array.'); // Ensure that the base hook is used to determine the suggestion alter hook. - \Drupal::moduleHandler()->install(array('theme_suggestions_test')); + \Drupal::service('module_installer')->install(array('theme_suggestions_test')); $this->resetAll(); $this->drupalGet('theme-test/specific-suggestion-alter'); $this->assertText('Template overridden based on suggestion alter hook determined by the base hook.'); @@ -131,7 +131,7 @@ function testThemeFunctionSuggestionsAlter() { // Enable the theme_suggestions_test module to test modules implementing // suggestions alter hooks. - \Drupal::moduleHandler()->install(array('theme_suggestions_test')); + \Drupal::service('module_installer')->install(array('theme_suggestions_test')); $this->resetAll(); $this->drupalGet('theme-test/function-suggestion-alter'); $this->assertText('Theme function overridden based on new theme suggestion provided by a module.'); @@ -148,7 +148,7 @@ public function testSuggestionsAlterInclude() { // Enable theme_suggestions_test module and make two requests to make sure // the include file is always loaded. The file will always be included for // the first request because the theme registry is being rebuilt. - \Drupal::moduleHandler()->install(array('theme_suggestions_test')); + \Drupal::service('module_installer')->install(array('theme_suggestions_test')); $this->resetAll(); $this->drupalGet('theme-test/suggestion-alter-include'); $this->assertText('Function suggested via suggestion alter hook found in include file.', 'Include file loaded for initial request.'); @@ -167,7 +167,7 @@ function testExecutionOrder() { \Drupal::config('system.theme') ->set('default', 'test_theme') ->save(); - \Drupal::moduleHandler()->install(array('theme_suggestions_test')); + \Drupal::service('module_installer')->install(array('theme_suggestions_test')); $this->resetAll(); // Send two requests so that we get all the messages we've set via diff --git a/core/modules/system/src/Tests/Theme/ThemeTest.php b/core/modules/system/src/Tests/Theme/ThemeTest.php index bee40f1..dfe249c 100644 --- a/core/modules/system/src/Tests/Theme/ThemeTest.php +++ b/core/modules/system/src/Tests/Theme/ThemeTest.php @@ -283,7 +283,7 @@ function testPreprocessHtml() { * Tests that region attributes can be manipulated via preprocess functions. */ function testRegionClass() { - \Drupal::moduleHandler()->install(array('block', 'theme_region_test')); + \Drupal::service('module_installer')->install(array('block', 'theme_region_test')); // Place a block. $this->drupalPlaceBlock('system_main_block'); diff --git a/core/modules/taxonomy/src/Tests/TermTest.php b/core/modules/taxonomy/src/Tests/TermTest.php index 0900dce..72694c0 100644 --- a/core/modules/taxonomy/src/Tests/TermTest.php +++ b/core/modules/taxonomy/src/Tests/TermTest.php @@ -349,7 +349,7 @@ function testTermAutocompletion() { * Save, edit and delete a term using the user interface. */ function testTermInterface() { - \Drupal::moduleHandler()->install(array('views')); + \Drupal::service('module_installer')->install(array('views')); $edit = array( 'name[0][value]' => $this->randomMachineName(12), 'description[0][value]' => $this->randomMachineName(100), diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php index fbe065a..07a1d29 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php +++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php @@ -91,7 +91,7 @@ public function testTaxonomyTermView() { $this->assertText($term->label()); $this->assertText($node->label()); - \Drupal::moduleHandler()->install(array('language', 'content_translation')); + \Drupal::service('module_installer')->install(array('language', 'content_translation')); $language = ConfigurableLanguage::createFromLangcode('ur'); $language->save(); // Enable translation for the article content type and ensure the change is diff --git a/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php b/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php index f265ec2..6cc1678 100644 --- a/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php +++ b/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php @@ -194,8 +194,8 @@ function testUninstallReinstall() { entity_create('field_config', $field_definition)->save(); require_once \Drupal::root() . '/core/includes/install.inc'; - $this->container->get('module_handler')->uninstall(array('taxonomy')); - \Drupal::moduleHandler()->install(array('taxonomy')); + $this->container->get('module_installer')->uninstall(array('taxonomy')); + $this->container->get('module_installer')->install(array('taxonomy')); // Now create a vocabulary with the same name. All fields // connected to this vocabulary name should have been removed when the diff --git a/core/modules/tracker/src/Tests/TrackerTest.php b/core/modules/tracker/src/Tests/TrackerTest.php index c593fc4..354e842 100644 --- a/core/modules/tracker/src/Tests/TrackerTest.php +++ b/core/modules/tracker/src/Tests/TrackerTest.php @@ -343,7 +343,7 @@ function testTrackerCronIndexing() { * Tests that publish/unpublish works at admin/content/node. */ function testTrackerAdminUnpublish() { - \Drupal::moduleHandler()->install(array('views')); + \Drupal::service('module_installer')->install(array('views')); $admin_user = $this->drupalCreateUser(array('access content overview', 'administer nodes', 'bypass node access')); $this->drupalLogin($admin_user); diff --git a/core/modules/user/src/Tests/UserCancelTest.php b/core/modules/user/src/Tests/UserCancelTest.php index 6a191da..9841ebe 100644 --- a/core/modules/user/src/Tests/UserCancelTest.php +++ b/core/modules/user/src/Tests/UserCancelTest.php @@ -71,7 +71,7 @@ function testUserCancelWithoutPermission() { * administer the site. */ function testUserCancelUid1() { - \Drupal::moduleHandler()->install(array('views')); + \Drupal::service('module_installer')->install(array('views')); // Update uid 1's name and password to we know it. $password = user_password(); $account = array( @@ -309,7 +309,7 @@ function testUserAnonymize() { function testUserDelete() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); \Drupal::config('user.settings')->set('cancel_method', 'user_cancel_delete')->save(); - \Drupal::moduleHandler()->install(array('comment')); + \Drupal::service('module_installer')->install(array('comment')); $this->resetAll(); $this->container->get('comment.manager')->addDefaultField('node', 'page'); @@ -428,7 +428,7 @@ function testUserWithoutEmailCancelByAdmin() { * Create an administrative user and mass-delete other users. */ function testMassUserCancelByAdmin() { - \Drupal::moduleHandler()->install(array('views')); + \Drupal::service('module_installer')->install(array('views')); \Drupal::config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); // Enable account cancellation notification. \Drupal::config('user.settings')->set('notify.status_canceled', TRUE)->save(); diff --git a/core/modules/user/src/Tests/UserLoginTest.php b/core/modules/user/src/Tests/UserLoginTest.php index 0e80ba5..d37c575 100644 --- a/core/modules/user/src/Tests/UserLoginTest.php +++ b/core/modules/user/src/Tests/UserLoginTest.php @@ -127,7 +127,7 @@ function testPasswordRehashOnLogin() { // containing the necessary container builder code and then verify that the // users password gets rehashed during the login. $overridden_count_log2 = 19; - \Drupal::moduleHandler()->install(array('user_custom_phpass_params_test')); + \Drupal::service('module_installer')->install(array('user_custom_phpass_params_test')); $this->resetAll(); $account->pass_raw = $password; diff --git a/core/modules/user/src/Tests/UserPermissionsTest.php b/core/modules/user/src/Tests/UserPermissionsTest.php index ec7ed23..ed937dc 100644 --- a/core/modules/user/src/Tests/UserPermissionsTest.php +++ b/core/modules/user/src/Tests/UserPermissionsTest.php @@ -87,7 +87,7 @@ function testAdministratorRole() { // Enable aggregator module and ensure the 'administer news feeds' // permission is assigned by default. - \Drupal::ModuleHandler()->install(array('aggregator')); + \Drupal::service('module_installer')->install(array('aggregator')); $this->assertTrue($this->admin_user->hasPermission('administer news feeds'), 'The permission was automatically assigned to the administrator role'); } diff --git a/core/modules/views/src/Tests/ViewTestBase.php b/core/modules/views/src/Tests/ViewTestBase.php index 5003336..c33776d 100644 --- a/core/modules/views/src/Tests/ViewTestBase.php +++ b/core/modules/views/src/Tests/ViewTestBase.php @@ -53,7 +53,7 @@ protected function enableViewsTestModule() { \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition()); \Drupal::state()->set('views_test_data_views_data', $this->viewsData()); - \Drupal::moduleHandler()->install(array('views_test_data')); + \Drupal::service('module_installer')->install(array('views_test_data')); $this->resetAll(); $this->rebuildContainer(); $this->container->get('module_handler')->reload(); diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/src/Tests/DisplayPathTest.php index b8c0440..71b2035 100644 --- a/core/modules/views_ui/src/Tests/DisplayPathTest.php +++ b/core/modules/views_ui/src/Tests/DisplayPathTest.php @@ -87,7 +87,7 @@ public function testDeleteWithNoPath() { * Tests the menu and tab option form. */ public function testMenuOptions() { - $this->container->get('module_handler')->install(array('menu_ui')); + $this->container->get('module_installer')->install(array('menu_ui')); $this->drupalGet('admin/structure/views/view/test_view'); // Add a new page display. diff --git a/core/modules/views_ui/src/Tests/PreviewTest.php b/core/modules/views_ui/src/Tests/PreviewTest.php index 4b6aca2..fd37343 100644 --- a/core/modules/views_ui/src/Tests/PreviewTest.php +++ b/core/modules/views_ui/src/Tests/PreviewTest.php @@ -27,7 +27,7 @@ class PreviewTest extends UITestBase { * Tests contextual links in the preview form. */ protected function testPreviewContextual() { - \Drupal::moduleHandler()->install(array('contextual')); + \Drupal::service('module_installer')->install(array('contextual')); $this->resetAll(); $this->drupalGet('admin/structure/views/view/test_preview/edit'); @@ -201,7 +201,7 @@ public function testPreviewWithPagersUI() { * Tests the additional information query info area. */ public function testPreviewAdditionalInfo() { - \Drupal::moduleHandler()->install(array('views_ui_test')); + \Drupal::service('module_installer')->install(array('views_ui_test')); $this->resetAll(); $this->drupalGet('admin/structure/views/view/test_preview/edit'); diff --git a/core/modules/views_ui/src/Tests/ViewEditTest.php b/core/modules/views_ui/src/Tests/ViewEditTest.php index 184d339..1ef21ac 100644 --- a/core/modules/views_ui/src/Tests/ViewEditTest.php +++ b/core/modules/views_ui/src/Tests/ViewEditTest.php @@ -101,7 +101,7 @@ public function testEditFormOtherOptions() { $this->assertResponse(200); $this->assertText(t("You don't have translatable entity types.")); // A node view should have language options. - $this->container->get('module_handler')->install(array('node', 'language')); + $this->container->get('module_installer')->install(array('node', 'language')); $this->resetAll(); $this->rebuildContainer(); diff --git a/core/profiles/standard/src/Tests/StandardTest.php b/core/profiles/standard/src/Tests/StandardTest.php index 3ba2347..24834d3 100644 --- a/core/profiles/standard/src/Tests/StandardTest.php +++ b/core/profiles/standard/src/Tests/StandardTest.php @@ -110,9 +110,9 @@ function testStandard() { // The installer does not have this limitation since it ensures that all of // the install profiles dependencies are installed before creating the // editor configuration. - \Drupal::moduleHandler()->uninstall(array('editor', 'ckeditor')); + \Drupal::service('module_installer')->uninstall(array('editor', 'ckeditor')); $this->rebuildContainer(); - \Drupal::moduleHandler()->install(array('editor')); + \Drupal::service('module_installer')->install(array('editor')); /** @var \Drupal\contact\ContactFormInterface $contact_form */ $contact_form = ContactForm::load('feedback'); $recipients = $contact_form->getRecipients(); diff --git a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php index 6b8744b..c5e5dcb 100644 --- a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php @@ -18,13 +18,6 @@ class ModuleHandlerTest extends UnitTestCase { /** - * The mocked drupal kernel. - * - * @var \Drupal\Core\DrupalKernelInterface - */ - protected $kernel; - - /** * The mocked cache backend. * * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject @@ -46,8 +39,6 @@ class ModuleHandlerTest extends UnitTestCase { protected function setUp() { parent::setUp(); - $this->kernel = $this->getMock('Drupal\Core\DrupalKernelInterface'); - $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); $this->moduleHandler = new ModuleHandler($this->root, array( 'module_handler_test' => array( @@ -55,7 +46,7 @@ protected function setUp() { 'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'filename' => 'module_handler_test.module', ) - ), $this->kernel, $this->cacheBackend); + ), $this->cacheBackend); } /** @@ -107,7 +98,7 @@ public function testModuleReloading() { 'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'filename' => 'module_handler_test.module', ) - ), $this->kernel, $this->cacheBackend + ), $this->cacheBackend )) ->setMethods(array('load')) ->getMock(); @@ -175,7 +166,7 @@ public function testGetModuleWithNonExistingModule() { public function testSetModuleList() { $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler') ->setConstructorArgs(array( - $this->root, array(), $this->kernel, $this->cacheBackend + $this->root, array(), $this->cacheBackend )) ->setMethods(array('resetImplementations')) ->getMock(); @@ -203,7 +194,7 @@ public function testAddModule() { $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler') ->setConstructorArgs(array( - $this->root, array(), $this->kernel, $this->cacheBackend + $this->root, array(), $this->cacheBackend )) ->setMethods(array('resetImplementations')) ->getMock(); @@ -225,7 +216,7 @@ public function testAddProfile() { $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler') ->setConstructorArgs(array( - $this->root, array(), $this->kernel, $this->cacheBackend + $this->root, array(), $this->cacheBackend )) ->setMethods(array('resetImplementations')) ->getMock(); @@ -262,7 +253,7 @@ public function testLoadAllIncludes() { 'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'filename' => 'module_handler_test.module', ) - ), $this->kernel, $this->cacheBackend + ), $this->cacheBackend )) ->setMethods(array('loadInclude')) ->getMock(); @@ -343,7 +334,7 @@ public function testCachedGetImplementations() { 'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'filename' => 'module_handler_test.module', ) - ), $this->kernel, $this->cacheBackend + ), $this->cacheBackend )) ->setMethods(array('buildImplementationInfo', 'loadInclude')) ->getMock(); @@ -378,7 +369,7 @@ public function testCachedGetImplementationsMissingMethod() { 'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'filename' => 'module_handler_test.module', ) - ), $this->kernel, $this->cacheBackend + ), $this->cacheBackend )) ->setMethods(array('buildImplementationInfo')) ->getMock();