Commit 91c38c8f authored by alexpott's avatar alexpott

Issue #2328111 by dawehner, martin107, neclimdul: Replace most instances of...

Issue #2328111 by dawehner, martin107, neclimdul: Replace most instances of the DRUPAL_ROOT constant with the app.root container parameter.
parent c18ba6aa
......@@ -42,6 +42,7 @@ services:
arguments: ['@database']
cache.backend.apcu:
class: Drupal\Core\Cache\ApcuBackendFactory
arguments: ['@app.root']
cache.backend.php:
class: Drupal\Core\Cache\PhpBackendFactory
cache.bootstrap:
......@@ -182,7 +183,7 @@ services:
arguments: ['@request_stack', '@url_generator']
form_cache:
class: Drupal\Core\Form\FormCache
arguments: ['@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@config.factory', '@request_stack', '@page_cache_request_policy']
arguments: ['@app.root', '@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@config.factory', '@request_stack', '@page_cache_request_policy']
public: false # Private to form_builder
keyvalue:
class: Drupal\Core\KeyValueStore\KeyValueFactory
......@@ -287,10 +288,10 @@ services:
arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
module_handler:
class: Drupal\Core\Extension\ModuleHandler
arguments: ['%container.modules%', '@kernel', '@cache.bootstrap']
arguments: ['@app.root', '%container.modules%', '@kernel', '@cache.bootstrap']
theme_handler:
class: Drupal\Core\Extension\ThemeHandler
arguments: ['@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator']
arguments: ['@app.root', '@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator']
entity.manager:
class: Drupal\Core\Entity\EntityManager
arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed', '@event_dispatcher']
......@@ -382,6 +383,13 @@ services:
event_dispatcher:
class: Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
arguments: ['@service_container']
app.root:
class: SplString
factory_service: 'app.root.factory'
factory_method: 'get'
app.root.factory:
class: Drupal\Core\AppRootFactory
arguments: ['@kernel']
controller_resolver:
class: Drupal\Core\Controller\ControllerResolver
arguments: ['@class_resolver', '@logger.channel.default']
......@@ -989,10 +997,10 @@ services:
arguments: ['@theme.registry', '@theme.negotiator', '@theme.initialization', '@request_stack']
theme.initialization:
class: Drupal\Core\Theme\ThemeInitialization
arguments: ['@theme_handler', '@state']
arguments: ['@app.root', '@theme_handler', '@state']
theme.registry:
class: Drupal\Core\Theme\Registry
arguments: ['@cache.default', '@lock', '@module_handler']
arguments: ['@app.root', '@cache.default', '@lock', '@module_handler']
tags:
- { name: needs_destruction }
authentication:
......@@ -1049,12 +1057,12 @@ services:
- { name: needs_destruction }
library.discovery.parser:
class: Drupal\Core\Asset\LibraryDiscoveryParser
arguments: ['@module_handler']
arguments: ['@app.root', '@module_handler']
info_parser:
class: Drupal\Core\Extension\InfoParser
twig:
class: Drupal\Core\Template\TwigEnvironment
arguments: ['@twig.loader', '@module_handler', '@theme_handler', '%twig.config%']
arguments: ['@app.root', '@twig.loader', '@module_handler', '@theme_handler', '%twig.config%']
tags:
- { name: service_collector, tag: 'twig.extension', call: addExtension }
twig.extension:
......@@ -1074,7 +1082,7 @@ services:
alias: twig.loader.filesystem
twig.loader.filesystem:
class: Twig_Loader_Filesystem
arguments: ['%app.root%']
arguments: ['@app.root']
element_info:
alias: plugin.manager.element_info
file.mime_type.guesser:
......
......@@ -235,7 +235,7 @@ function _batch_process() {
// request, we check if it requires an additional file for functions
// definitions.
if ($set_changed && isset($current_set['file']) && is_file($current_set['file'])) {
include_once DRUPAL_ROOT . '/' . $current_set['file'];
include_once \Drupal::root() . '/' . $current_set['file'];
}
$task_message = $label = '';
......@@ -408,7 +408,7 @@ function _batch_finished() {
if (isset($batch_set['finished'])) {
// Check if the set requires an additional file for function definitions.
if (isset($batch_set['file']) && is_file($batch_set['file'])) {
include_once DRUPAL_ROOT . '/' . $batch_set['file'];
include_once \Drupal::root() . '/' . $batch_set['file'];
}
if (is_callable($batch_set['finished'])) {
$queue = _batch_queue($batch_set);
......
......@@ -277,7 +277,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
}
// If still unknown, perform a filesystem scan.
if (!isset($files[$type][$name])) {
$listing = new ExtensionDiscovery();
$listing = new ExtensionDiscovery(DRUPAL_ROOT);
// Prevent an infinite recursion by this legacy function.
if ($original_type == 'profile') {
$listing->setProfileDirectories(array());
......@@ -1190,7 +1190,7 @@ function _current_path($path = NULL) {
*/
function drupal_classloader_register($name, $path) {
$loader = \Drupal::service('class_loader');
$loader->addPsr4('Drupal\\' . $name . '\\', DRUPAL_ROOT . '/' . $path . '/src');
$loader->addPsr4('Drupal\\' . $name . '\\', \Drupal::root() . '/' . $path . '/src');
}
/**
......
......@@ -199,8 +199,8 @@ function _drupal_log_error($error, $fatal = FALSE) {
// Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
// in the message. This does not happen for (false) security.
$root_length = strlen(DRUPAL_ROOT);
if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) {
$root_length = strlen(\Drupal::root());
if (substr($error['%file'], 0, $root_length) == \Drupal::root()) {
$error['%file'] = substr($error['%file'], $root_length + 1);
}
// Should not translate the string to avoid errors producing more errors.
......
......@@ -287,7 +287,7 @@ function install_begin_request(&$install_state) {
$site_path = DrupalKernel::findSitePath($request, FALSE);
$class_loader = require __DIR__ . '/../vendor/autoload.php';
Settings::initialize($site_path, $class_loader);
Settings::initialize(dirname(dirname(__DIR__)), $site_path, $class_loader);
// Ensure that procedural dependencies are loaded as early as possible,
// since the error/exception handlers depend on them.
......@@ -389,7 +389,7 @@ function install_begin_request(&$install_state) {
}
// Add list of all available profiles to the installation state.
$listing = new ExtensionDiscovery();
$listing = new ExtensionDiscovery($container->get('app.root'));
$listing->setProfileDirectories(array());
$install_state['profiles'] += $listing->scan('profile');
......@@ -717,7 +717,7 @@ function install_tasks($install_state) {
$profile = $install_state['parameters']['profile'];
$profile_install_file = $install_state['profiles'][$profile]->getPath() . '/' . $profile . '.install';
if (file_exists($profile_install_file)) {
include_once DRUPAL_ROOT . '/' . $profile_install_file;
include_once \Drupal::root() . '/' . $profile_install_file;
}
$function = $install_state['parameters']['profile'] . '_install_tasks';
if (function_exists($function)) {
......
......@@ -593,7 +593,7 @@ function drupal_verify_profile($install_state) {
$info = $install_state['profile_info'];
// Get the list of available modules for the selected installation profile.
$listing = new ExtensionDiscovery();
$listing = new ExtensionDiscovery(DRUPAL_ROOT);
$present_modules = array();
foreach ($listing->scan('module') as $present_module) {
$present_modules[] = $present_module->getName();
......
......@@ -179,7 +179,7 @@ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE)
* Returns an array of modules required by core.
*/
function drupal_required_modules() {
$listing = new ExtensionDiscovery();
$listing = new ExtensionDiscovery(\Drupal::root());
$files = $listing->scan('module');
$required = array();
......
......@@ -341,7 +341,7 @@ function _theme($hook, $variables = array()) {
// elsewhere.
if (!empty($info['includes'])) {
foreach ($info['includes'] as $include_file) {
include_once DRUPAL_ROOT . '/' . $include_file;
include_once \Drupal::root() . '/' . $include_file;
}
}
......@@ -353,7 +353,7 @@ function _theme($hook, $variables = array()) {
// might reside there.
if (!empty($base_hook_info['includes'])) {
foreach ($base_hook_info['includes'] as $include_file) {
include_once DRUPAL_ROOT . '/' . $include_file;
include_once \Drupal::root() . '/' . $include_file;
}
}
// Replace the preprocess functions with those from the base hook.
......
......@@ -152,6 +152,15 @@ public static function hasService($id) {
return static::$container && static::$container->has($id);
}
/**
* Gets the app root.
*
* @return string
*/
public static function root() {
return static::$container->get('app.root');
}
/**
* Indicates if there is a currently active request object.
*
......
<?php
/**
* @file
* Contains \Drupal\Core\AppRootFactory.
*/
namespace Drupal\Core;
/**
* Gets the app root from the kernel.
*/
class AppRootFactory {
/**
* The Drupal kernel.
*
* @var \Drupal\Core\DrupalKernelInterface
*/
protected $drupalKernel;
/**
* Constructs an AppRootFactory instance.
*
* @param \Drupal\Core\DrupalKernelInterface $drupal_kernel
* The Drupal kernel.
*/
public function __construct(DrupalKernelInterface $drupal_kernel) {
$this->drupalKernel = $drupal_kernel;
}
/**
* Gets the app root.
*
* @return string
*/
public function get() {
return $this->drupalKernel->getAppRoot();
}
}
......@@ -27,10 +27,22 @@ class LibraryDiscoveryParser {
protected $moduleHandler;
/**
* The app root.
*
* @var string
*/
protected $root;
/**
* Constructs a new LibraryDiscoveryParser instance.
*
* @param string $root
* The app root.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(ModuleHandlerInterface $module_handler) {
public function __construct($root, ModuleHandlerInterface $module_handler) {
$this->root = $root;
$this->moduleHandler = $module_handler;
}
......@@ -67,7 +79,7 @@ public function buildByExtension($extension) {
$library_file = $path . '/' . $extension . '.libraries.yml';
if ($library_file && file_exists(DRUPAL_ROOT . '/' . $library_file)) {
if ($library_file && file_exists($this->root . '/' . $library_file)) {
$libraries = $this->parseLibraryInfo($extension, $library_file);
}
......@@ -222,7 +234,7 @@ public function buildByExtension($extension) {
*/
protected function parseLibraryInfo($extension, $library_file) {
try {
$libraries = Yaml::decode(file_get_contents(DRUPAL_ROOT . '/' . $library_file));
$libraries = Yaml::decode(file_get_contents($this->root . '/' . $library_file));
}
catch (InvalidDataTypeException $e) {
// Rethrow a more helpful exception to provide context.
......
......@@ -20,9 +20,12 @@ class ApcuBackendFactory implements CacheFactoryInterface {
/**
* Constructs an ApcuBackendFactory object.
*
* @param string $root
* The app root.
*/
public function __construct() {
$this->sitePrefix = Crypt::hashBase64(DRUPAL_ROOT . '/' . conf_path());
public function __construct($root) {
$this->sitePrefix = Crypt::hashBase64($root . '/' . conf_path());
}
/**
......
......@@ -157,7 +157,7 @@ protected function getAllFolders() {
if ($profile = drupal_get_profile()) {
$this->folders += $this->getComponentNames('profile', array($profile));
}
$listing = new ExtensionDiscovery();
$listing = new ExtensionDiscovery(DRUPAL_ROOT);
$this->folders += $this->getComponentNames('module', array_keys($listing->scan('module')));
$this->folders += $this->getComponentNames('theme', array_keys($listing->scan('theme')));
}
......
......@@ -41,8 +41,6 @@ class CoreServiceProvider implements ServiceProviderInterface {
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
$container->setParameter('app.root', DRUPAL_ROOT);
$this->registerUuid($container);
$this->registerTest($container);
......
......@@ -179,6 +179,13 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
*/
protected $sitePath;
/**
* The app root.
*
* @var string
*/
protected $root;
/**
* Create a DrupalKernel object from a request.
*
......@@ -198,7 +205,8 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
*/
public static function createFromRequest(Request $request, $class_loader, $environment, $allow_dumping = TRUE) {
// Include our bootstrap file.
require_once dirname(dirname(dirname(__DIR__))) . '/includes/bootstrap.inc';
$core_root = dirname(dirname(dirname(__DIR__)));
require_once $core_root . '/includes/bootstrap.inc';
$kernel = new static($environment, $class_loader, $allow_dumping);
......@@ -206,7 +214,9 @@ public static function createFromRequest(Request $request, $class_loader, $envir
static::bootEnvironment();
// Get our most basic settings setup.
$kernel->initializeSettings($request);
$site_path = static::findSitePath($request);
$kernel->setSitePath($site_path);
Settings::initialize(dirname($core_root), $site_path, $class_loader);
// Redirect the user to the installation script if Drupal has not been
// installed yet (i.e., if no $databases array has been defined in the
......@@ -219,18 +229,6 @@ public static function createFromRequest(Request $request, $class_loader, $envir
return $kernel;
}
/**
* Initializes the kernel's site path and the Settings singleton.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request that will be used to determine the site path.
*/
protected function initializeSettings(Request $request) {
$site_path = static::findSitePath($request);
$this->setSitePath($site_path);
Settings::initialize($site_path, $this->classLoader);
}
/**
* Constructs a DrupalKernel object.
*
......@@ -248,6 +246,7 @@ public function __construct($environment, $class_loader, $allow_dumping = TRUE)
$this->environment = $environment;
$this->classLoader = $class_loader;
$this->allowDumping = $allow_dumping;
$this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
}
/**
......@@ -349,6 +348,13 @@ public function getSitePath() {
return $this->sitePath;
}
/**
* {@inheritdoc}
*/
public function getAppRoot() {
return $this->root;
}
/**
* {@inheritdoc}
*/
......@@ -361,21 +367,21 @@ public function boot() {
Timer::start('page');
// Load legacy and other functional code.
require_once DRUPAL_ROOT . '/core/includes/common.inc';
require_once DRUPAL_ROOT . '/core/includes/database.inc';
require_once DRUPAL_ROOT . '/core/includes/path.inc';
require_once DRUPAL_ROOT . '/core/includes/module.inc';
require_once DRUPAL_ROOT . '/core/includes/theme.inc';
require_once DRUPAL_ROOT . '/core/includes/pager.inc';
require_once DRUPAL_ROOT . '/core/includes/menu.inc';
require_once DRUPAL_ROOT . '/core/includes/tablesort.inc';
require_once DRUPAL_ROOT . '/core/includes/file.inc';
require_once DRUPAL_ROOT . '/core/includes/unicode.inc';
require_once DRUPAL_ROOT . '/core/includes/form.inc';
require_once DRUPAL_ROOT . '/core/includes/mail.inc';
require_once DRUPAL_ROOT . '/core/includes/errors.inc';
require_once DRUPAL_ROOT . '/core/includes/schema.inc';
require_once DRUPAL_ROOT . '/core/includes/entity.inc';
require_once $this->root . '/core/includes/common.inc';
require_once $this->root . '/core/includes/database.inc';
require_once $this->root . '/core/includes/path.inc';
require_once $this->root . '/core/includes/module.inc';
require_once $this->root . '/core/includes/theme.inc';
require_once $this->root . '/core/includes/pager.inc';
require_once $this->root . '/core/includes/menu.inc';
require_once $this->root . '/core/includes/tablesort.inc';
require_once $this->root . '/core/includes/file.inc';
require_once $this->root . '/core/includes/unicode.inc';
require_once $this->root . '/core/includes/form.inc';
require_once $this->root . '/core/includes/mail.inc';
require_once $this->root . '/core/includes/errors.inc';
require_once $this->root . '/core/includes/schema.inc';
require_once $this->root . '/core/includes/entity.inc';
// Ensure that findSitePath is set.
if (!$this->sitePath) {
......@@ -588,7 +594,7 @@ public function prepareLegacyRequest(Request $request) {
protected function moduleData($module) {
if (!$this->moduleData) {
// First, find profiles.
$listing = new ExtensionDiscovery();
$listing = new ExtensionDiscovery($this->root);
$listing->setProfileDirectories(array());
$all_profiles = $listing->scan('profile');
$profiles = array_intersect_key($all_profiles, $this->moduleList);
......@@ -1017,7 +1023,7 @@ protected function compileContainer() {
// - Entity
// - Plugin
foreach (array('Core', 'Component') as $parent_directory) {
$path = DRUPAL_ROOT . '/core/lib/Drupal/' . $parent_directory;
$path = $this->root . '/core/lib/Drupal/' . $parent_directory;
$parent_namespace = 'Drupal\\' . $parent_directory;
foreach (new \DirectoryIterator($path) as $component) {
/** @var $component \DirectoryIterator */
......@@ -1230,7 +1236,7 @@ protected function getModuleFileNames() {
protected function getModuleNamespacesPsr4($module_file_names) {
$namespaces = array();
foreach ($module_file_names as $module => $filename) {
$namespaces["Drupal\\$module"] = DRUPAL_ROOT . '/' . dirname($filename) . '/src';
$namespaces["Drupal\\$module"] = $this->root . '/' . dirname($filename) . '/src';
}
return $namespaces;
}
......
......@@ -73,6 +73,13 @@ public function setSitePath($path);
*/
public function getSitePath();
/**
* Gets the app root.
*
* @return string
*/
public function getAppRoot();
/**
* Updates the kernel's list of modules to the new list.
*
......
......@@ -42,9 +42,18 @@ class Extension implements \Serializable {
*/
protected $splFileInfo;
/**
* The app root.
*
* @var string
*/
protected $root;
/**
* Constructs a new Extension object.
*
* @param string $root
* The app root.
* @param string $type
* The type of the extension; e.g., 'module'.
* @param string $pathname
......@@ -53,7 +62,8 @@ class Extension implements \Serializable {
* @param string $filename
* (optional) The filename of the main extension file; e.g., 'node.module'.
*/
public function __construct($type, $pathname, $filename = NULL) {
public function __construct($root, $type, $pathname, $filename = NULL) {
$this->root = $root;
$this->type = $type;
$this->pathname = $pathname;
$this->filename = $filename;
......@@ -132,7 +142,7 @@ public function getExtensionFilename() {
*/
public function load() {
if ($this->filename) {
include_once DRUPAL_ROOT . '/' . $this->getPath() . '/' . $this->filename;
include_once $this->root . '/' . $this->getPath() . '/' . $this->filename;
return TRUE;
}
return FALSE;
......@@ -157,6 +167,7 @@ public function __call($method, array $args) {
*/
public function serialize() {
$data = array(
'root' => $this->root,
'type' => $this->type,
'pathname' => $this->pathname,
'filename' => $this->filename,
......@@ -177,6 +188,7 @@ public function serialize() {
*/
public function unserialize($data) {
$data = unserialize($data);
$this->root = $data['root'];
$this->type = $data['type'];
$this->pathname = $data['pathname'];
$this->filename = $data['filename'];
......
......@@ -73,6 +73,23 @@ class ExtensionDiscovery {
*/
protected $profileDirectories;
/**
* The app root.
*
* @var string
*/
protected $root;
/**
* Constructs a new ExtensionDiscovery object.
*
* @param string $root
* The app root.
*/
public function __construct($root) {
$this->root = $root;
}
/**
* Discovers available extensions of a given type.
*
......@@ -80,7 +97,7 @@ class ExtensionDiscovery {
* searches in several locations. For instance, to discover all available
* modules:
* @code
* $listing = new ExtensionDiscovery();
* $listing = new ExtensionDiscovery(\Drupal::root());
* $modules = $listing->scan('module');
* @endcode
*
......@@ -304,9 +321,9 @@ protected function scanDirectory($dir, $include_tests) {
// be used (which also improves performance, since any configured PHP
// include_paths will not be consulted). Retain the relative originating
// directory being scanned, so relative paths can be reconstructed below
// (all paths are expected to be relative to DRUPAL_ROOT).
// (all paths are expected to be relative to $this->root).
$dir_prefix = ($dir == '' ? '' : "$dir/");
$absolute_dir = ($dir == '' ? DRUPAL_ROOT : DRUPAL_ROOT . "/$dir");
$absolute_dir = ($dir == '' ? $this->root : $this->root . "/$dir");
if (!is_dir($absolute_dir)) {
return $files;
......@@ -370,7 +387,7 @@ protected function scanDirectory($dir, $include_tests) {
$filename = NULL;
}
$extension = new Extension($type, $pathname, $filename);
$extension = new Extension($this->root, $type, $pathname, $filename);
// Track the originating directory for sorting purposes.
$extension->subpath = $fileinfo->getSubPath();
......
......@@ -92,9 +92,18 @@ class ModuleHandler implements ModuleHandlerInterface {
*/
protected $alterFunctions;
/**
* The app root.
*
* @var string
*/
protected $root;
/**
* Constructs a ModuleHandler object.
*
* @param string $root
* The app root.
* @param array $module_list
* An associative array whose keys are the names of installed modules and
* whose values are Extension class parameters. This is normally the
......@@ -107,10 +116,11 @@ class ModuleHandler implements ModuleHandlerInterface {
* @see \Drupal\Core\DrupalKernel
* @see \Drupal\Core\CoreServiceProvider
*/
public function __construct(array $module_list = array(), DrupalKernelInterface $kernel, CacheBackendInterface $cache_backend) {
public function __construct($root, array $module_list = array(), DrupalKernelInterface $kernel, CacheBackendInterface $cache_backend) {
$this->root = $root;
$this->moduleList = array();
foreach ($module_list as $name => $module) {
$this->moduleList[$name] = new Extension($module['type'], $module['pathname'], $module['filename']);
$this->moduleList[$name] = new Extension($this->root, $module['type'], $module['pathname'], $module['filename']);
}
$this->kernel = $kernel;
$this->cacheBackend = $cache_backend;
......@@ -212,8 +222,8 @@ public function addProfile($name, $path) {
*/
protected function add($type, $name, $path) {
$pathname = "$path/$name.info.yml";
$filename = file_exists(DRUPAL_ROOT . "/$path/$name.$type") ? "$name.$type" : NULL;
$this->moduleList[$name] = new Extension($type, $pathname, $filename);
$filename = file_exists($this->root . "/$path/$name.$type") ? "$name.$type" : NULL;
$this->moduleList[$name] = new Extension($this->root, $type, $pathname, $filename);
$this->resetImplementations();
}
......@@ -262,12 +272,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;
......@@ -736,7 +746,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');
......@@ -783,7 +793,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
$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('module', $pathname, $filename);
$module_filenames[$name] = new Extension($this->root, 'module', $pathname, $filename);
}
}
......@@ -1076,7 +1086,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;
}
......
......@@ -114,9 +114,18 @@ class ThemeHandler implements ThemeHandlerInterface {
*/
protected $configManager;
/**
* The app root.
*
* @var string
*/
protected $root;