diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index d488664..0f56781 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2264,6 +2264,13 @@ function _drupal_bootstrap_configuration() { // Load the procedural configuration system helper functions. require_once DRUPAL_ROOT . '/core/includes/config.inc'; + // 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 (empty($GLOBALS['databases']) && !drupal_installation_attempted()) { + include_once DRUPAL_ROOT . '/core/includes/install.inc'; + install_goto('core/install.php'); + } } /** @@ -2359,15 +2366,6 @@ function _drupal_initialize_db_test_prefix() { * Initializes the database system by loading database.inc. */ function _drupal_bootstrap_database() { - // 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 (empty($GLOBALS['databases']) && !drupal_installation_attempted()) { - include_once DRUPAL_ROOT . '/core/includes/install.inc'; - install_goto('core/install.php'); - } - - // Initialize the database system. Note that the connection // won't be initialized until it is actually requested. require_once DRUPAL_ROOT . '/core/includes/database.inc'; @@ -2442,10 +2440,9 @@ function drupal_container(Container $new_container = NULL, $rebuild = FALSE) { $container = $new_container; } if (!isset($container)) { - // Return a ContainerBuilder instance with the bare essentials needed for any - // full bootstrap regardless of whether there will be a DrupalKernel involved. - // This will get merged with the full Kernel-built Container on normal page - // requests. + // This is only ever used by the installer and by run-tests.sh. + // @todo Remove this entire section once these have been converted to use a + // kernel. $container = new ContainerBuilder(); // Register active configuration storage. @@ -2703,11 +2700,9 @@ function language($type, $reset = FALSE) { // When the language_manager service exists (is both defined and the 'request' // scope is active in the container), use it to get the language. Otherwise // return the default language. - try { + if (drupal_container()->isScopeActive('request')) { $language_manager = drupal_container()->get('language_manager', Container::NULL_ON_INVALID_REFERENCE); } - catch (DependencyInjectionRuntimeException $e) { - } if (isset($language_manager)) { return $language_manager->getLanguage($type); @@ -3443,54 +3438,6 @@ function drupal_check_memory_limit($required, $memory_limit = NULL) { } /** - * Instantiates and statically caches a storage controller for generated PHP code. - * - * By default, this returns an instance of the - * Drupal\Component\PhpStorage\MTimeProtectedFileStorage class. - * - * Classes implementing - * Drupal\Component\PhpStorage\PhpStorageInterface can be registered for a - * specific bin or as a default implementation. - * - * @param $name - * The name for which the storage controller should be returned. Defaults to - * 'default'. The name is also used as the storage bin if one is not - * specified in the configuration. - * - * @return Drupal\Component\PhpStorage\PhpStorageInterface - * An instantiated storage controller for the specified name. - * - * @see Drupal\Component\PhpStorage\PhpStorageInterface - */ -function drupal_php_storage($name = 'default') { - global $conf; - $storage_controllers = &drupal_static(__FUNCTION__); - if (!isset($storage_controllers[$name])) { - if (isset($conf['php_storage'][$name])) { - $configuration = $conf['php_storage'][$name]; - } - elseif (isset($conf['php_storage']['default'])) { - $configuration = $conf['php_storage']['default']; - } - else { - $configuration = array( - 'class' => 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage', - 'secret' => drupal_get_hash_salt(), - ); - } - $class = isset($configuration['class']) ? $configuration['class'] : 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage'; - if (!isset($configuration['bin'])) { - $configuration['bin'] = $name; - } - if (!isset($configuration['directory'])) { - $configuration['directory'] = DRUPAL_ROOT . '/' . variable_get('file_public_path', conf_path() . '/files') . '/php'; - } - $storage_controllers[$name] = new $class($configuration); - } - return $storage_controllers[$name]; -} - -/** * @defgroup lock Locking mechanisms * @{ * Functions to coordinate long-running operations across requests. diff --git a/core/includes/common.inc b/core/includes/common.inc index f8a54e9..facb9b3 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3,6 +3,7 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Drupal\Component\PhpStorage\PhpStorageFactory; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Datetime\DrupalDateTime; @@ -6748,8 +6749,8 @@ function drupal_flush_all_caches() { menu_router_rebuild(); // Wipe the PHP Storage caches. - drupal_php_storage('service_container')->deleteAll(); - drupal_php_storage('twig')->deleteAll(); + PhpStorageFactory::get('service_container')->deleteAll(); + PhpStorageFactory::get('twig')->deleteAll(); // Re-initialize the maintenance theme, if the current request attempted to // use it. Unlike regular usages of this function, the installer and update diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index d5983b6..4391e27 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1,6 +1,7 @@ boot(); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); } diff --git a/core/lib/Drupal/Component/PhpStorage/PhpStorageFactory.php b/core/lib/Drupal/Component/PhpStorage/PhpStorageFactory.php new file mode 100644 index 0000000..993f8c5 --- /dev/null +++ b/core/lib/Drupal/Component/PhpStorage/PhpStorageFactory.php @@ -0,0 +1,58 @@ + 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage', + 'secret' => $GLOBALS['drupal_hash_salt'], + ); + } + $class = isset($configuration['class']) ? $configuration['class'] : 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage'; + if (!isset($configuration['bin'])) { + $configuration['bin'] = $name; + } + if (!isset($configuration['directory'])) { + $path = isset($conf['file_public_path']) ? $conf['file_public_path'] : conf_path() . '/files'; + $configuration['directory'] = DRUPAL_ROOT . "/$path/php"; + } + return new $class($configuration); + } + +} diff --git a/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php b/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php new file mode 100644 index 0000000..ac9f67f --- /dev/null +++ b/core/lib/Drupal/Core/Config/BootstrapConfigStorageFactory.php @@ -0,0 +1,31 @@ +register('config.cachedstorage.storage', 'Drupal\Core\Config\FileStorage') + ->addArgument(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY)); + // @todo Replace this with a cache.factory service plus 'config' argument. + $container + ->register('cache.config', 'Drupal\Core\Cache\CacheBackendInterface') + ->setFactoryClass('Drupal\Core\Cache\CacheFactory') + ->setFactoryMethod('get') + ->addArgument('config'); + + $container + ->register('config.storage', 'Drupal\Core\Config\CachedStorage') + ->addArgument(new Reference('config.cachedstorage.storage')) + ->addArgument(new Reference('cache.config')); + + // Register configuration object factory. + $container->register('config.subscriber.globalconf', 'Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber'); + $container->register('dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher') + ->addMethodCall('addSubscriber', array(new Reference('config.subscriber.globalconf'))); + $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') + ->addArgument(new Reference('config.storage')) + ->addArgument(new Reference('dispatcher')); + + // Register staging configuration storage. + $container + ->register('config.storage.staging', 'Drupal\Core\Config\FileStorage') + ->addArgument(config_get_config_directory(CONFIG_STAGING_DIRECTORY)); + + // Register the service for the default database connection. + $container->register('database', 'Drupal\Core\Database\Connection') + ->setFactoryClass('Drupal\Core\Database\Database') + ->setFactoryMethod('getConnection') + ->addArgument('default'); + // Register the KeyValueStore factory. + $container + ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory') + ->addArgument(new Reference('service_container')); + $container + ->register('keyvalue.database', 'Drupal\Core\KeyValueStore\KeyValueDatabaseFactory') + ->addArgument(new Reference('database')); + + // Register the EntityManager. + $container->register('plugin.manager.entity', 'Drupal\Core\Entity\EntityManager'); // The 'request' scope and service enable services to depend on the Request // object and get reconstructed when the request object changes (e.g., // during a subrequest). diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 072e109..a48e21a 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -7,11 +7,10 @@ namespace Drupal\Core; -use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Component\PhpStorage\PhpStorageFactory; use Symfony\Component\ClassLoader\UniversalClassLoader; -use Drupal\Core\Config\FileStorage; +use Drupal\Core\Config\BootstrapConfigStorageFactory; use Drupal\Core\CoreBundle; -use Drupal\Component\PhpStorage\PhpStorageInterface; use Symfony\Component\HttpKernel\Kernel; use Drupal\Core\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\Loader\LoaderInterface; @@ -59,6 +58,20 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface { protected $moduleData = array(); /** + * Holds a list of enabled modules and their paths. + * + * This is used to store module data as a container parameter so that it can + * be retrieved for registering namespaces when using a compiled container. + * When not using a compiled container, the namespaces get registered during + * the process of building the container. + * + * @var array + * An associative array whose keys are module names and whose values are + * module paths. + */ + protected $modulePaths = array(); + + /** * PHP code storage object to use for the compiled container. * * @var \Drupal\Component\PhpStorage\PhpStorageInterface @@ -73,6 +86,13 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface { protected $classLoader; /** + * Config storage object used for reading enabled modules configuration. + * + * @var \Drupal\Core\Config\StorageInterface + */ + protected $configStorage; + + /** * The list of the classnames of the bundles in this kernel. * * @var array @@ -80,6 +100,20 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface { protected $bundleClasses; /** + * Whether the container can be dumped. + * + * @var bool + */ + protected $allowDumping; + + /** + * Whether the container needs to be dumped. + * + * @var bool + */ + protected $containerNeedsDumping; + + /** * Constructs a DrupalKernel object. * * @param string $environment @@ -95,15 +129,14 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface { * 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 bundles. - * @param \Drupal\Component\PhpStorage\PhpStorageInterface $storage - * (optional) An object handling the load and save of the compiled - * container. If not specified, the container will neither be stored to - * disk nor read from there. + * @param bool $allow_dumping + * (optional) FALSE to stop the container from being written to or read + * from disk. */ - public function __construct($environment, $debug, UniversalClassLoader $class_loader, PhpStorageInterface $storage = NULL) { + public function __construct($environment, $debug, UniversalClassLoader $class_loader, $allow_dumping = TRUE) { parent::__construct($environment, $debug); - $this->storage = $storage; $this->classLoader = $class_loader; + $this->allowDumping = $allow_dumping; } /** @@ -125,28 +158,44 @@ public function boot() { } $this->initializeContainer(); $this->booted = TRUE; + // @todo Remove this once everything in the bootstrap has been converted to + // services in the DIC. + drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); + // Now that full bootstrap is complete, we can dump the container if it + // was just rebuilt. + if ($this->containerNeedsDumping && !$this->dumpDrupalContainer($this->container, $this->getContainerBaseClass())) { + watchdog('DrupalKernel', 'Container cannot be written to disk'); + } } /** * Returns an array of available bundles. */ public function registerBundles() { + $this->configStorage = BootstrapConfigStorageFactory::get(); $bundles = array( new CoreBundle(), ); if (!isset($this->moduleList)) { - $storage = new FileStorage(config_get_config_directory()); - $module_list = $storage->read('system.module'); + $module_list = $this->configStorage->read('system.module'); $this->moduleList = isset($module_list['enabled']) ? $module_list['enabled'] : array(); } $namespaces = $this->classLoader->getNamespaces(); + // We will need to store module locations in a container parameter so that + // we can register all namespaces when using a compiled container. + $this->modulePaths = array(); foreach ($this->moduleList as $module => $weight) { // When installing new modules, the modules in the list passed to // updateModules() do not yet have their namespace registered. $namespace = 'Drupal\\' . $module; if (!isset($namespaces[$namespace]) && $this->moduleData($module)) { - $this->classLoader->registerNamespace($namespace, dirname(DRUPAL_ROOT . '/' . $this->moduleData($module)->uri) . '/lib'); + $path = dirname(DRUPAL_ROOT . '/' . $this->moduleData($module)->uri) . '/lib'; + $this->modulePaths[$module] = $path; + $this->classLoader->registerNamespace($namespace, $path); + } + else { + $this->modulePaths[$module] = $namespaces[$namespace]; } $camelized = ContainerBuilder::camelize($module); $class = "Drupal\\{$module}\\{$camelized}Bundle"; @@ -177,10 +226,9 @@ protected function moduleData($module) { $profiles_scanner = new SystemListing(); $all_profiles = $profiles_scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); $profiles = array_keys(array_intersect_key($this->moduleList, $all_profiles)); - $storage = new FileStorage(config_get_config_directory()); // If a module is within a profile directory but specifies another // profile for testing, it needs to be found in the parent profile. - if (($parent_profile_config = $storage->read('simpletest.settings')) && isset($parent_profile_config['parent_profile']) && $parent_profile_config['parent_profile'] != $profiles[0]) { + if (($parent_profile_config = $this->configStorage->read('simpletest.settings')) && isset($parent_profile_config['parent_profile']) && $parent_profile_config['parent_profile'] != $profiles[0]) { // In case both profile directories contain the same extension, the // actual profile always has precedence. array_unshift($profiles, $parent_profile_config['parent_profile']); @@ -236,10 +284,10 @@ protected function initializeContainer() { $class = $this->getClassName(); $cache_file = $class . '.php'; - if ($this->storage) { + if ($this->allowDumping) { // First, try to load. if (!class_exists($class, FALSE)) { - $this->storage->load($cache_file); + $this->storage()->load($cache_file); } // If the load succeeded or the class already existed, use it. if (class_exists($class, FALSE)) { @@ -259,28 +307,32 @@ protected function initializeContainer() { // web frontend or during the installer -- changed the list of enabled // modules. if (isset($this->container)) { + // All namespaces must be registered before we attempt to use any service + // from the container. + $namespaces = $this->classLoader->getNamespaces(); + foreach ($this->container->getParameter('container.modules') as $module => $path) { + $namespace = 'Drupal\\' . $module; + if (!isset($namespaces[$namespace])) { + $this->classLoader->registerNamespace($namespace, $path); + } + } $module_list = $this->moduleList ?: $this->container->get('config.factory')->get('system.module')->load()->get('enabled'); - if (array_keys((array)$module_list) !== $this->container->getParameter('container.modules')) { + if (array_keys((array)$module_list) !== array_keys($this->container->getParameter('container.modules'))) { unset($this->container); } } if (!isset($this->container)) { $this->container = $this->buildContainer(); - if ($this->storage && !$this->dumpDrupalContainer($this->container, $this->getContainerBaseClass())) { - // We want to log this as an error but we cannot call watchdog() until - // the container has been fully built and set in drupal_container(). - $error = 'Container cannot be written to disk'; + if ($this->allowDumping) { + $this->containerNeedsDumping = TRUE; } } $this->container->set('kernel', $this); + $this->container->set('class_loader', $this->classLoader); drupal_container($this->container); - - if (isset($error)) { - watchdog('DrupalKernel', $error); - } } /** @@ -292,12 +344,10 @@ protected function buildContainer() { $this->initializeBundles(); $container = $this->getContainerBuilder(); $container->setParameter('container.bundles', $this->bundleClasses); - $container->setParameter('container.modules', array_keys($this->moduleList)); + $container->setParameter('container.modules', $this->modulePaths); + // Register the class loader and php storage mechanism as synthetic services + $container->register('class_loader', 'Symfony\Component\ClassLoader\UniversalClassLoader')->setSynthetic(TRUE); - // Merge in the minimal bootstrap container. - if ($bootstrap_container = drupal_container()) { - $container->merge($bootstrap_container); - } foreach ($this->bundles as $bundle) { $bundle->build($container); } @@ -329,14 +379,14 @@ protected function getContainerBuilder() { * TRUE if the container was successfully dumped to disk. */ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass) { - if (!$this->storage->writeable()) { + if (!$this->storage()->writeable()) { return FALSE; } // Cache the container. $dumper = new PhpDumper($container); $class = $this->getClassName(); $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass)); - return $this->storage->save($class . '.php', $content); + return $this->storage()->save($class . '.php', $content); } /** @@ -352,4 +402,16 @@ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass) public function registerContainerConfiguration(LoaderInterface $loader) { } + /** + * Gets the PHP code storage object to use for the compiled container. + * + * @return \Drupal\Component\PhpStorage\PhpStorageInterface + */ + protected function storage() { + if (!isset($this->storage)) { + $this->storage = PhpStorageFactory::get('service_container'); + } + return $this->storage; + } + } diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php index d4c8b8b..d54b776 100644 --- a/core/lib/Drupal/Core/DrupalKernelInterface.php +++ b/core/lib/Drupal/Core/DrupalKernelInterface.php @@ -25,8 +25,6 @@ * * @param array $module_list * The new list of modules. - * @param array $module_path - * List of module paths, keyed by module name. */ - public function updateModules(array $module_list, array $module_path = array()); + public function updateModules(array $module_list, array $module_paths = array()); } diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index bc7ab65..b5e60b1 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -6,6 +6,7 @@ */ namespace Drupal\Core\Template; +use Drupal\Component\PhpStorage\PhpStorageFactory; /** * A class that defines a Twig environment for Drupal. @@ -24,9 +25,8 @@ class TwigEnvironment extends \Twig_Environment { * internally. */ public function __construct(\Twig_LoaderInterface $loader = NULL, $options = array()) { - // @todo Pass as arguments from the DIC? + // @todo Pass as arguments from the DIC. $this->cache_object = cache(); - $this->storage = drupal_php_storage('twig'); parent::__construct($loader, $options); } @@ -47,7 +47,7 @@ public function needsUpdate($cache_filename, $name) { public function updateCompiledTemplate($cache_filename, $name) { $source = $this->loader->getSource($name); $compiled_source = $this->compileSource($source, $name); - $this->storage->save($cache_filename, $compiled_source); + $this->storage()->save($cache_filename, $compiled_source); // Save the last modification time $cid = 'twig:' . $cache_filename; $this->cache_object->set($cid, REQUEST_TIME); @@ -83,9 +83,9 @@ public function loadTemplate($name, $index = NULL) { $this->updateCompiledTemplate($cache_filename, $name); } - if (!$this->storage->load($cache_filename)) { + if (!$this->storage()->load($cache_filename)) { $this->updateCompiledTemplate($cache_filename, $name); - $this->storage->load($cache_filename); + $this->storage()->load($cache_filename); } } } @@ -97,4 +97,16 @@ public function loadTemplate($name, $index = NULL) { return $this->loadedTemplates[$cls] = new $cls($this); } + /** + * Gets the PHP code storage object to use for the compiled Twig files. + * + * @return \Drupal\Component\PhpStorage\PhpStorageInterface + */ + protected function storage() { + if (!isset($this->storage)) { + $this->storage = PhpStorageFactory::get('service_container'); + } + return $this->storage; + } + } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index 89ccb8e..1be5b81 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -7,6 +7,7 @@ namespace Drupal\simpletest; +use Drupal\Component\PhpStorage\PhpStorageFactory; use Drupal\Core\Database\Database; use Drupal\Core\Database\ConnectionNotDefinedException; use Drupal\Core\DrupalKernel; @@ -912,7 +913,7 @@ protected function rebuildContainer() { // container in drupal_container(). Drupal\simpletest\TestBase::tearDown() // restores the original container. // @see Drupal\Core\DrupalKernel::initializeContainer() - $this->kernel = new DrupalKernel('testing', FALSE, drupal_classloader()); + $this->kernel = new DrupalKernel('testing', FALSE, drupal_classloader(), FALSE); // Booting the kernel is necessary to initialize the new DIC. While // normally the kernel gets booted on demand in // Symfony\Component\HttpKernel\handle(), this kernel needs manual booting diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php index f4dd294..c313d82 100644 --- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php @@ -36,23 +36,24 @@ function testCompileDIC() { // test. $original_container = drupal_container(); $classloader = drupal_classloader(); - $configuration = array( + global $conf; + $conf['php_storage']['service_container']= array( 'bin' => 'service_container', + 'class' => 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage', 'directory' => DRUPAL_ROOT . '/' . variable_get('file_public_path', conf_path() . '/files') . '/php', 'secret' => $GLOBALS['drupal_hash_salt'], ); // @todo: write a memory based storage backend for testing. - $php_storage = new MTimeProtectedFastFileStorage($configuration); $module_enabled = array( 'system' => 'system', 'user' => 'user', ); - $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage); + $kernel = new DrupalKernel('testing', FALSE, $classloader); $kernel->updateModules($module_enabled); $kernel->boot(); // Instantiate it a second time and we should get the compiled Container // class. - $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage); + $kernel = new DrupalKernel('testing', FALSE, $classloader); $kernel->updateModules($module_enabled); $kernel->boot(); $container = $kernel->getContainer(); @@ -67,8 +68,8 @@ function testCompileDIC() { // Now use the read-only storage implementation, simulating a "production" // environment. - $php_storage = new FileReadOnlyStorage($configuration); - $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage); + $conf['php_storage']['service_container']['class'] = 'Drupal\Component\PhpStorage\FileReadOnlyStorage'; + $kernel = new DrupalKernel('testing', FALSE, $classloader); $kernel->updateModules($module_enabled); $kernel->boot(); $container = $kernel->getContainer(); @@ -77,6 +78,10 @@ function testCompileDIC() { $refClass->getParentClass()->getName() == 'Symfony\Component\DependencyInjection\Container' && !$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder'); $this->assertTrue($is_compiled_container); + // Test that our synthetic services are there. + $classloader = $container->get('class_loader'); + $refClass = new ReflectionClass($classloader); + $this->assertTrue($refClass->hasMethod('getNamespaces'), 'Container has a classloader'); // We make this assertion here purely to show that the new container below // is functioning correctly, i.e. we get a brand new ContainerBuilder @@ -90,12 +95,12 @@ function testCompileDIC() { // Add another module so that we can test that the new module's bundle is // registered to the new container. $module_enabled['bundle_test'] = 'bundle_test'; - $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage); + $kernel = new DrupalKernel('testing', FALSE, $classloader); $kernel->updateModules($module_enabled); $kernel->boot(); // Instantiate it a second time and we should still get a ContainerBuilder // class because we are using the read-only PHP storage. - $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage); + $kernel = new DrupalKernel('testing', FALSE, $classloader); $kernel->updateModules($module_enabled); $kernel->boot(); $container = $kernel->getContainer(); @@ -104,6 +109,10 @@ function testCompileDIC() { $this->assertTrue($is_container_builder); // Assert that the new module's bundle was registered to the new container. $this->assertTrue($container->has('bundle_test_class')); + // Test that our synthetic services are there. + $classloader = $container->get('class_loader'); + $refClass = new ReflectionClass($classloader); + $this->assertTrue($refClass->hasMethod('getNamespaces'), 'Container has a classloader'); // Restore the original container. drupal_container($original_container); diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/ClassLoaderTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/ClassLoaderTest.php index df59ea0..7f61652 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Module/ClassLoaderTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Module/ClassLoaderTest.php @@ -37,10 +37,13 @@ function testClassLoading() { module_disable(array('module_autoload_test'), FALSE); $this->resetAll(); - // Check twice to test an unprimed and primed system_list() cache. + // The first request after a module has been disabled will result in that + // module's namespace getting registered because the kernel registers all + // namespaces in the existing 'container.modules' parameter before checking + // whether the list of modules has changed and rebuilding the container. 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($expected, 'Autoloader does not load classes from a disabled module.'); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/PhpStorage/FileStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/PhpStorage/FileStorageTest.php index 6280cc4..d1de46e 100644 --- a/core/modules/system/lib/Drupal/system/Tests/PhpStorage/FileStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/PhpStorage/FileStorageTest.php @@ -39,7 +39,7 @@ function setUp() { * Tests basic load/save/delete operations. */ function testCRUD() { - $php = drupal_php_storage('simpletest'); + $php = $this->storageFactory->get('simpletest'); $this->assertIdentical(get_class($php), 'Drupal\Component\PhpStorage\FileStorage'); $this->assertCRUD($php); } @@ -48,7 +48,7 @@ function testCRUD() { * Tests writing with one class and reading with another. */ function testReadOnly() { - $php = drupal_php_storage('simpletest'); + $php = $this->storageFactory->get('simpletest'); $name = $this->randomName() . '/' . $this->randomName() . '.php'; // Find a global that doesn't exist. @@ -60,7 +60,7 @@ function testReadOnly() { $code = "save($name, $code); $this->assertIdentical($success, TRUE); - $php_read = drupal_php_storage('readonly'); + $php_read = $this->storageFactory->get('readonly'); $php_read->load($name); $this->assertTrue($GLOBALS[$random]); diff --git a/core/modules/system/lib/Drupal/system/Tests/PhpStorage/MTimeProtectedFileStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/PhpStorage/MTimeProtectedFileStorageTest.php index a0649cb..ae54c2f 100644 --- a/core/modules/system/lib/Drupal/system/Tests/PhpStorage/MTimeProtectedFileStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/PhpStorage/MTimeProtectedFileStorageTest.php @@ -7,6 +7,8 @@ namespace Drupal\system\Tests\PhpStorage; +use Drupal\Component\PhpStorage\PhpStorageFactory; + /** * Tests the directory mtime based PHP loader implementation. */ @@ -45,7 +47,7 @@ function setUp() { * Tests basic load/save/delete operations. */ function testCRUD() { - $php = drupal_php_storage('simpletest'); + $php = $this->storageFactory->get('simpletest'); $this->assertIdentical(get_class($php), $this->storageClass); $this->assertCRUD($php); } @@ -57,7 +59,7 @@ function testCRUD() { * mtime too. */ function testSecurity() { - $php = drupal_php_storage('simpletest'); + $php = $this->storageFactory->get('simpletest'); $name = 'simpletest.php'; $php->save($name, 'storageFactory->get('simpletest'); $GLOBALS['hacked'] = FALSE; $untrusted_code = "storageFactory = new PhpStorageFactory; + } + + /** * Assert that a PHP storage controller's load/save/delete operations work. */ public function assertCRUD($php) { diff --git a/core/modules/system/tests/http.php b/core/modules/system/tests/http.php index 8594648..f53bea6 100644 --- a/core/modules/system/tests/http.php +++ b/core/modules/system/tests/http.php @@ -36,6 +36,6 @@ drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); -$kernel = new DrupalKernel('prod', FALSE, drupal_classloader()); +$kernel = new DrupalKernel('prod', FALSE, drupal_classloader(), FALSE); $response = $kernel->handle($request)->prepare($request)->send(); $kernel->terminate($request, $response); diff --git a/core/modules/system/tests/https.php b/core/modules/system/tests/https.php index 54d8878..e186f0c 100644 --- a/core/modules/system/tests/https.php +++ b/core/modules/system/tests/https.php @@ -35,6 +35,6 @@ drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); -$kernel = new DrupalKernel('prod', FALSE, drupal_classloader()); +$kernel = new DrupalKernel('prod', FALSE, drupal_classloader(), FALSE); $response = $kernel->handle($request)->prepare($request)->send(); $kernel->terminate($request, $response); diff --git a/index.php b/index.php index 4d56290..818d98f 100644 --- a/index.php +++ b/index.php @@ -12,6 +12,7 @@ */ use Drupal\Core\DrupalKernel; +use Drupal\Component\PhpStorage\PhpStorageFactory; use Symfony\Component\HttpFoundation\Request; /** @@ -25,10 +26,10 @@ // @see Drupal\Core\EventSubscriber\PathSubscriber; // @see Drupal\Core\EventSubscriber\LegacyRequestSubscriber; require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc'; -drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); +drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION); // @todo Figure out how best to handle the Kernel constructor parameters. -$kernel = new DrupalKernel('prod', FALSE, drupal_classloader(), drupal_php_storage('service_container')); +$kernel = new DrupalKernel('prod', FALSE, drupal_classloader()); // Create a request object from the HTTPFoundation. $request = Request::createFromGlobals();