Commit 6aeb7e9a authored by catch's avatar catch

Issue #2325197 by tstoeckler, sun: Remove drupal_classloader().

parent 5289c3e3
......@@ -1024,7 +1024,8 @@ function drupal_bootstrap($phase = NULL) {
switch ($current_phase) {
case DRUPAL_BOOTSTRAP_CONFIGURATION:
$kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod');
$classloader = require __DIR__ . '/../vendor/autoload.php';
$kernel = DrupalKernel::createFromRequest($request, $classloader, 'prod');
break;
case DRUPAL_BOOTSTRAP_KERNEL:
......@@ -1398,50 +1399,6 @@ function _current_path($path = NULL) {
return $current_path;
}
/**
* Initializes and returns the class loader.
*
* The class loader is responsible for lazy-loading all PSR-0 compatible
* classes, interfaces, and traits (PHP 5.4 and later). It's only dependency
* is DRUPAL_ROOT. Otherwise it may be called as early as possible.
*
* @param $class_loader
* The name of class loader to use. This can be used to change the class
* loader class when calling drupal_classloader() from settings.php. It is
* ignored otherwise.
*
* @return \Composer\Autoload\ClassLoader
* A ClassLoader class instance (or extension thereof).
*/
function drupal_classloader($class_loader = NULL) {
// By default, use the ClassLoader which is best for development, as it does
// not break when code is moved on the file system. However, as it is slow,
// allow to use the APC class loader in production.
static $loader;
if (!isset($loader)) {
// Retrieve the Composer ClassLoader for loading classes.
$loader = include __DIR__ . '/../vendor/autoload.php';
// Register the class loader.
// When configured to use APC, the ApcClassLoader is registered instead.
// Note that ApcClassLoader decorates ClassLoader and only provides the
// findFile() method, but none of the others. The actual registry is still
// in ClassLoader.
if (!isset($class_loader)) {
$class_loader = Settings::get('class_loader', 'default');
}
if ($class_loader === 'apc') {
require_once __DIR__ . '/../vendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcClassLoader.php';
$apc_loader = new ApcClassLoader('drupal.' . Settings::getHashSalt(), $loader);
$loader->unregister();
$apc_loader->register();
}
}
return $loader;
}
/**
* Registers an additional namespace.
*
......@@ -1451,7 +1408,7 @@ function drupal_classloader($class_loader = NULL) {
* The relative path to the Drupal component in the filesystem.
*/
function drupal_classloader_register($name, $path) {
$loader = drupal_classloader();
$loader = \Drupal::service('class_loader');
$loader->addPsr4('Drupal\\' . $name . '\\', DRUPAL_ROOT . '/' . $path . '/src');
}
......
......@@ -286,7 +286,8 @@ function install_begin_request(&$install_state) {
}
$site_path = DrupalKernel::findSitePath($request, FALSE);
Settings::initialize($site_path);
$class_loader = require __DIR__ . '/../vendor/autoload.php';
Settings::initialize($site_path, $class_loader);
// Ensure that procedural dependencies are loaded as early as possible,
// since the error/exception handlers depend on them.
......@@ -358,7 +359,7 @@ function install_begin_request(&$install_state) {
}
// Only allow dumping the container once the hash salt has been created.
$kernel = InstallerKernel::createFromRequest($request, drupal_classloader(), $environment, (bool) Settings::get('hash_salt', FALSE));
$kernel = InstallerKernel::createFromRequest($request, $class_loader, $environment, (bool) Settings::get('hash_salt', FALSE));
$kernel->setSitePath($site_path);
$kernel->boot();
$container = $kernel->getContainer();
......
......@@ -182,19 +182,20 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
* Create a DrupalKernel object from a request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Composer\Autoload\ClassLoader $class_loader
* (optional) The classloader is only used if $storage is not given or
* the load from storage fails and a container rebuild is required. In
* this case, the loaded modules will be registered with this loader in
* order to be able to find the module serviceProviders.
* The request.
* @param $class_loader
* The class loader. Normally Composer's ClassLoader, as included by the
* front controller, but may also be decorated; e.g.,
* \Symfony\Component\ClassLoader\ApcClassLoader.
* @param string $environment
* String indicating the environment, e.g. 'prod' or 'dev'.
* @param bool $allow_dumping
* (optional) FALSE to stop the container from being written to or read
* from disk. Defaults to TRUE.
*
* @return static
*/
public static function createFromRequest(Request $request, ClassLoader $class_loader, $environment, $allow_dumping = TRUE) {
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';
......@@ -204,9 +205,7 @@ public static function createFromRequest(Request $request, ClassLoader $class_lo
static::bootEnvironment();
// Get our most basic settings setup.
$site_path = static::findSitePath($request);
$kernel->setSitePath($site_path);
Settings::initialize($site_path);
$kernel->initializeSettings($request);
// 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,21 +218,32 @@ public static function createFromRequest(Request $request, ClassLoader $class_lo
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.
*
* @param string $environment
* String indicating the environment, e.g. 'prod' or 'dev'.
* @param \Composer\Autoload\ClassLoader $class_loader
* (optional) The class loader is only used if $storage is not given or
* the load from storage fails and a container rebuild is required. In
* this case, the loaded modules will be registered with this loader in
* order to be able to find the module serviceProviders.
* @param $class_loader
* The class loader. Normally \Composer\Autoload\ClassLoader, as included by
* the front controller, but may also be decorated; e.g.,
* \Symfony\Component\ClassLoader\ApcClassLoader.
* @param bool $allow_dumping
* (optional) FALSE to stop the container from being written to or read
* from disk. Defaults to TRUE.
*/
public function __construct($environment, ClassLoader $class_loader, $allow_dumping = TRUE) {
public function __construct($environment, $class_loader, $allow_dumping = TRUE) {
$this->environment = $environment;
$this->classLoader = $class_loader;
$this->allowDumping = $allow_dumping;
......@@ -349,8 +359,6 @@ public function boot() {
// Start a page timer:
Timer::start('page');
drupal_classloader();
// Load legacy and other functional code.
require_once DRUPAL_ROOT . '/core/includes/common.inc';
require_once DRUPAL_ROOT . '/core/includes/database.inc';
......
......@@ -87,8 +87,14 @@ public static function getAll() {
*
* @param string $site_path
* The current site path.
* @param \Composer\Autoload\ClassLoader $class_loader
* The class loader that is used for this request. Passed by reference and
* exposed to the local scope of settings.php, so as to allow it to be
* decorated with Symfony's ApcClassLoader, for example.
*
* @see default.settings.php
*/
public static function initialize($site_path) {
public static function initialize($site_path, &$class_loader) {
// Export these settings.php variables to the global namespace.
global $base_url, $cookie_domain, $config_directories, $config;
$settings = array();
......
......@@ -138,7 +138,8 @@ protected function setUp() {
// Import new settings.php written by the installer.
$request = Request::createFromGlobals();
Settings::initialize(DrupalKernel::findSitePath($request));
$class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
Settings::initialize(DrupalKernel::findSitePath($request), $class_loader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
}
......@@ -150,7 +151,7 @@ protected function setUp() {
// WebTestBase::tearDown() will delete the entire test site directory.
// Not using File API; a potential error must trigger a PHP warning.
chmod(DRUPAL_ROOT . '/' . $this->siteDirectory, 0777);
$this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', FALSE);
$this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
$this->kernel->prepareLegacyRequest($request);
$this->container = $this->kernel->getContainer();
$config = $this->container->get('config.factory');
......
......@@ -155,7 +155,8 @@ protected function setUp() {
// Back up settings from TestBase::prepareEnvironment().
$settings = Settings::getAll();
// Bootstrap a new kernel. Don't use createFromRequest so we don't mess with settings.
$this->kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
$class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
$this->kernel = new DrupalKernel('testing', $class_loader, FALSE);
$request = Request::create('/');
$this->kernel->setSitePath(DrupalKernel::findSitePath($request));
$this->kernel->boot();
......
......@@ -861,14 +861,15 @@ protected function setUp() {
// Since Drupal is bootstrapped already, install_begin_request() will not
// bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to
// reload the newly written custom settings.php manually.
Settings::initialize($directory);
$class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
Settings::initialize($directory, $class_loader);
// Execute the non-interactive installer.
require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
install_drupal($parameters);
// Import new settings.php written by the installer.
Settings::initialize($directory);
Settings::initialize($directory, $class_loader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
}
......@@ -882,7 +883,7 @@ protected function setUp() {
chmod($directory, 0777);
$request = \Drupal::request();
$this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', TRUE);
$this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', TRUE);
$this->kernel->prepareLegacyRequest($request);
// Force the container to be built from scratch instead of loaded from the
// disk. This forces us to not accidently load the parent site.
......
......@@ -9,7 +9,7 @@
use Drupal\Core\DrupalKernel;
use Drupal\Core\Site\Settings;
use Drupal\simpletest\DrupalUnitTestBase;
use Drupal\simpletest\KernelTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
......@@ -17,12 +17,7 @@
*
* @group DrupalKernel
*/
class DrupalKernelTest extends DrupalUnitTestBase {
/**
* @var \Composer\Autoload\ClassLoader
*/
protected $classloader;
class DrupalKernelTest extends KernelTestBase {
protected function setUp() {
// DrupalKernel relies on global $config_directories and requires those
......@@ -38,8 +33,6 @@ protected function setUp() {
'directory' => DRUPAL_ROOT . '/' . $this->public_files_directory . '/php',
'secret' => Settings::getHashSalt(),
)));
$this->classloader = drupal_classloader();
}
/**
......@@ -59,7 +52,8 @@ protected function setUp() {
*/
protected function getTestKernel(Request $request, array $modules_enabled = NULL, $read_only = FALSE) {
// Manually create kernel to avoid replacing settings.
$kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'testing');
$class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
$kernel = DrupalKernel::createFromRequest($request, $class_loader, 'testing');
$this->settingsSet('hash_salt', $this->databasePrefix);
if (isset($modules_enabled)) {
$kernel->updateModules($modules_enabled);
......
......@@ -32,7 +32,8 @@ function testSystemInitIgnoresSecondaries() {
Database::addConnectionInfo('default', 'replica', $connection_info['default']);
db_ignore_replica();
$kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
$class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
$kernel = new DrupalKernel('testing', $class_loader, FALSE);
$event = new GetResponseEvent($kernel, Request::create('http://example.com'), HttpKernelInterface::MASTER_REQUEST);
$subscriber = new ReplicaDatabaseIgnoreSubscriber();
$subscriber->checkReplicaServer($event);
......
......@@ -25,7 +25,7 @@
// Manually resemble early bootstrap of DrupalKernel::boot().
require_once __DIR__ . '/includes/bootstrap.inc';
DrupalKernel::bootEnvironment();
Settings::initialize(DrupalKernel::findSitePath($request));
Settings::initialize(DrupalKernel::findSitePath($request), $autoloader);
if (Settings::get('rebuild_access', FALSE) ||
($request->get('token') && $request->get('timestamp') &&
......
......@@ -371,17 +371,23 @@
/**
* Class Loader.
*
* By default, Drupal uses Composer's ClassLoader, which is best for
* development, as it does not break when code is moved on the file
* system. It is possible, however, to wrap the class loader with a
* cached class loader solution for better performance, which is
* By default, Composer's ClassLoader is used, which is best for development, as
* it does not break when code is moved in the file system. You can decorate the
* class loader with a cached solution for better performance, which is
* recommended for production sites.
*
* Examples:
* $settings['class_loader'] = 'apc';
* $settings['class_loader'] = 'default';
* To do so, you may decorate and replace the local $class_loader variable.
*
* For example, to use Symfony's APC class loader, uncomment the code below.
*/
# $settings['class_loader'] = 'apc';
/*
if ($settings['hash_salt']) {
$apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader('drupal.' . $settings['hash_salt'], $class_loader);
$class_loader->unregister();
$apc_loader->register();
$class_loader = $apc_loader;
}
*/
/**
* Authorized file system operations:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment