Commit 1f31a38f authored by Dries's avatar Dries
Browse files

Merge remote-tracking branch 'sandbox/bundles' into 8.x

parents f77cdf16 790b2e4a
......@@ -4,7 +4,9 @@
use Drupal\Core\Database\Database;
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Language\Language;
......@@ -1455,7 +1457,7 @@ function t($string, array $args = array(), array $options = array()) {
// Merge in default.
if (empty($options['langcode'])) {
$options['langcode'] = drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode;
$options['langcode'] = language_manager(LANGUAGE_TYPE_INTERFACE)->langcode;
}
if (empty($options['context'])) {
$options['context'] = '';
......@@ -1609,29 +1611,6 @@ function request_uri($omit_query_string = FALSE) {
return $omit_query_string ? strtok($uri, '?') : $uri;
}
/**
* Returns the current global request object.
*
* @todo Replace this function with a proper dependency injection container.
*
* @staticvar Symfony\Component\HttpFoundation\Request $request
*
* @param Symfony\Component\HttpFoundation\Request $new_request
* Optional. The new request object to store. This parameter should only be
* used by index.php.
*
* @return Symfony\Component\HttpFoundation\Request
* The current request object.
*/
function request(Request $new_request = NULL) {
static $request;
if ($new_request) {
$request = $new_request;
}
return $request;
}
/**
* Logs an exception.
*
......@@ -2428,28 +2407,23 @@ function drupal_get_bootstrap_phase() {
/**
* Retrieves the Drupal Container to standardize object construction.
*
* Example:
* @code
* // Register the LANGUAGE_TYPE_INTERFACE definition. Registered definitions
* // do not necessarily need to be named by a constant.
* // See
* // http://symfony.com/doc/current/components/dependency_injection/introduction.html
* // for usage examples of adding object initialization code after register().
* $container = drupal_container();
* $container->register(LANGUAGE_TYPE_INTERFACE, 'Drupal\\Core\\Language\\Language');
*
* // Retrieve the LANGUAGE_TYPE_INTERFACE object.
* $language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
* @endcode
* On a normal page request the container is built by the kernel and passed in
* to this function which stores it statically. Any full bootstrap outside of
* the context of a page request will require a container with a minimal set of
* services. If this function is called without the $reset parameter, and no
* container object has been statically cached, it builds this minimal container,
* registering the services that are required.
*
* @see Drupal\Core\DrupalKernel
*
* @param $reset
* A new container instance to reset the Drupal container to.
*
* @return Drupal\Component\DependencyInjection\ContainerBuilder
* The instance of the Drupal Container used to set up and maintain object
* @return Symfony\Component\DependencyInjection\Container
* The instance of the Container used to set up and maintain object
* instances.
*/
function drupal_container(ContainerBuilder $reset = NULL) {
function drupal_container(Container $reset = NULL) {
// We do not use drupal_static() here because we do not have a mechanism by
// which to reinitialize the stored objects, so a drupal_static_reset() call
// would leave Drupal in a nonfunctional state.
......@@ -2458,7 +2432,31 @@ function drupal_container(ContainerBuilder $reset = NULL) {
$container = $reset;
}
elseif (!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.
$container = new ContainerBuilder();
// Register configuration storage dispatcher.
$container->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,
),
));
$container->register('config.storage.dispatcher', 'Drupal\Core\Config\StorageDispatcher')
->addArgument('%config.storage.info%');
// Register configuration object factory.
$container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
->addArgument(new Reference('config.storage.dispatcher'));
}
return $container;
}
......@@ -2606,34 +2604,71 @@ function get_t() {
/**
* Initializes all the defined language types.
*
* @see Drupal\Core\Language\Language
* @see language_manager()
*/
function drupal_language_initialize() {
$types = language_types_get_all();
$container = drupal_container();
// Ensure a language object is registered for each language type, whether the
// site is multilingual or not.
if (language_multilingual()) {
include_once DRUPAL_ROOT . '/core/includes/language.inc';
$types = language_types_get_all();
foreach ($types as $type) {
$language = language_types_initialize($type);
$container->set($type, NULL);
$container->register($type, 'Drupal\\Core\\Language\\Language')
->addMethodCall('extend', array($language));
language_manager($type);
}
// Allow modules to react on language system initialization in multilingual
// environments.
bootstrap_invoke_all('language_init');
}
else {
$default = language_default();
foreach ($types as $type) {
$container->set($type, NULL);
$container->register($type, 'Drupal\\Core\\Language\\Language')
->addMethodCall('extend', array($default));
}
/**
* Initializes the passed in language type.
*
* The 'language_manager' service is only available within the scope of a kernel
* request. When it's not available, we return a default language object,
* regardless of the type passed in.
*
* Note that this function is provided for legacy code that needs to get e.g.
* the interface language outside the scope of a request. Code that runs within
* the scope of a request should call
* drupal_container()->get('language_manager')->getLanguage($type)
* directly.
*
* @see Drupal\Core\Language\LanguageManager
*
* @param $type
* The type of language object needed, e.g. LANGUAGE_TYPE_INTERFACE. Passing
* NULL invokes a reset of the statically stored language type objects.
*/
function language_manager($type = NULL) {
// Keep track of whether we are in a multilingual environment.
static $multilingual = FALSE;
// Keep track of whether the language_manager service is available.
static $language_manager_service = FALSE;
if ($multilingual && $language_manager_service) {
if (!$type) {
drupal_container()->get('language_manager')->reset();
return;
}
return drupal_container()->get('language_manager')->getLanguage($type);
}
if (language_multilingual()) {
$multilingual = TRUE;
if (drupal_container()->has('language_manager')) {
$language_manager_service = TRUE;
return drupal_container()->get('language_manager')->getLanguage($type);
}
}
// We can't use drupal_static() here because resetting is not a simple case of
// drupal_static_reset().
static $languages;
// If no type was passed in, reset the languages array.
if (!$type) {
$languages = array();
}
// If this is not a multilingual environment or we have not yet entered the
// request scope, just use the default language regardless of $type.
if (!isset($languages[$type])) {
$languages[$type] = language_default();
}
return $languages[$type];
}
/**
......
......@@ -1599,7 +1599,7 @@ function filter_xss_bad_protocol($string, $decode = TRUE) {
* Arbitrary elements may be added using the $args associative array.
*/
function format_rss_channel($title, $link, $description, $items, $langcode = NULL, $args = array()) {
$langcode = $langcode ? $langcode : drupal_container()->get(LANGUAGE_TYPE_CONTENT)->langcode;
$langcode = $langcode ? $langcode : language_manager(LANGUAGE_TYPE_CONTENT)->langcode;
$output = "<channel>\n";
$output .= ' <title>' . check_plain($title) . "</title>\n";
......@@ -1901,7 +1901,7 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
}
if (empty($langcode)) {
$langcode = drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode;
$langcode = language_manager(LANGUAGE_TYPE_INTERFACE)->langcode;
}
switch ($type) {
......@@ -2077,7 +2077,7 @@ function _format_date_callback(array $matches = NULL, $new_langcode = NULL) {
* - 'language': An optional language object. If the path being linked to is
* internal to the site, $options['language'] is used to look up the alias
* for the URL. If $options['language'] is omitted, the language will be
* obtained from drupal_container()->get(LANGUAGE_TYPE_URL).
* obtained from language_manager(LANGUAGE_TYPE_URL).
* - 'https': Whether this URL should point to a secure location. If not
* defined, the current scheme is used, so the user stays on http or https
* respectively. TRUE enforces HTTPS and FALSE enforces HTTP, but HTTPS can
......@@ -2322,7 +2322,7 @@ function l($text, $path, array $options = array()) {
// Append active class.
if (($path == current_path() || ($path == '<front>' && drupal_is_front_page())) &&
(empty($options['language']) || $options['language']->langcode == drupal_container()->get(LANGUAGE_TYPE_URL)->langcode)) {
(empty($options['language']) || $options['language']->langcode == language_manager(LANGUAGE_TYPE_URL)->langcode)) {
$options['attributes']['class'][] = 'active';
}
......@@ -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;
......@@ -6017,7 +6017,7 @@ function drupal_render_cid_parts($granularity = NULL) {
// part.
if (language_multilingual()) {
foreach (language_types_get_configurable() as $language_type) {
$cid_parts[] = drupal_container()->get($language_type)->langcode;
$cid_parts[] = language_manager($language_type)->langcode;
}
}
......
......@@ -1267,7 +1267,7 @@ function drupal_redirect_form($form_state) {
$function($form_state['redirect']);
}
}
drupal_goto(current_path(), array('query' => request()->query->all()));
drupal_goto(current_path(), array('query' => drupal_container()->get('request')->query->all()));
}
}
......
<?php
use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Install\TaskException;
......@@ -254,11 +255,6 @@ function install_begin_request(&$install_state) {
// A request object from the HTTPFoundation to tell us about the request.
$request = Request::createFromGlobals();
// Set the global $request object. This is a temporary measure to
// keep legacy utility functions working. It should be moved to a dependency
// injection container at some point.
request($request);
// This must go after drupal_bootstrap(), which unsets globals!
global $conf;
......@@ -1416,6 +1412,12 @@ function install_bootstrap_full(&$install_state) {
// Clear the module list that was overriden earlier in the process.
// This will allow all freshly installed modules to be loaded.
module_list_reset();
// @todo The constructor parameters for the Kernel class are for environment,
// e.g. 'prod', 'dev', and a boolean indicating whether it is in debug mode.
// Drupal does not currently make use of either of these, though that may
// change with http://drupal.org/node/1537198.
$kernel = new DrupalKernel('prod', FALSE);
$kernel->boot();
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
}
......
......@@ -107,10 +107,13 @@
* @param $type
* The language type key to find the language for.
*
* @param $request
* The HttpReqeust object representing the current request.
*
* @return
* The negotiated language object.
*/
function language_types_initialize($type) {
function language_types_initialize($type, $request = NULL) {
// Execute the language negotiation methods in the order they were set up and
// return the first valid language found.
$negotiation = variable_get("language_negotiation_$type", array());
......@@ -120,7 +123,7 @@ function language_types_initialize($type) {
if (isset($method['types']) && !in_array($type, $method['types'])) {
continue;
}
$language = language_negotiation_method_invoke($method_id, $method);
$language = language_negotiation_method_invoke($method_id, $method, $request);
if ($language) {
// Remember the method ID used to detect the language.
$language->method_id = $method_id;
......@@ -428,10 +431,13 @@ function language_negotiation_info() {
* invoked (see hook_language_negotiation_info() for details). If not passed
* in, it will be loaded through language_negotiation_info().
*
* @param $request
* (optional) The HttpRequest object representing the current request.
*
* @return
* A language object representing the language chosen by the method.
*/
function language_negotiation_method_invoke($method_id, $method = NULL) {
function language_negotiation_method_invoke($method_id, $method = NULL, $request = NULL) {
$results = &drupal_static(__FUNCTION__);
if (!isset($results[$method_id])) {
......@@ -447,12 +453,11 @@ function language_negotiation_method_invoke($method_id, $method = NULL) {
if (isset($method['file'])) {
require_once DRUPAL_ROOT . '/' . $method['file'];
}
// If the language negotiation method has no cache preference or this is
// satisfied we can execute the callback.
$cache = !isset($method['cache']) || $user->uid || $method['cache'] == variable_get('cache', 0);
$callback = isset($method['callbacks']['negotiation']) ? $method['callbacks']['negotiation'] : FALSE;
$langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE;
$langcode = $cache && function_exists($callback) ? $callback($languages, $request) : FALSE;
$results[$method_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
}
......
......@@ -1069,7 +1069,7 @@ function menu_tree_output($tree) {
*/
function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
$tree = &drupal_static(__FUNCTION__, array());
$language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
$language_interface = language_manager(LANGUAGE_TYPE_INTERFACE);
// Use $mlid as a flag for whether the data being loaded is for the whole tree.
$mlid = isset($link['mlid']) ? $link['mlid'] : 0;
......@@ -1180,7 +1180,7 @@ function menu_tree_get_path($menu_name) {
function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail = FALSE) {
$tree = &drupal_static(__FUNCTION__, array());
$language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
$language_interface = language_manager(LANGUAGE_TYPE_INTERFACE);
// Check if the active trail has been overridden for this menu tree.
$active_path = menu_tree_get_path($menu_name);
......@@ -1336,7 +1336,7 @@ function menu_build_tree($menu_name, array $parameters = array()) {
function _menu_build_tree($menu_name, array $parameters = array()) {
// Static cache of already built menu trees.
$trees = &drupal_static(__FUNCTION__, array());
$language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
$language_interface = language_manager(LANGUAGE_TYPE_INTERFACE);
// Build the cache id; sort parents to prevent duplicate storage and remove
// default parameter values.
......
......@@ -82,7 +82,7 @@ function drupal_lookup_path($action, $path = '', $langcode = NULL) {
// language. If we used a language different from the one conveyed by the
// requested URL, we might end up being unable to check if there is a path
// alias matching the URL path.
$langcode = $langcode ? $langcode : drupal_container()->get(LANGUAGE_TYPE_URL)->langcode;
$langcode = $langcode ? $langcode : language_manager(LANGUAGE_TYPE_URL)->langcode;
if ($action == 'wipe') {
$cache = array();
......@@ -213,8 +213,17 @@ function drupal_cache_system_paths() {
// request to avoid writing to cache on every request.
$cache = &drupal_static('drupal_lookup_path', array());
if (empty($cache['system_paths']) && !empty($cache['map'])) {
// @todo Because we are not within the request scope at this time, we cannot
// use current_path(), which would give us the system path to use as the
// key. Instead we call _current_path(), which may give us the alias
// instead. However, at lookup time the system path will be used as the
// key, because it uses current_path(), and so it will be a cache miss.
// There is a critical issue for fixing the path alias logic here:
// http://drupal.org/node/1269742
// Generate a cache ID (cid) specifically for this page.
$cid = current_path();
$cid = _current_path();
// The static $map array used by drupal_lookup_path() includes all
// system paths for the page request.
if ($paths = current($cache['map'])) {
......@@ -358,6 +367,14 @@ function drupal_match_path($path, $patterns) {
* @see request_path()
*/
function current_path() {
// @todo Remove the check for whether the request service exists and the
// fallback code below, once the path alias logic has been figured out in
// http://drupal.org/node/1269742.
if (drupal_container()->has('request')) {
return drupal_container()->get('request')->attributes->get('system_path');
}
// If we are outside the request scope, fall back to using the path stored in
// _current_path().
return _current_path();
}
......
......@@ -1624,7 +1624,7 @@ function theme_link($variables) {
* http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
*/
function theme_links($variables) {
$language_url = drupal_container()->get(LANGUAGE_TYPE_URL);
$language_url = language_manager(LANGUAGE_TYPE_URL);
$links = $variables['links'];
$attributes = $variables['attributes'];
......@@ -2395,7 +2395,7 @@ function _template_preprocess_default_variables() {
* @see html.tpl.php
*/
function template_preprocess_html(&$variables) {
$language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
$language_interface = language_manager(LANGUAGE_TYPE_INTERFACE);
// Compile a list of classes that are going to be applied to the body element.
// This allows advanced theming based on context (home page, node of certain type, etc.).
......@@ -2527,7 +2527,7 @@ function template_preprocess_html(&$variables) {
* @see page.tpl.php
*/
function template_preprocess_page(&$variables) {
$language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
$language_interface = language_manager(LANGUAGE_TYPE_INTERFACE);
$site_config = config('system.site');
// Move some variables to the top level for themer convenience and template cleanliness.
......@@ -2708,7 +2708,7 @@ function theme_get_suggestions($args, $base, $delimiter = '__') {
*/
function template_preprocess_maintenance_page(&$variables) {
global $theme;
$language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE);
$language_interface = language_manager(LANGUAGE_TYPE_INTERFACE);
// Retrieve the theme data to list all available regions.
$theme_data = list_themes();
$regions = $theme_data[$theme]->info['regions'];
......
......@@ -247,8 +247,10 @@ function update_prepare_d8_language() {
// Update the 'language_default' system variable, if configured.
$language_default = variable_get('language_default');
if (!empty($language_default) && isset($language_default->language)) {
$language_default->langcode = $language_default->language;
if (!empty($language_default) && (isset($language_default->langcode) || isset($language_default->language))) {
if (!isset($language_default->langcode)) {
$language_default->langcode = $language_default->language;
}
unset($language_default->language);
// In D8, the 'language_default' is not anymore an object, but an array,
// so make sure that the new value that is saved into this variable is an
......
<?php
/**
* @file
* Definition of Drupal\Core\CoreBundle.
*/
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\DependencyInjection\Scope;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
/**
* Bundle class for mandatory core services.
*
* This is where Drupal core registers all of its services to the Dependency
* Injection Container. Modules wishing to register services to the container
* should extend Symfony's Bundle class directly, not this class.
*/
class CoreBundle extends Bundle
{
public function build(ContainerBuilder $container) {
// 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).
$container->addScope(new Scope('request'));
$container->register('request', 'Symfony\Component\HttpFoundation\Request')
->setSynthetic(TRUE);
$container->register('dispatcher', 'Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher')
->addArgument(new Reference('service_container'));
$container->register('resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver');
$container->register('http_kernel', 'Drupal\Core\HttpKernel')
->addArgument(new Reference('dispatcher'))
->addArgument(new Reference('service_container'))
->addArgument(new Reference('resolver'));
$container->register('language_manager', 'Drupal\Core\Language\LanguageManager')
->addArgument(new Reference('request'))
->setScope('request');
// @todo Replace below lines with the commented out block below it when it's
// performant to do so: http://drupal.org/node/1706064.
$dispatcher = $container->get('dispatcher');
$matcher = new \Drupal\Core\LegacyUrlMatcher();
$content_negotation = new \Drupal\Core\ContentNegotiation();
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RouterListener($matcher));
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\ViewSubscriber($content_negotation));
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\AccessSubscriber());
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\MaintenanceModeSubscriber());
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\PathSubscriber());
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\LegacyRequestSubscriber());
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\LegacyControllerSubscriber());
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\FinishResponseSubscriber());
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RequestCloseSubscriber());
$container->set('content_negotiation', $content_negotation);
$dispatcher->addSubscriber(\Drupal\Core\ExceptionController::getExceptionListener($container));
/*
$container->register('matcher', 'Drupal\Core\LegacyUrlMatcher');
$container->register('router_listener', 'Drupal\Core\EventSubscriber\RouterListener')
->addArgument(new Reference('matcher'))
->addTag('kernel.event_subscriber');
$container->register('content_negotiation', 'Drupal\Core\ContentNegotiation');
$container->register('view_subscriber', 'Drupal\Core\EventSubscriber\ViewSubscriber')
->addArgument(new Reference('content_negotiation'))
->addTag('kernel.event_subscriber');
$container->register('access_subscriber', 'Drupal\Core\EventSubscriber\AccessSubscriber')
->addTag('kernel.event_subscriber');
$container->register('maintenance_mode_subscriber', 'Drupal\Core\EventSubscriber\MaintenanceModeSubscriber')
->addTag('kernel.event_subscriber');
$container->register('path_subscriber', 'Drupal\Core\EventSubscriber\PathSubscriber')
->addTag('kernel.event_subscriber');
$container->register('legacy_request_subscriber', 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber')
->addTag('kernel.event_subscriber');
$container->register('legacy_controller_subscriber', 'Drupal\Core\EventSubscriber\LegacyControllerSubscriber')
->addTag('kernel.event_subscriber');
$container->register('finish_response_subscriber', 'Drupal\Core\EventSubscriber\FinishResponseSubscriber')
->addArgument(new Reference('language_manager'))
->setScope('request')
->addTag('kernel.event_subscriber');
$container->register('request_close_subscriber', 'Drupal\Core\EventSubscriber\RequestCloseSubscriber')
->addTag('kernel.event_subscriber');
$container->register('database', 'Drupal\Core\Database\Connection')
->setFactoryClass('Drupal\Core\Database\Database')
->setFactoryMethod('getConnection')
->addArgument('default');
$container->register('database.slave', 'Drupal\Core\Database\Connection')
->setFactoryClass('Drupal\Core\Database\Database')
->setFactoryMethod('getConnection')
->addArgument('slave');
$container->register('exception_listener', 'Symfony\Component\HttpKernel\EventListener\ExceptionListener')
->addTag('kernel.event_subscriber')
->addArgument(new Reference('service_container'))
->setFactoryClass('Drupal\Core\ExceptionController')
->setFactoryMethod('getExceptionListener');
// Add a compiler pass for registering event subscribers.
$container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
*/
}
}
<?php
/**
* @file
* Definition of Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass.
*/
namespace Drupal\Core\DependencyInjection\Compiler;
use InvalidArgumentException;
use ReflectionClass;
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';