Problem/Motivation
The DrupalKernel requires knowing about a $root property and has separate code to determine the $sitePath. This logic is currently primarily captured within DrupalKernel which does allow providing $app_root. However, setting the $sitePath can only be done through setSitePath under specific circumstances. It really should be general configuration for the kernel.
It should really not be a concern for the DrupalKernel itself to figure out what the layout is of the Drupal file system. It should only be provided with the right information to act on. What the layout of the application is on disk really is a concern that depends on the runtime.
There are currently a lot of places within Drupal that duplicate some of the functionality around app root or site path. Specifically in tests, lower level bootstrap or install logic, and front-controllers.
With the introduction of Symfony runtime in #3313404: Use symfony/runtime for less bespoke bootstrap/compatibility with varied runtime environments we now have a place to determine these kinds of environmental dependencies in a way that can be swapped out by the application built on Drupal if desirable.
Another concern is that CLI tools, such as Drush, or background processes, like Cron, may be doing things without serving an active request. In those cases it's still important for Drupal to have application context for the things it's doing like the $base_url and $base_path so that even outside of a request context it can properly generate links (e.g. in a notification email).
Tools like Drush currently have to create a fake request to get Drupal to properly set the base_uri and base_path, even though they already have the information and it's thus redundant for Drupal to parse this from a request.
This originally started as an idea in #2529170-104: [PP-1] Remove DrupalKernel::initializeRequestGlobals and replace base_root, base_url and base_path with a service. However, replacing all usages of the globals is in itself already a large task and the structure to contain the app context information and standardising root and siteDirectory uses in tests to that new structure, is big enough that this was split out to its own issue.
Steps to reproduce
Proposed resolution
Introduce a low level \Drupal\Core\AppContext class that initially contains:
- string $appRoot - The path of the application root.
- string $sitePath -The current site path directory.
- string $baseUrl - The base URL of the application.
- string $basePath - The path part of the base URL.
The logic that currently exists within DrupalKernel to determine this should be moved into Drupal\Core\Runtime\DrupalRuntime in a way that it can be easily reused by e.g. Drupal\Tests\DrupalTestCaseTrait. DrupalKernel will be adjusted to receive this $app_context as required constructor input.
Existing logic outside of DrupalKernel should be standardised to use the same shared code to determine the application context but may overwrite the site path of the application context (e.g. in tests).
Front-controllers should be able to easily retrieve AppContext $app_context as a resolved argument from the runtime to pass this to the kernel.
Applications that have different layout requirements now have a single object that they can instantiate to determine how the DrupalKernel and Drupal services deal with the file system. In case an existing application wants to change its layout, it can replace the instantiation of the default AppContext instance by building and/or configuring a runtime class for their application with different behavior.
Related issues
This change relates to a bunch of existing issues and would make those easier to achieve.
#1792310: Wrong DRUPAL_ROOT with non-standard code structure
That issue is introducing a composer plugin that knows where Drupal core is installed. By letting the plugin provide the app root path, the Drupal core directory can be moved to a different location (e.g. using symlinks for easier development).
The overlap between that issue and this one is in standardising code outside of DrupalKernel on using a shared logic to determine the $app_root. However, they're otherwise complementary issues: this issue tries to pull the logic for $app_root outside of the DrupalKernel, that issue wants to change how $app_root is determined based on the environment, rather than by magic path magic.
This issue contains forwards compatibility for 1792310 by having AppContextTrait::getApplicationRoot check for the newly introduced DrupalInstalled::getAppRoot, and using it if it exists.
This issue aims to standardise the way app root is determined, so that 1792310's introduction of DrupalInstalled::getAppRoot takes effect across the codebase.
#3208975: split the concept of DRUPAL_ROOT/app root into app root and Drupal web root
That issue rightly identifies that $app_root is used with different intentions. There is for example a difference in using it to find the web root of the Drupal application to serve files on the web versus trying to determine the location of files in Drupal core so they can be loaded in the Drupal application.
This issue introduces the concept of the AppContext which can be initially extended with getter methods that both return $app_root but allow us to better document the intent of code using the application root value. Then as a follow-up it would be possible to return different path values and allow different parts of the Drupal application to be moved around.
#2529170: [PP-1] Remove DrupalKernel::initializeRequestGlobals and replace base_root, base_url and base_path with a service
That issue is what this one is originally split off from. The most important part of that issue, the usage of $base_url, $base_path, $base_secure_url (derived from $base_url), and $base_insecure_url (derived from $base_url), can now be accessed from the AppContext, rather than relying on globals. The scope of that issue would thus change to ensuring that the places that are currently using the global have access to the app context.
The $base_root is actually taken directly from $request and all use cases in Drupal core seem to have access to the $request where it's used, so those can be easily replaced in that issue.
#2690035: Extract DrupalKernel::bootEnvironment into SAPI adapter
That issue wants to move bootEnvironment out of DrupalKernel. Booting the environment is a task of the runtime and not of the kernel. One challenge up til now is that booting the environment depends on the app root.
This issue removes the dependency of the app root on the DrupalKernel and makes it available in the runtime. This means that it becomes trivial to move the environment boot into the runtime as well, since that now has all the necessary information in AppContext.
The SAPIAdapter concept in that issue was essentially a prototype of what the Symfony Runtime and Runner concepts provide us.
Remaining tasks
User interface changes
Introduced terminology
API changes
AppContextis introduced as container for Drupal application context and replaces DrupalKernel's standalonerootandsitePathproperties as well as providing a standardised way to set or receive$base_urland$base_path.AppContextTraitis introduced to help in constructingAppContextfrom theDrupalRuntimeor alternative runtime implementations as well as test classes..- Providing or omitting a string
$app_roottoDrupalKernel::__constructis deprecated. A mandatoryAppContextinstance should be provided instead DrupalKernel::findSitePathis deprecated. Use the Runtime to determine the site path throughAppContextinstead.DrupalKernel::setSitePathis deprecated, provide the site path to theDrupalKernelusingAppContextinstead.- Calling
DrupalKernel::bootEnvironmentwithout an$app_rootis deprecated, provide the app_root fromAppContextinstead. - It's possible to disable multi-site discovery and restrict to the
sites/defaultsite path by settingextra.runtime.disable_multisitein yourcomposer.jsontoTRUE.
Data model changes
Release notes snippet
Issue fork drupal-3590337
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments