Issue #1658720 by RobLoach, dawehner, sun, chx: Use ClassLoader instead of UniversalClassLoader.
parent
7aca9955dc
commit
8c21dcb622
|
@ -21,6 +21,13 @@
|
|||
"easyrdf/easyrdf": "0.8.0-beta.1",
|
||||
"phpunit/phpunit": "3.7.15"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Drupal\\Core": "core/lib/",
|
||||
"Drupal\\Component": "core/lib/",
|
||||
"Drupal\\Driver": "drivers/lib/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"config": {
|
||||
"vendor-dir": "core/vendor"
|
||||
|
|
|
@ -6,8 +6,8 @@ use Drupal\Component\Utility\Timer;
|
|||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader;
|
||||
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
|
||||
use Symfony\Component\ClassLoader\ClassLoader;
|
||||
use Symfony\Component\ClassLoader\ApcClassLoader;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
@ -3076,78 +3076,41 @@ function ip_address() {
|
|||
* loader class when calling drupal_classloader() from settings.php. It is
|
||||
* ignored otherwise.
|
||||
*
|
||||
* @return Symfony\Component\ClassLoader\UniversalClassLoader
|
||||
* A UniversalClassLoader class instance (or extension thereof).
|
||||
* @return \Symfony\Component\ClassLoader\ClassLoader
|
||||
* A ClassLoader class instance (or extension thereof).
|
||||
*/
|
||||
function drupal_classloader($class_loader = NULL) {
|
||||
// By default, use the UniversalClassLoader 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.
|
||||
// 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)) {
|
||||
|
||||
// Include the Symfony ClassLoader for loading PSR-0-compatible classes.
|
||||
require_once DRUPAL_ROOT . '/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php';
|
||||
if (!isset($class_loader) && class_exists('Drupal\Component\Utility\Settings', FALSE)) {
|
||||
$class_loader = settings()->get('class_loader');
|
||||
require_once DRUPAL_ROOT . '/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/ClassLoader.php';
|
||||
$loader = new ClassLoader();
|
||||
|
||||
// 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 DRUPAL_ROOT . '/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcClassLoader.php';
|
||||
$apc_loader = new ApcClassLoader('drupal.' . $GLOBALS['drupal_hash_salt'], $loader);
|
||||
$apc_loader->register();
|
||||
}
|
||||
else {
|
||||
$loader->register();
|
||||
}
|
||||
|
||||
switch ($class_loader) {
|
||||
case 'apc':
|
||||
if (function_exists('apc_store')) {
|
||||
require_once DRUPAL_ROOT . '/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php';
|
||||
$loader = new ApcUniversalClassLoader('drupal.' . $GLOBALS['drupal_hash_salt']);
|
||||
break;
|
||||
}
|
||||
// Fall through to the default loader if APC was not loaded, so that the
|
||||
// site does not fail completely.
|
||||
case 'dev':
|
||||
case 'default':
|
||||
default:
|
||||
$loader = new UniversalClassLoader();
|
||||
break;
|
||||
}
|
||||
|
||||
// Register explicit namespaces for Drupal core.
|
||||
// The majority of namespaces that need to be resolved are from Drupal core,
|
||||
// so registering/setting them before vendor libraries saves a few
|
||||
// additional cycles per class lookup.
|
||||
$loader->registerNamespaces(array(
|
||||
'Drupal\Core' => DRUPAL_ROOT . '/core/lib',
|
||||
'Drupal\Component' => DRUPAL_ROOT . '/core/lib',
|
||||
'Drupal\Driver' => DRUPAL_ROOT . '/drivers/lib',
|
||||
));
|
||||
|
||||
// Register namespaces and PEAR-like prefixes for vendor libraries managed
|
||||
// by Composer. Composer combines libraries that use PHP 5.3 namespaces and
|
||||
// ones that use PEAR-like class prefixes in a single array, but the Symfony
|
||||
// class loader requires them to be registered separately.
|
||||
// Register namespaces for vendor libraries managed by Composer.
|
||||
$prefixes_and_namespaces = require DRUPAL_ROOT . '/core/vendor/composer/autoload_namespaces.php';
|
||||
$prefixes = array();
|
||||
$namespaces = array();
|
||||
foreach ($prefixes_and_namespaces as $key => $path) {
|
||||
// If the key:
|
||||
// - Contains a namespace separator, we know it's a namespace.
|
||||
// - Doesn't contain a namespace separator and ends in an "_" (e.g.,
|
||||
// "Twig_"), it's likely intended as a PEAR-like prefix rather than a
|
||||
// namespace.
|
||||
// - Doesn't contain a namespace separator or end in an "_" (e.g.,
|
||||
// "Assetic"), then it could be either a namespace or an incomplete
|
||||
// PEAR-like prefix, but we assume the former, since the only example of
|
||||
// that currently in Drupal is Assetic.
|
||||
// @todo Switch to a class loader that doesn't require this guessing:
|
||||
// http://drupal.org/node/1658720.
|
||||
$is_namespace = (strpos($key, '\\') !== FALSE) && (substr($key, -1) !== '_');
|
||||
if ($is_namespace) {
|
||||
$namespaces[rtrim($key, '\\')] = $path;
|
||||
}
|
||||
else {
|
||||
$prefixes[$key] = $path;
|
||||
}
|
||||
}
|
||||
$loader->registerPrefixes($prefixes);
|
||||
$loader->registerNamespaces($namespaces);
|
||||
$loader->addPrefixes($prefixes_and_namespaces);
|
||||
|
||||
// Register the loader with PHP.
|
||||
$loader->register();
|
||||
|
@ -3165,7 +3128,7 @@ function drupal_classloader($class_loader = NULL) {
|
|||
*/
|
||||
function drupal_classloader_register($name, $path) {
|
||||
$loader = drupal_classloader();
|
||||
$loader->registerNamespace('Drupal\\' . $name, DRUPAL_ROOT . '/' . $path . '/lib');
|
||||
$loader->addPrefix('Drupal\\' . $name, DRUPAL_ROOT . '/' . $path . '/lib');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,7 +11,7 @@ use Drupal\Component\PhpStorage\PhpStorageFactory;
|
|||
use Drupal\Core\Config\BootstrapConfigStorageFactory;
|
||||
use Drupal\Core\CoreBundle;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader;
|
||||
use Symfony\Component\ClassLoader\ClassLoader;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
|
@ -67,7 +67,7 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
/**
|
||||
* The classloader object.
|
||||
*
|
||||
* @var \Symfony\Component\ClassLoader\UniversalClassLoader
|
||||
* @var \Symfony\Component\ClassLoader\ClassLoader
|
||||
*/
|
||||
protected $classLoader;
|
||||
|
||||
|
@ -110,7 +110,7 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
* Boolean indicating whether we are in debug mode. Used by
|
||||
* Symfony\Component\HttpKernel\Kernel::__construct(). Drupal does not use
|
||||
* this value currently. Pass TRUE.
|
||||
* @param \Symfony\Component\ClassLoader\UniversalClassLoader $class_loader
|
||||
* @param \Symfony\Component\ClassLoader\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
|
||||
|
@ -119,7 +119,7 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
* (optional) FALSE to stop the container from being written to or read
|
||||
* from disk. Defaults to TRUE.
|
||||
*/
|
||||
public function __construct($environment, $debug, UniversalClassLoader $class_loader, $allow_dumping = TRUE) {
|
||||
public function __construct($environment, $debug, ClassLoader $class_loader, $allow_dumping = TRUE) {
|
||||
parent::__construct($environment, $debug);
|
||||
$this->classLoader = $class_loader;
|
||||
$this->allowDumping = $allow_dumping;
|
||||
|
@ -294,7 +294,7 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
// All namespaces must be registered before we attempt to use any service
|
||||
// from the container.
|
||||
$container_modules = $this->container->getParameter('container.modules');
|
||||
$namespaces_before = $this->classLoader->getNamespaces();
|
||||
$namespaces_before = $this->classLoader->getPrefixes();
|
||||
$this->registerNamespaces($this->getModuleNamespaces($container_modules));
|
||||
|
||||
// If 'container.modules' is wrong, the container must be rebuilt.
|
||||
|
@ -308,9 +308,9 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
// registerNamespaces() performs a merge rather than replace, so to
|
||||
// effectively remove erroneous registrations, we must replace them with
|
||||
// empty arrays.
|
||||
$namespaces_after = $this->classLoader->getNamespaces();
|
||||
$namespaces_after = $this->classLoader->getPrefixes();
|
||||
$namespaces_before += array_fill_keys(array_diff(array_keys($namespaces_after), array_keys($namespaces_before)), array());
|
||||
$this->classLoader->registerNamespaces($namespaces_before);
|
||||
$this->registerNamespaces($namespaces_before);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,7 +376,7 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
$container->setParameter('container.namespaces', $namespaces);
|
||||
|
||||
// Register synthetic services.
|
||||
$container->register('class_loader', 'Symfony\Component\ClassLoader\UniversalClassLoader')->setSynthetic(TRUE);
|
||||
$container->register('class_loader', 'Symfony\Component\ClassLoader\ClassLoader')->setSynthetic(TRUE);
|
||||
$container->register('kernel', 'Symfony\Component\HttpKernel\KernelInterface')->setSynthetic(TRUE);
|
||||
$container->register('service_container', 'Symfony\Component\DependencyInjection\ContainerInterface')->setSynthetic(TRUE);
|
||||
foreach ($this->bundles as $bundle) {
|
||||
|
@ -474,8 +474,6 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
|
|||
* Registers a list of namespaces.
|
||||
*/
|
||||
protected function registerNamespaces(array $namespaces = array()) {
|
||||
foreach ($namespaces as $namespace => $dir) {
|
||||
$this->classLoader->registerNamespace($namespace, $dir);
|
||||
}
|
||||
$this->classLoader->addPrefixes($namespaces);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -526,19 +526,19 @@ function simpletest_classloader_register() {
|
|||
$matches = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir']);
|
||||
foreach ($matches as $name => $file) {
|
||||
drupal_classloader_register($name, dirname($file->uri));
|
||||
drupal_classloader()->registerNamespace('Drupal\\' . $name . '\\Tests', DRUPAL_ROOT . '/' . dirname($file->uri) . '/tests');
|
||||
drupal_classloader()->addPrefix('Drupal\\' . $name . '\\Tests', DRUPAL_ROOT . '/' . dirname($file->uri) . '/tests');
|
||||
// While being there, prime drupal_get_filename().
|
||||
drupal_get_filename($type, $name, $file->uri);
|
||||
}
|
||||
}
|
||||
|
||||
// Register the core test directory so we can find Drupal\UnitTestCase.
|
||||
drupal_classloader()->registerNamespace('Drupal\\Tests', DRUPAL_ROOT . '/core/tests');
|
||||
drupal_classloader()->addPrefix('Drupal\\Tests', DRUPAL_ROOT . '/core/tests');
|
||||
|
||||
// Manually register phpunit prefixes because they use a classmap instead of a
|
||||
// prefix. This can be safely removed if we move to using composer's
|
||||
// autoloader with a classmap.
|
||||
drupal_classloader()->registerPrefixes(array(
|
||||
drupal_classloader()->addPrefixes(array(
|
||||
'PHPUnit' => DRUPAL_ROOT . '/core/vendor/phpunit/phpunit',
|
||||
'File_Iterator' => DRUPAL_ROOT . '/core/vendor/phpunit/php-file-iterator/',
|
||||
'PHP_Timer' => DRUPAL_ROOT . '/core/vendor/phpunit/php-timer/',
|
||||
|
|
|
@ -13,6 +13,12 @@ use Drupal\simpletest\WebTestBase;
|
|||
* Tests class loading.
|
||||
*/
|
||||
class ClassLoaderTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* The expected result from calling the module-provided class' method.
|
||||
*/
|
||||
protected $expected = 'Drupal\\module_autoload_test\\SomeClass::testMethod() was invoked.';
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Module class loader',
|
||||
|
@ -23,24 +29,33 @@ class ClassLoaderTest extends WebTestBase {
|
|||
|
||||
/**
|
||||
* Tests that module-provided classes can be loaded when a module is enabled.
|
||||
*
|
||||
* @see \Drupal\module_autoload_test\SomeClass
|
||||
*/
|
||||
function testClassLoading() {
|
||||
$expected = 'Drupal\\module_autoload_test\\SomeClass::testMethod() was invoked.';
|
||||
|
||||
// Enable the module_test and module_autoload_test modules.
|
||||
module_enable(array('module_test', 'module_autoload_test'), FALSE);
|
||||
$this->resetAll();
|
||||
// Check twice to test an unprimed and primed system_list() cache.
|
||||
for ($i=0; $i<2; $i++) {
|
||||
$this->drupalGet('module-test/class-loading');
|
||||
$this->assertText($expected, 'Autoloader loads classes from an enabled module.');
|
||||
$this->assertText($this->expected, 'Autoloader loads classes from an enabled module.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that module-provided classes can't be loaded from disabled modules.
|
||||
*
|
||||
* @see \Drupal\module_autoload_test\SomeClass
|
||||
*/
|
||||
function testClassLoadingDisabledModules() {
|
||||
// Ensure that module_autoload_test is disabled.
|
||||
module_disable(array('module_autoload_test'), FALSE);
|
||||
$this->resetAll();
|
||||
// Check twice to test an unprimed and primed system_list() cache.
|
||||
for ($i=0; $i<2; $i++) {
|
||||
$this->drupalGet('module-test/class-loading');
|
||||
$this->assertNoText($expected, 'Autoloader does not load classes from a disabled module.');
|
||||
$this->assertNoText($this->expected, 'Autoloader does not load classes from a disabled module.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ $vendorDir = dirname(__DIR__);
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Drupal\\Driver' => $baseDir . '/../drivers/lib/',
|
||||
'Drupal\\Core' => $baseDir . '/lib/',
|
||||
'Drupal\\Component' => $baseDir . '/lib/',
|
||||
'Twig_' => $vendorDir . '/twig/twig/lib/',
|
||||
'Symfony\\Component\\Yaml\\' => $vendorDir . '/symfony/yaml/',
|
||||
'Symfony\\Component\\Validator\\' => $vendorDir . '/symfony/validator/',
|
||||
|
|
Loading…
Reference in New Issue