Issue #1599108: first pass at adding bundles
Conflicts: core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php8.0.x
parent
e06c4610db
commit
47c9feb9e7
|
@ -2458,7 +2458,7 @@ function drupal_container(ContainerBuilder $reset = NULL) {
|
|||
$container = $reset;
|
||||
}
|
||||
elseif (!isset($container)) {
|
||||
$container = new ContainerBuilder();
|
||||
// HALP!!
|
||||
}
|
||||
return $container;
|
||||
}
|
||||
|
|
|
@ -4913,9 +4913,9 @@ function _drupal_bootstrap_code() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Temporary BC function for scripts not using HttpKernel.
|
||||
* Temporary BC function for scripts not using DrupalKernel.
|
||||
*
|
||||
* HttpKernel skips this and replicates it via event listeners.
|
||||
* DrupalKernel skips this and replicates it via event listeners.
|
||||
*
|
||||
* @see Drupal\Core\EventSubscriber\PathSubscriber;
|
||||
* @see Drupal\Core\EventSubscriber\LegacyRequestSubscriber;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
|
||||
class RegisterKernelListenersPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('dispatcher')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('dispatcher');
|
||||
|
||||
foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) {
|
||||
|
||||
// We must assume that the class value has been correcly filled, even if the service is created by a factory
|
||||
$class = $container->getDefinition($id)->getClass();
|
||||
|
||||
$refClass = new \ReflectionClass($class);
|
||||
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
|
||||
if (!$refClass->implementsInterface($interface)) {
|
||||
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
|
||||
}
|
||||
$definition->addMethodCall('addSubscriberService', array($id, $class));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,113 +7,38 @@
|
|||
|
||||
namespace Drupal\Core\DependencyInjection;
|
||||
|
||||
use Drupal\Core\ContentNegotiation;
|
||||
use Drupal\Core\EventSubscriber\AccessSubscriber;
|
||||
use Drupal\Core\EventSubscriber\FinishResponseSubscriber;
|
||||
use Drupal\Core\EventSubscriber\LegacyControllerSubscriber;
|
||||
use Drupal\Core\EventSubscriber\LegacyRequestSubscriber;
|
||||
use Drupal\Core\EventSubscriber\MaintenanceModeSubscriber;
|
||||
use Drupal\Core\EventSubscriber\PathSubscriber;
|
||||
use Drupal\Core\EventSubscriber\RequestCloseSubscriber;
|
||||
use Drupal\Core\EventSubscriber\RouterListener;
|
||||
use Drupal\Core\EventSubscriber\ViewSubscriber;
|
||||
use Drupal\Core\ExceptionController;
|
||||
use Drupal\Core\LegacyUrlMatcher;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder as BaseContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
|
||||
use Symfony\Component\DependencyInjection\Compiler\Compiler;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
|
||||
/**
|
||||
* Drupal's dependency injection container.
|
||||
*/
|
||||
class ContainerBuilder extends BaseContainerBuilder {
|
||||
|
||||
/**
|
||||
* Registers the base Drupal services for the dependency injection container.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
|
||||
{
|
||||
if (!isset($this->compiler) || null === $this->compiler) {
|
||||
$this->compiler = new Compiler();
|
||||
}
|
||||
|
||||
// An interface language always needs to be available for t() and other
|
||||
// functions. This default is overridden by drupal_language_initialize()
|
||||
// during language negotiation.
|
||||
$this->register(LANGUAGE_TYPE_INTERFACE, 'Drupal\\Core\\Language\\Language');
|
||||
$this->compiler->addPass($pass, $type);
|
||||
}
|
||||
|
||||
// Register the default language content.
|
||||
$this->register(LANGUAGE_TYPE_CONTENT, 'Drupal\\Core\\Language\\Language');
|
||||
public function compile()
|
||||
{
|
||||
if (null === $this->compiler) {
|
||||
$this->compiler = new Compiler();
|
||||
}
|
||||
|
||||
// Register configuration storage dispatcher.
|
||||
$this->setParameter('config.storage.info', array(
|
||||
'Drupal\Core\Config\DatabaseStorage' => array(
|
||||
'connection' => 'default',
|
||||
'target' => 'default',
|
||||
'read' => TRUE,
|
||||
'write' => TRUE,
|
||||
),
|
||||
'Drupal\Core\Config\FileStorage' => array(
|
||||
'directory' => config_get_config_directory(),
|
||||
'read' => TRUE,
|
||||
'write' => FALSE,
|
||||
),
|
||||
));
|
||||
$this->register('config.storage.dispatcher', 'Drupal\Core\Config\StorageDispatcher')
|
||||
->addArgument('%config.storage.info%');
|
||||
$this->compiler->compile($this);
|
||||
$this->parameterBag->resolve();
|
||||
// TODO: The line below is commented out because there is code that calls
|
||||
// the set() method on the container after it has been built - that method
|
||||
// throws an exception if the container's parameters have been frozen.
|
||||
//$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
|
||||
}
|
||||
|
||||
// Register configuration object factory.
|
||||
$this->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
|
||||
->addArgument(new Reference('config.storage.dispatcher'));
|
||||
|
||||
// Register the HTTP kernel services.
|
||||
$this->register('dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher')
|
||||
->addArgument(new Reference('service_container'))
|
||||
->setFactoryClass('Drupal\Core\DependencyInjection\ContainerBuilder')
|
||||
->setFactoryMethod('getKernelEventDispatcher');
|
||||
$this->register('resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver');
|
||||
$this->register('httpkernel', 'Symfony\Component\HttpKernel\HttpKernel')
|
||||
->addArgument(new Reference('dispatcher'))
|
||||
->addArgument(new Reference('resolver'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an EventDispatcher for the HttpKernel. Factory method.
|
||||
*
|
||||
* @param Drupal\Core\DependencyInjection\ContainerBuilder $container
|
||||
* The dependency injection container that contains the HTTP kernel.
|
||||
*
|
||||
* @return Symfony\Component\EventDispatcher\EventDispatcher
|
||||
* An EventDispatcher with the default listeners attached to it.
|
||||
*/
|
||||
public static function getKernelEventDispatcher($container) {
|
||||
$dispatcher = new EventDispatcher();
|
||||
|
||||
$matcher = new LegacyUrlMatcher();
|
||||
$dispatcher->addSubscriber(new RouterListener($matcher));
|
||||
|
||||
$negotiation = new ContentNegotiation();
|
||||
|
||||
// @todo Make this extensible rather than just hard coding some.
|
||||
// @todo Add a subscriber to handle other things, too, like our Ajax
|
||||
// replacement system.
|
||||
$dispatcher->addSubscriber(new ViewSubscriber($negotiation));
|
||||
$dispatcher->addSubscriber(new AccessSubscriber());
|
||||
$dispatcher->addSubscriber(new MaintenanceModeSubscriber());
|
||||
$dispatcher->addSubscriber(new PathSubscriber());
|
||||
$dispatcher->addSubscriber(new LegacyRequestSubscriber());
|
||||
$dispatcher->addSubscriber(new LegacyControllerSubscriber());
|
||||
$dispatcher->addSubscriber(new FinishResponseSubscriber());
|
||||
$dispatcher->addSubscriber(new RequestCloseSubscriber());
|
||||
|
||||
// Some other form of error occured that wasn't handled by another kernel
|
||||
// listener. That could mean that it's a method/mime-type/error combination
|
||||
// that is not accounted for, or some other type of error. Either way, treat
|
||||
// it as a server-level error and return an HTTP 500. By default, this will
|
||||
// be an HTML-type response because that's a decent best guess if we don't
|
||||
// know otherwise.
|
||||
$exceptionController = new ExceptionController($negotiation);
|
||||
$exceptionController->setContainer($container);
|
||||
$dispatcher->addSubscriber(new ExceptionListener(array($exceptionController, 'execute')));
|
||||
|
||||
return $dispatcher;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core;
|
||||
|
||||
use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
|
||||
class DrupalBundle extends Bundle
|
||||
{
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
parent::build($container);
|
||||
// An interface language always needs to be available for t() and other
|
||||
// functions. This default is overridden by drupal_language_initialize()
|
||||
// during language negotiation.
|
||||
$container->register(LANGUAGE_TYPE_INTERFACE, 'Drupal\\Core\\Language\\Language');
|
||||
|
||||
// Register the default language content.
|
||||
$container->register(LANGUAGE_TYPE_CONTENT, 'Drupal\\Core\\Language\\Language');
|
||||
|
||||
$definitions = array(
|
||||
'dispatcher' => array(
|
||||
'class' => 'Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher',
|
||||
'references' => array(
|
||||
'service_container',
|
||||
),
|
||||
),
|
||||
'resolver' => array(
|
||||
'class' => 'Symfony\Component\HttpKernel\Controller\ControllerResolver',
|
||||
),
|
||||
'http_kernel' => array(
|
||||
'class' => 'Symfony\Component\HttpKernel\HttpKernel',
|
||||
'references' => array(
|
||||
'dispatcher', 'resolver',
|
||||
)
|
||||
),
|
||||
'matcher' => array(
|
||||
'class' => 'Drupal\Core\LegacyUrlMatcher',
|
||||
),
|
||||
'router_listener' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\RouterListener',
|
||||
'references' => array('matcher'),
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'content_negotiation' => array(
|
||||
'class' => 'Drupal\Core\ContentNegotiation',
|
||||
),
|
||||
'view_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\ViewSubscriber',
|
||||
'references' => array('content_negotiation'),
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'access_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\AccessSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'maintenance_mode_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\MaintenanceModeSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'path_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\PathSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'legacy_request_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'legacy_controller_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\LegacyControllerSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'finish_response_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\FinishResponseSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'request_close_subscriber' => array(
|
||||
'class' => 'Drupal\Core\EventSubscriber\RequestCloseSubscriber',
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
'exception_controller' => array(
|
||||
'class' => 'Drupal\Core\ExceptionController',
|
||||
'references' => array('content_negotiation'),
|
||||
'methods' => array('setContainer' => array('service_container'))
|
||||
),
|
||||
'exception_listener' => array(
|
||||
'class' => 'Symfony\Component\HttpKernel\EventListener\ExceptionListener',
|
||||
'references' => array('exception_controller'),
|
||||
'tags' => array('kernel.event_subscriber')
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($definitions as $id => $info) {
|
||||
$info += array(
|
||||
'tags' => array(),
|
||||
'references' => array(),
|
||||
'methods' => array(),
|
||||
);
|
||||
|
||||
$references = array();
|
||||
foreach ($info['references'] as $ref_id) {
|
||||
$references[] = new Reference($ref_id);
|
||||
}
|
||||
|
||||
$definition = new Definition($info['class'], $references);
|
||||
|
||||
foreach($info['tags'] as $tag) {
|
||||
$definition->addTag($tag);
|
||||
}
|
||||
|
||||
foreach ($info['methods'] as $method => $args) {
|
||||
$definition->addMethodCall($method, $args);
|
||||
}
|
||||
|
||||
$container->setDefinition($id, $definition);
|
||||
}
|
||||
|
||||
$container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\Core\DrupalKernel.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core;
|
||||
|
||||
use Drupal\Core\DrupalBundle;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
|
||||
/**
|
||||
* The DrupalKernel class is the core of Drupal itself.
|
||||
*/
|
||||
class DrupalKernel extends Kernel {
|
||||
|
||||
public function registerBundles()
|
||||
{
|
||||
$bundles = array(
|
||||
new DrupalBundle(),
|
||||
);
|
||||
$modules = array_keys(system_list('module_enabled'));
|
||||
foreach ($modules as $module) {
|
||||
$class = "\Drupal\{$module}\{$module}Bundle";
|
||||
if (class_exists($class)) {
|
||||
$bundles[] = new $class();
|
||||
}
|
||||
}
|
||||
return $bundles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the service container.
|
||||
*/
|
||||
protected function initializeContainer()
|
||||
{
|
||||
$this->container = $this->buildContainer();
|
||||
$this->container->set('kernel', $this);
|
||||
drupal_container($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the service container.
|
||||
*
|
||||
* @return ContainerBuilder The compiled service container
|
||||
*/
|
||||
protected function buildContainer()
|
||||
{
|
||||
$container = $this->getContainerBuilder();
|
||||
foreach ($this->bundles as $bundle) {
|
||||
$bundle->build($container);
|
||||
}
|
||||
$container->compile();
|
||||
return $container;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a new ContainerBuilder instance used to build the service container.
|
||||
*
|
||||
* @return ContainerBuilder
|
||||
*/
|
||||
protected function getContainerBuilder()
|
||||
{
|
||||
return new ContainerBuilder(new ParameterBag($this->getKernelParameters()));
|
||||
}
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||
{
|
||||
// We have to define this method because it's not defined in the base class,
|
||||
// but the LoaderInterface class is part of the config component, which we
|
||||
// are not using, so this is badness :-/ The alternative is to not extend
|
||||
// the base Kernel class and just implement the KernelInterface.
|
||||
}
|
||||
}
|
|
@ -107,7 +107,7 @@ class ExceptionController extends ContainerAware {
|
|||
drupal_static_reset('menu_set_active_trail');
|
||||
menu_reset_static_cache();
|
||||
|
||||
$response = $this->container->get('httpkernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
|
||||
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
|
||||
$response->setStatusCode(403, 'Access denied');
|
||||
}
|
||||
else {
|
||||
|
@ -172,7 +172,7 @@ class ExceptionController extends ContainerAware {
|
|||
drupal_static_reset('menu_set_active_trail');
|
||||
menu_reset_static_cache();
|
||||
|
||||
$response = $this->container->get('httpkernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
|
||||
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
|
||||
$response->setStatusCode(404, 'Not Found');
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* See COPYRIGHT.txt and LICENSE.txt files in the "core" directory.
|
||||
*/
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
|
@ -20,6 +21,7 @@ define('DRUPAL_ROOT', getcwd());
|
|||
// Bootstrap the lowest level of what we need.
|
||||
require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
|
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
|
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES);
|
||||
|
||||
// Create a request object from the HTTPFoundation.
|
||||
$request = Request::createFromGlobals();
|
||||
|
@ -29,6 +31,9 @@ $request = Request::createFromGlobals();
|
|||
// container at some point.
|
||||
request($request);
|
||||
|
||||
$kernel = new DrupalKernel('prod', FALSE);
|
||||
$kernel->boot();
|
||||
|
||||
// Bootstrap all of Drupal's subsystems, but do not initialize anything that
|
||||
// depends on the fully resolved Drupal path, because path resolution happens
|
||||
// during the REQUEST event of the kernel.
|
||||
|
@ -36,6 +41,6 @@ request($request);
|
|||
// @see Drupal\Core\EventSubscriber\LegacyRequestSubscriber;
|
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
|
||||
|
||||
$kernel = drupal_container()->get('httpkernel');
|
||||
$response = $kernel->handle($request)->prepare($request)->send();
|
||||
|
||||
$kernel->terminate($request, $response);
|
||||
|
|
Loading…
Reference in New Issue