diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index 859b270..ae0ba7f 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -19,6 +19,13 @@ class ModuleHandler implements ModuleHandlerInterface { /** + * Absolute path of the document root directory. + * + * @var string + */ + protected $root; + + /** * List of loaded files. * * @var array @@ -85,16 +92,23 @@ class ModuleHandler implements ModuleHandlerInterface { * %container.modules% parameter being set up by DrupalKernel. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend for storing module hook implementation information. + * @param string $root_directory + * (optional) The absolute path of the document root directory. * * @see \Drupal\Core\DrupalKernel * @see \Drupal\Core\CoreServiceProvider */ - public function __construct(array $module_list = array(), CacheBackendInterface $cache_backend) { + public function __construct(array $module_list = array(), CacheBackendInterface $cache_backend, $root_directory = NULL) { $this->moduleList = array(); foreach ($module_list as $name => $module) { $this->moduleList[$name] = new Extension($module['type'], $module['pathname'], $module['filename']); } $this->cacheBackend = $cache_backend; + + if (!isset($root_directory)) { + $root_directory = DRUPAL_ROOT; + } + $this->root = $root_directory; } /** @@ -183,10 +197,10 @@ public function addProfile($name, $path) { */ protected function add($type, $name, $path) { $pathname = "$path/$name.info.yml"; - if (!file_exists(DRUPAL_ROOT . '/' . $pathname)) { + if (!file_exists($this->root . "/$pathname")) { throw new \InvalidArgumentException("Unknown $type: $pathname not found."); } - $filename = file_exists("$path/$name.$type") ? "$name.$type" : NULL; + $filename = file_exists($this->root . "/$path/$name.$type") ? "$name.$type" : NULL; $this->moduleList[$name] = new Extension($type, $pathname, $filename); $this->resetImplementations(); } @@ -236,12 +250,12 @@ public function loadAllIncludes($type, $name = NULL) { public function loadInclude($module, $type, $name = NULL) { if ($type == 'install') { // Make sure the installation API is available - include_once DRUPAL_ROOT . '/core/includes/install.inc'; + include_once $this->root . '/core/includes/install.inc'; } $name = $name ?: $module; if (isset($this->moduleList[$module])) { - $file = DRUPAL_ROOT . '/' . $this->moduleList[$module]->getPath() . "/$name.$type"; + $file = $this->root . '/' . $this->moduleList[$module]->getPath() . "/$name.$type"; if (is_file($file)) { require_once $file; return $file; @@ -684,7 +698,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) { } // Required for module installation checks. - include_once DRUPAL_ROOT . '/core/includes/install.inc'; + include_once $this->root . '/core/includes/install.inc'; /** @var \Drupal\Core\Config\ConfigInstaller $config_installer */ $config_installer = \Drupal::service('config.installer'); @@ -977,7 +991,7 @@ protected function removeCacheBins($module) { public function getModuleDirectories() { $dirs = array(); foreach ($this->getModuleList() as $name => $module) { - $dirs[$name] = DRUPAL_ROOT . '/' . $module->getPath(); + $dirs[$name] = $this->root . '/' . $module->getPath(); } return $dirs; } diff --git a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php index 73e45c5..84e85dc 100644 --- a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php @@ -14,9 +14,9 @@ * Tests the module handler. * * @group Drupal - * @group Module + * @group Extension * - * @see \Drupal\Core\Extension\ModuleHandler + * @coversDefaultClass \Drupal\Core\Extension\ModuleHandler */ class ModuleHandlerTest extends UnitTestCase { @@ -51,11 +51,14 @@ public static function getInfo() { protected function setUp() { $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); - $this->moduleHandler = new ModuleHandler(array(), $this->cacheBackend); + $this->moduleHandler = new ModuleHandler(array(), $this->cacheBackend, __DIR__); } /** * Tests adding a module. + * + * @covers ::addModule + * @covers ::add */ public function testAddModule() { $this->cacheBackend->expects($this->once()) @@ -74,6 +77,9 @@ public function testAddModule() { * * @expectedException \InvalidArgumentException * @expectedExceptionMessage Unknown module: modules/non_existing/name.info.yml not found. + * + * @covers ::addModule + * @covers ::add */ public function testAddModuleNonExisting() { $this->moduleHandler->addModule('name', 'modules/non_existing'); @@ -81,6 +87,9 @@ public function testAddModuleNonExisting() { /** * Tests adding a profile. + * + * @covers ::addProfile + * @covers ::add */ public function testAddProfile() { $this->cacheBackend->expects($this->once()) @@ -99,12 +108,12 @@ public function testAddProfile() { * * @expectedException \InvalidArgumentException * @expectedExceptionMessage Unknown profile: profiles/non_existing/name.info.yml not found. + * + * @covers ::addProfile + * @covers ::add */ public function testAddProfileNonExisting() { $this->moduleHandler->addProfile('name', 'profiles/non_existing'); } } - -// Explicitly map document root to this test directory. -define('DRUPAL_ROOT', __DIR__);