Commit 5e58da00 authored by catch's avatar catch

Issue #2016629 by larowlan, neclimdul, sun, alexpott, jibran, ParisLiakos,...

Issue #2016629 by larowlan, neclimdul, sun, alexpott, jibran, ParisLiakos, donquixote, effulgentsia, msonnabaum: Refactor bootstrap to better utilize the kernel.
parent 18bbe3a7
......@@ -25,8 +25,9 @@ ErrorDocument 404 /index.php
DirectoryIndex index.php index.html index.htm
# Override PHP settings that cannot be changed at runtime. See
# sites/default/default.settings.php and drupal_environment_initialize() in
# core/includes/bootstrap.inc for settings that can be changed at runtime.
# sites/default/default.settings.php and
# Drupal\Core\DrupalKernel::bootEnvironment() for settings that can be
# changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
......@@ -119,7 +120,7 @@ DirectoryIndex index.php index.html index.htm
RewriteRule ^ %1/core/%2 [L,QSA,R=301]
# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
# index.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
......
......@@ -20,13 +20,15 @@
* @link authorize Authorized operation helper functions @endlink
*/
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Site\Settings;
use Drupal\Core\Page\DefaultHtmlPageRenderer;
// Change the directory to the Drupal root.
chdir('..');
require_once __DIR__ . '/vendor/autoload.php';
$autoloader = require_once __DIR__ . '/vendor/autoload.php';
/**
* Global flag to identify update.php and authorize.php runs.
......@@ -51,18 +53,9 @@ function authorize_access_allowed() {
return Settings::get('allow_authorize_operations', TRUE) && user_access('administer software updates');
}
// *** Real work of the script begins here. ***
require_once __DIR__ . '/includes/bootstrap.inc';
require_once __DIR__ . '/includes/common.inc';
require_once __DIR__ . '/includes/file.inc';
require_once __DIR__ . '/includes/module.inc';
require_once __DIR__ . '/includes/ajax.inc';
// Prepare a minimal bootstrap.
drupal_bootstrap(DRUPAL_BOOTSTRAP_PAGE_CACHE);
$request = \Drupal::request();
\Drupal::service('request_stack')->push($request);
$request = Request::createFromGlobals();
$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->prepareLegacyRequest($request);
// We have to enable the user and system modules, even to check access and
// display errors via the maintenance theme.
......
......@@ -204,6 +204,10 @@ services:
arguments: ['@access_check.theme']
tags:
- { name: service_collector, tag: theme_negotiator, call: addNegotiator }
theme.negotiator.request_subscriber:
class: Drupal\Core\EventSubscriber\ThemeNegotiatorRequestSubscriber
tags:
- { name: event_subscriber }
theme.negotiator.default:
class: Drupal\Core\Theme\DefaultNegotiator
arguments: ['@config.factory']
......@@ -608,10 +612,6 @@ services:
tags:
- { name: event_subscriber }
arguments: ['@path.alias_manager', '@path_processor_manager']
legacy_request_subscriber:
class: Drupal\Core\EventSubscriber\LegacyRequestSubscriber
tags:
- { name: event_subscriber }
finish_response_subscriber:
class: Drupal\Core\EventSubscriber\FinishResponseSubscriber
tags:
......
......@@ -6,30 +6,16 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\Environment;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Timer;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\Core\Site\Settings;
use Drupal\Core\Utility\Title;
use Drupal\Core\Utility\Error;
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Exception\RuntimeException as DependencyInjectionRuntimeException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Lock\DatabaseLockBackend;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Session\AnonymousUserSession;
/**
* Minimum supported version of PHP.
......@@ -127,26 +113,36 @@
/**
* First bootstrap phase: initialize configuration.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
*/
const DRUPAL_BOOTSTRAP_CONFIGURATION = 0;
/**
* Second bootstrap phase, initalize a kernel.
* Second bootstrap phase, initialize a kernel.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
*/
const DRUPAL_BOOTSTRAP_KERNEL = 1;
/**
* Third bootstrap phase: try to serve a cached page.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
*/
const DRUPAL_BOOTSTRAP_PAGE_CACHE = 2;
/**
* Fourth bootstrap phase: load code for subsystems and modules.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
*/
const DRUPAL_BOOTSTRAP_CODE = 3;
/**
* Final bootstrap phase: initialize language, path, theme, and modules.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
*/
const DRUPAL_BOOTSTRAP_FULL = 4;
......@@ -208,11 +204,6 @@
/**
* Returns the appropriate configuration directory.
*
* Returns the configuration path based on the site's hostname, port, and
* pathname. Uses find_conf_path() to find the current configuration directory.
* See default.settings.php for examples on how the URL is converted to a
* directory.
*
* @param bool $require_settings
* Only configuration directories with an existing settings.php file
* will be recognized. Defaults to TRUE. During initial installation,
......@@ -221,100 +212,36 @@
* @param bool $reset
* Force a full search for matching directories even if one had been
* found previously. Defaults to FALSE.
* @param \Symfony\Component\HttpFoundation\Request $request
* (optional) The current request. Defaults to \Drupal::request() or a new
* request created from globals.
*
* @return
* The path of the matching directory.
* @return string
* The path of the matching directory.@see default.settings.php
*
* @see default.settings.php
*/
function conf_path($require_settings = TRUE, $reset = FALSE) {
static $conf_path;
if (isset($conf_path) && !$reset) {
return $conf_path;
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Use \Drupal\Core\DrupalKernel::getSitePath() instead. If the kernel is
* unavailable or the site path needs to be recalculated then
* Drupal\Core\DrupalKernel::findSitePath() can be used.
*/
function conf_path($require_settings = TRUE, $reset = FALSE, Request $request = NULL) {
if (!isset($request)) {
if (\Drupal::hasRequest()) {
$request = \Drupal::request();
}
// @todo Remove once external CLI scripts (Drush) are updated.
else {
$request = Request::createFromGlobals();
}
}
// Check for a simpletest override.
if ($test_prefix = drupal_valid_test_ua()) {
$conf_path = 'sites/simpletest/' . substr($test_prefix, 10);
return $conf_path;
if (\Drupal::hasService('kernel')) {
$site_path = \Drupal::service('kernel')->getSitePath();
}
// Otherwise, use the normal $conf_path.
$script_name = $_SERVER['SCRIPT_NAME'];
if (!$script_name) {
$script_name = $_SERVER['SCRIPT_FILENAME'];
if (!isset($site_path) || empty($site_path)) {
$site_path = DrupalKernel::findSitePath($request, $require_settings);
}
$http_host = $_SERVER['HTTP_HOST'];
$conf_path = find_conf_path($http_host, $script_name, $require_settings);
return $conf_path;
return $site_path;
}
/**
* Finds the appropriate configuration directory for a given host and path.
*
* Finds a matching configuration directory file by stripping the website's
* hostname from left to right and pathname from right to left. By default,
* the directory must contain a 'settings.php' file for it to match. If the
* parameter $require_settings is set to FALSE, then a directory without a
* 'settings.php' file will match as well. The first configuration
* file found will be used and the remaining ones will be ignored. If no
* configuration file is found, returns a default value '$confdir/default'. See
* default.settings.php for examples on how the URL is converted to a directory.
*
* If a file named sites.php is present in the $confdir, it will be loaded
* prior to scanning for directories. That file can define aliases in an
* associative array named $sites. The array is written in the format
* '<port>.<domain>.<path>' => 'directory'. As an example, to create a
* directory alias for http://www.drupal.org:8080/mysite/test whose configuration
* file is in sites/example.com, the array should be defined as:
* @code
* $sites = array(
* '8080.www.drupal.org.mysite.test' => 'example.com',
* );
* @endcode
*
* @param $http_host
* The hostname and optional port number, e.g. "www.example.com" or
* "www.example.com:8080".
* @param $script_name
* The part of the URL following the hostname, including the leading slash.
* @param $require_settings
* Defaults to TRUE. If TRUE, then only match directories with a
* 'settings.php' file. Otherwise match any directory.
*
* @return
* The path of the matching configuration directory.
*
* @see default.settings.php
* @see example.sites.php
* @see conf_path()
*/
function find_conf_path($http_host, $script_name, $require_settings = TRUE) {
// Determine whether multi-site functionality is enabled.
if (!file_exists(DRUPAL_ROOT . '/sites/sites.php')) {
return 'sites/default';
}
$sites = array();
include DRUPAL_ROOT . '/sites/sites.php';
$uri = explode('/', $script_name);
$server = explode('.', implode('.', array_reverse(explode(':', rtrim($http_host, '.')))));
for ($i = count($uri) - 1; $i > 0; $i--) {
for ($j = count($server); $j > 0; $j--) {
$dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
if (isset($sites[$dir]) && file_exists(DRUPAL_ROOT . '/sites/' . $sites[$dir])) {
$dir = $sites[$dir];
}
if (file_exists(DRUPAL_ROOT . '/sites/' . $dir . '/settings.php') || (!$require_settings && file_exists(DRUPAL_ROOT . '/sites/' . $dir))) {
return "sites/$dir";
}
}
}
return 'sites/default';
}
/**
* Returns the path of a configuration directory.
*
......@@ -334,207 +261,6 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) {
throw new \Exception(format_string('The configuration directory type %type does not exist.', array('%type' => $type)));
}
/**
* Initializes the PHP environment.
*/
function drupal_environment_initialize() {
if (!isset($_SERVER['SERVER_PROTOCOL']) || ($_SERVER['SERVER_PROTOCOL'] != 'HTTP/1.0' && $_SERVER['SERVER_PROTOCOL'] != 'HTTP/1.1')) {
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0';
}
if (isset($_SERVER['HTTP_HOST'])) {
// As HTTP_HOST is user input, ensure it only contains characters allowed
// in hostnames. See RFC 952 (and RFC 2181).
// $_SERVER['HTTP_HOST'] is lowercased here per specifications.
$_SERVER['HTTP_HOST'] = strtolower($_SERVER['HTTP_HOST']);
if (!drupal_valid_http_host($_SERVER['HTTP_HOST'])) {
// HTTP_HOST is invalid, e.g. if containing slashes it may be an attack.
header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
exit;
}
}
else {
// Some pre-HTTP/1.1 clients will not send a Host header. Ensure the key is
// defined for E_ALL compliance.
$_SERVER['HTTP_HOST'] = '';
}
// @todo Refactor with the Symfony Request object.
_current_path(request_path());
// Enforce E_STRICT, but allow users to set levels not part of E_STRICT.
error_reporting(E_STRICT | E_ALL | error_reporting());
// Override PHP settings required for Drupal to work properly.
// sites/default/default.settings.php contains more runtime settings.
// The .htaccess file contains settings that cannot be changed at runtime.
// Use session cookies, not transparent sessions that puts the session id in
// the query string.
ini_set('session.use_cookies', '1');
ini_set('session.use_only_cookies', '1');
ini_set('session.use_trans_sid', '0');
// Don't send HTTP headers using PHP's session handler.
// Send an empty string to disable the cache limiter.
ini_set('session.cache_limiter', '');
// Use httponly session cookies.
ini_set('session.cookie_httponly', '1');
// Set sane locale settings, to ensure consistent string, dates, times and
// numbers handling.
setlocale(LC_ALL, 'C');
}
/**
* Validates that a hostname (for example $_SERVER['HTTP_HOST']) is safe.
*
* @return
* TRUE if only containing valid characters, or FALSE otherwise.
*/
function drupal_valid_http_host($host) {
return preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
}
/**
* Sets the base URL, cookie domain, and session name from configuration.
*/
function drupal_settings_initialize() {
// Export these settings.php variables to the global namespace.
global $base_url, $cookie_domain, $config_directories, $config;
$databases = array();
$settings = array();
$config = array();
// Make conf_path() available as local variable in settings.php.
$conf_path = conf_path();
if (is_readable(DRUPAL_ROOT . '/' . $conf_path . '/settings.php')) {
require DRUPAL_ROOT . '/' . $conf_path . '/settings.php';
}
// Initialize Database.
Database::setMultipleConnectionInfo($databases);
// Initialize Settings.
new Settings($settings);
}
/**
* Initializes global request variables.
*
* @todo D8: Eliminate this entirely in favor of Request object.
*/
function _drupal_request_initialize() {
// Provided by settings.php.
// @see drupal_settings_initialize()
global $base_url, $cookie_domain;
// Set and derived from $base_url by this function.
global $base_path, $base_root, $script_path;
global $base_secure_url, $base_insecure_url;
$is_https = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
if (isset($base_url)) {
// Parse fixed base URL from settings.php.
$parts = parse_url($base_url);
if (!isset($parts['path'])) {
$parts['path'] = '';
}
$base_path = $parts['path'] . '/';
// Build $base_root (everything until first slash after "scheme://").
$base_root = substr($base_url, 0, strlen($base_url) - strlen($parts['path']));
}
else {
// Create base URL
$http_protocol = $is_https ? 'https' : 'http';
$base_root = $http_protocol . '://' . $_SERVER['HTTP_HOST'];
$base_url = $base_root;
// For a request URI of '/index.php/foo', $_SERVER['SCRIPT_NAME'] is
// '/index.php', whereas $_SERVER['PHP_SELF'] is '/index.php/foo'.
if ($dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/')) {
// Remove "core" directory if present, allowing install.php, update.php,
// and others to auto-detect a base path.
$core_position = strrpos($dir, '/core');
if ($core_position !== FALSE && strlen($dir) - 5 == $core_position) {
$base_path = substr($dir, 0, $core_position);
}
else {
$base_path = $dir;
}
$base_url .= $base_path;
$base_path .= '/';
}
else {
$base_path = '/';
}
}
$base_secure_url = str_replace('http://', 'https://', $base_url);
$base_insecure_url = str_replace('https://', 'http://', $base_url);
// Determine the path of the script relative to the base path, and add a
// trailing slash. This is needed for creating URLs to Drupal pages.
if (!isset($script_path)) {
$script_path = '';
// We don't expect scripts outside of the base path, but sanity check
// anyway.
if (strpos($_SERVER['SCRIPT_NAME'], $base_path) === 0) {
$script_path = substr($_SERVER['SCRIPT_NAME'], strlen($base_path)) . '/';
// If the request URI does not contain the script name, then clean URLs
// are in effect and the script path can be similarly dropped from URL
// generation. For servers that don't provide $_SERVER['REQUEST_URI'], we
// do not know the actual URI requested by the client, and request_uri()
// returns a URI with the script name, resulting in non-clean URLs unless
// there's other code that intervenes.
if (strpos(request_uri(TRUE) . '/', $base_path . $script_path) !== 0) {
$script_path = '';
}
// @todo Temporary BC for install.php, update.php, and other scripts.
// - http://drupal.org/node/1547184
// - http://drupal.org/node/1546082
if ($script_path !== 'index.php/') {
$script_path = '';
}
}
}
if ($cookie_domain) {
// If the user specifies the cookie domain, also use it for session name.
$session_name = $cookie_domain;
}
else {
// Otherwise use $base_url as session name, without the protocol
// to use the same session identifiers across HTTP and HTTPS.
list( , $session_name) = explode('://', $base_url, 2);
// HTTP_HOST can be modified by a visitor, but we already sanitized it
// in drupal_settings_initialize().
if (!empty($_SERVER['HTTP_HOST'])) {
$cookie_domain = $_SERVER['HTTP_HOST'];
// Strip leading periods, www., and port numbers from cookie domain.
$cookie_domain = ltrim($cookie_domain, '.');
if (strpos($cookie_domain, 'www.') === 0) {
$cookie_domain = substr($cookie_domain, 4);
}
$cookie_domain = explode(':', $cookie_domain);
$cookie_domain = '.' . $cookie_domain[0];
}
}
// Per RFC 2109, cookie domains must contain at least one dot other than the
// first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
ini_set('session.cookie_domain', $cookie_domain);
}
// To prevent session cookies from being hijacked, a user can configure the
// SSL version of their website to only transfer session cookies via SSL by
// using PHP's session.cookie_secure setting. The browser will then use two
// separate session cookies for the HTTPS and HTTP versions of the site. So we
// must use different session identifiers for HTTPS and HTTP to prevent a
// cookie collision.
if ($is_https) {
ini_set('session.cookie_secure', TRUE);
}
$prefix = ini_get('session.cookie_secure') ? 'SSESS' : 'SESS';
session_name($prefix . substr(hash('sha256', $session_name), 0, 32));
}
/**
* Returns and optionally sets the filename for a system resource.
*
......@@ -1253,128 +979,49 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
* @endcode
*
* @param $phase
* A constant telling which phase to bootstrap to. When you bootstrap to a
* particular phase, all earlier phases are run automatically. Possible
* values:
* A constant telling which phase to bootstrap to. Possible values:
* - DRUPAL_BOOTSTRAP_CONFIGURATION: Initializes configuration.
* - DRUPAL_BOOTSTRAP_KERNEL: Initalizes a kernel.
* - DRUPAL_BOOTSTRAP_PAGE_CACHE: Tries to serve a cached page.
* - DRUPAL_BOOTSTRAP_CODE: Loads code for subsystems and modules.
* - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
* data.
*
* @return
* @return int
* The most recently completed phase.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Interact directly with the kernel.
*/
function drupal_bootstrap($phase = NULL) {
// Not drupal_static(), because does not depend on any run-time information.
static $phases = array(
DRUPAL_BOOTSTRAP_CONFIGURATION,
DRUPAL_BOOTSTRAP_KERNEL,
DRUPAL_BOOTSTRAP_PAGE_CACHE,
DRUPAL_BOOTSTRAP_CODE,
DRUPAL_BOOTSTRAP_FULL,
);
// Not drupal_static(), because the only legitimate API to control this is to
// call drupal_bootstrap() with a new phase parameter.
static $final_phase = -1;
// Not drupal_static(), because it's impossible to roll back to an earlier
// bootstrap state.
static $stored_phase = -1;
// Store the phase name so it's not forgotten during recursion. Additionally,
// ensure that $final_phase is never rolled back to an earlier bootstrap
// state.
if ($phase > $final_phase) {
$final_phase = $phase;
}
// Temporary variables used for booting later legacy phases.
/** @var \Drupal\Core\DrupalKernel $kernel */
static $kernel;
static $boot_level = 0;
if (isset($phase)) {
// Call a phase if it has not been called before and is below the requested
// phase.
while ($phases && $phase > $stored_phase && $final_phase > $stored_phase) {
$current_phase = array_shift($phases);
// This function is re-entrant. Only update the completed phase when the
// current call actually resulted in a progress in the bootstrap process.
if ($current_phase > $stored_phase) {
$stored_phase = $current_phase;
}
$request = Request::createFromGlobals();
for ($current_phase = $boot_level; $current_phase <= $phase; $current_phase++) {
switch ($current_phase) {
case DRUPAL_BOOTSTRAP_CONFIGURATION:
_drupal_bootstrap_configuration();
$kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod');
break;
case DRUPAL_BOOTSTRAP_KERNEL:
_drupal_bootstrap_kernel();
$kernel->boot();
break;
case DRUPAL_BOOTSTRAP_PAGE_CACHE:
_drupal_bootstrap_page_cache();
$kernel->handlePageCache($request);
break;
case DRUPAL_BOOTSTRAP_CODE:
require_once __DIR__ . '/common.inc';
_drupal_bootstrap_code();
break;
case DRUPAL_BOOTSTRAP_FULL:
_drupal_bootstrap_full();
$kernel->prepareLegacyRequest($request);
break;
}
}
$boot_level = $phase;
}
return $stored_phase;
}
/**
* Handles an entire PHP request.
*
* This function may be called by PHP scripts (e.g., Drupal's index.php) that
* want Drupal to take over the entire PHP processing of the request. The only
* expectation is that PHP's superglobals are initialized as desired (PHP does
* this automatically, but some scripts might want to alter them) and that the
* DRUPAL_ROOT constant is defined and set to the absolute server directory of
* Drupal's codebase.
*
* Scripts and applications that want to invoke multiple Drupal requests within
* a single PHP request, or Drupal request handling within some larger workflow,
* should not call this function, but instead instantiate and use
* \Drupal\Core\DrupalKernel as needed.
*
* @param boolean $test_only
* Whether to restrict handling to only requests invoked by SimpleTest.
*
* @see index.php
*/
function drupal_handle_request($test_only = FALSE) {
// Initialize the environment, load settings.php, and activate a PSR-0 class
// autoloader with required namespaces registered.
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
// Exit if we should be in a test environment but aren't.
if ($test_only && !drupal_valid_test_ua()) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
exit;
}
$kernel = new DrupalKernel('prod', drupal_classloader(), !$test_only);
// @todo Remove this once everything in the bootstrap has been
// converted to services in the DIC.
$kernel->boot();
// Create a request object from the HttpFoundation.
$request = Request::createFromGlobals();
$container = \Drupal::getContainer();
$container->set('request', $request);
$container->get('request_stack')->push($request);
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
$response = $kernel->handle($request)->prepare($request)->send();
$kernel->terminate($request, $response);
return \Drupal::getContainer() ? DRUPAL_BOOTSTRAP_CODE : DRUPAL_BOOTSTRAP_CONFIGURATION;
}
/**
......@@ -1456,111 +1103,14 @@ function _drupal_exception_handler($exception) {
}
}
/**
* Sets up the script environment and loads settings.php.
*/
function _drupal_bootstrap_configuration() {
drupal_environment_initialize();
// Indicate that code is operating in a test child site.
if ($test_prefix = drupal_valid_test_ua()) {
// Only code that interfaces directly with tests should rely on this
// constant; e.g., the error/exception handler conditionally adds further
// error information into HTTP response headers that are consumed by
// Simpletest's internal browser.
define('DRUPAL_TEST_IN_CHILD_SITE', TRUE);
// Log fatal errors to the test site directory.
ini_set('log_errors', 1);
ini_set('error_log', DRUPAL_ROOT . '/sites/simpletest/' . substr($test_prefix, 10) . '/error.log');
}
else {
// Ensure that no other code defines this.
define('DRUPAL_TEST_IN_CHILD_SITE', FALSE);
}
// Initialize the configuration, including variables from settings.php.
drupal_settings_initialize();
_drupal_request_initialize();
// Activate the class loader.
drupal_classloader();
// Start a page timer:
Timer::start('page');
// Detect string handling method.
Unicode::check();
// Set the Drupal custom error handler. (requires \Drupal::config())
set_error_handler('_drupal_error_handler');
set_exception_handler('_drupal_exception_handler');
// 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
// settings.php file) and we are not already installing.
if (!Database::getConnectionInfo() && !drupal_installation_attempted() && !drupal_is_cli()) {
include_once __DIR__ . '/install.inc';
install_goto('core/install.php');
}
}
/**
* Initialize the kernel / service container.
*/
function _drupal_bootstrap_kernel() {
// Normally, index.php puts a container in the Drupal class by creating a
// kernel. If there is no container yet, create one.
if (!\Drupal::getContainer()) {
$kernel = new DrupalKernel('prod', drupal_classloader());
$kernel->boot();
$request = Request::createFromGlobals();
$container = \Drupal::getContainer();
$container->set('request', $request);
$container->get('request_stack')->push($request);
}
}
/**
* Attempts to serve a page from the cache.
*/
function _drupal_bootstrap_page_cache() {
require_once __DIR__ . '/database.inc';
// Check for a cache mode force from settings.php.
if (Settings::get('page_cache_without_database')) {
$cache_enabled = TRUE;
}
else {
$config = \Drupal::config('system.performance');
$cache_enabled = $config->get('cache.page.use_internal');
}