Pull merge.
[yaffs-website] / web / core / lib / Drupal / Core / Extension / ModuleInstaller.php
index 87924987c2c6ca0c3b0ccdb141ad0746840ab415..65466a2d657542847a5f8429c5138631ee59bd6b 100644 (file)
@@ -14,6 +14,11 @@ use Drupal\Core\Serialization\Yaml;
  *
  * It registers the module in config, installs its own configuration,
  * installs the schema, updates the Drupal kernel and more.
+ *
+ * We don't inject dependencies yet, as we would need to reload them after
+ * each installation or uninstallation of a module.
+ * https://www.drupal.org/project/drupal/issues/2350111 for example tries to
+ * solve this dilemma.
  */
 class ModuleInstaller implements ModuleInstallerInterface {
 
@@ -93,8 +98,8 @@ class ModuleInstaller implements ModuleInstallerInterface {
       }
 
       // Add dependencies to the list. The new modules will be processed as
-      // the while loop continues.
-      while (list($module) = each($module_list)) {
+      // the foreach loop continues.
+      foreach ($module_list as $module => $value) {
         foreach (array_keys($module_data[$module]->requires) as $dependency) {
           if (!isset($module_data[$dependency])) {
             // The dependency does not exist.
@@ -170,7 +175,7 @@ class ModuleInstaller implements ModuleInstallerInterface {
             $module_filenames[$name] = $current_module_filenames[$name];
           }
           else {
-            $module_path = drupal_get_path('module', $name);
+            $module_path = \Drupal::service('extension.list.module')->getPath($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);
@@ -186,10 +191,10 @@ class ModuleInstaller implements ModuleInstallerInterface {
         $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');
+        // Clear the static cache of the "extension.list.module" service to pick
+        // up the new module, since it merges the installation status of modules
+        // into its statically cached list.
+        \Drupal::service('extension.list.module')->reset();
 
         // Update the kernel to include it.
         $this->updateKernel($module_filenames);
@@ -304,7 +309,11 @@ class ModuleInstaller implements ModuleInstallerInterface {
 
     // If any modules were newly installed, invoke hook_modules_installed().
     if (!empty($modules_installed)) {
-      \Drupal::getContainer()->set('router.route_provider', \Drupal::service('router.route_provider.old'));
+      // If the container was rebuilt during hook_install() it might not have
+      // the 'router.route_provider.old' service.
+      if (\Drupal::hasService('router.route_provider.old')) {
+        \Drupal::getContainer()->set('router.route_provider', \Drupal::service('router.route_provider.old'));
+      }
       if (!\Drupal::service('router.route_provider.lazy_builder')->hasRebuilt()) {
         // Rebuild routes after installing module. This is done here on top of
         // \Drupal\Core\Routing\RouteBuilder::destruct to not run into errors on
@@ -340,9 +349,8 @@ class ModuleInstaller implements ModuleInstallerInterface {
 
     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)) {
+      // the foreach loop continues.
+      foreach ($module_list as $module => $value) {
         foreach (array_keys($module_data[$module]->required_by) as $dependent) {
           if (!isset($module_data[$dependent])) {
             // The dependent module does not exist.
@@ -350,7 +358,7 @@ class ModuleInstaller implements ModuleInstallerInterface {
           }
 
           // Skip already uninstalled modules.
-          if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) {
+          if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent])) {
             $module_list[$dependent] = $dependent;
           }
         }
@@ -415,16 +423,11 @@ class ModuleInstaller implements ModuleInstallerInterface {
           $update_manager->uninstallEntityType($entity_type);
         }
         elseif ($entity_type->entityClassImplements(FieldableEntityInterface::CLASS)) {
-          // The module being installed may be adding new fields to existing
-          // entity types. Field definitions for any entity type defined by
-          // the module are handled in the if branch.
-          $entity_type_id = $entity_type->id();
-          /** @var \Drupal\Core\Entity\FieldableEntityStorageInterface $storage */
-          $storage = $entity_manager->getStorage($entity_type_id);
-          foreach ($entity_manager->getFieldStorageDefinitions($entity_type_id) as $storage_definition) {
-            // @todo We need to trigger field purging here.
-            //   See https://www.drupal.org/node/2282119.
-            if ($storage_definition->getProvider() == $module && !$storage->countFieldData($storage_definition, TRUE)) {
+          // The module being uninstalled might have added new fields to
+          // existing entity types. This will add them to the deleted fields
+          // repository so their data will be purged on cron.
+          foreach ($entity_manager->getFieldStorageDefinitions($entity_type->id()) as $storage_definition) {
+            if ($storage_definition->getProvider() == $module) {
               $update_manager->uninstallFieldStorageDefinition($storage_definition);
             }
           }
@@ -448,10 +451,10 @@ class ModuleInstaller implements ModuleInstallerInterface {
       // 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 the static cache of the "extension.list.module" service to pick
+      // up the new module, since it merges the installation status of modules
+      // into its statically cached list.
+      \Drupal::service('extension.list.module')->reset();
 
       // Clear plugin manager caches.
       \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();