From 200cef5a5575eede52553d739ddba96dc62a9480 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Mon, 29 Jun 2020 14:38:39 +0100
Subject: [PATCH] Issue #3144354 by alexpott, vijaycs85, andypost:
 ModuleInstaller loads .module and .install before allowing classes to
 autoloaded

(cherry picked from commit 1a48485eded95e8ece29e4ed872fc11eacc05e8d)
---
 .../Drupal/Core/Extension/ModuleInstaller.php    | 13 ++++++-------
 .../module_autoload_test.module                  | 10 ++++++++++
 .../module_autoload_test/src/SomeClass.php       |  2 ++
 .../src/Functional/Module/ClassLoaderTest.php    | 16 ++++++++++++++++
 4 files changed, 34 insertions(+), 7 deletions(-)
 create mode 100644 core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module

diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index 09f8434370ed..3540a42ef0d0 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -193,14 +193,9 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
           }
         }
 
-        // 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.
+        // Update the module handler in order to have the correct module list
+        // for the kernel update.
         $this->moduleHandler->setModuleList($module_filenames);
-        $this->moduleHandler->load($module);
-        module_load_install($module);
 
         // Clear the static cache of the "extension.list.module" service to pick
         // up the new module, since it merges the installation status of modules
@@ -210,6 +205,10 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
         // Update the kernel to include it.
         $this->updateKernel($module_filenames);
 
+        // Load the module's .module and .install files.
+        $this->moduleHandler->load($module);
+        module_load_install($module);
+
         // Replace the route provider service with a version that will rebuild
         // if routes used during installation. This ensures that a module's
         // routes are available during installation. This has to occur before
diff --git a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module b/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module
new file mode 100644
index 000000000000..cf6983bc7f3e
--- /dev/null
+++ b/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @file
+ * Test module.
+ */
+
+use Drupal\module_autoload_test\SomeClass;
+
+define('MODULE_AUTOLOAD_TEST_CONSTANT', SomeClass::TEST);
diff --git a/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php b/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php
index 11993b71f48e..65529f23dca7 100644
--- a/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php
+++ b/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php
@@ -4,6 +4,8 @@
 
 class SomeClass {
 
+  const TEST = '\Drupal\module_autoload_test\SomeClass::TEST';
+
   public function testMethod() {
     return 'Drupal\\module_autoload_test\\SomeClass::testMethod() was invoked.';
   }
diff --git a/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php b/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php
index cb855e34a90f..c22247b63fa3 100644
--- a/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php
+++ b/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\system\Functional\Module;
 
+use Drupal\module_autoload_test\SomeClass;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -96,4 +97,19 @@ public function testMultipleModules() {
     $this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_install_class_loader_test2'), 'The module_install_class_loader_test2 module has been installed.');
   }
 
+  /**
+   * Tests that .module files can use class constants in main section.
+   */
+  public function testAutoloadFromModuleFile() {
+    $this->assertFalse(defined('MODULE_AUTOLOAD_TEST_CONSTANT'));
+    $this->drupalLogin($this->rootUser);
+    $edit = [
+      "modules[module_autoload_test][enable]" => TRUE,
+    ];
+    $this->drupalPostForm('admin/modules', $edit, t('Install'));
+    $this->assertSession()->statusCodeEquals(200);
+    $this->resetAll();
+    $this->assertSame(SomeClass::TEST, MODULE_AUTOLOAD_TEST_CONSTANT);
+  }
+
 }
-- 
GitLab