CoreBundle.php 19.1 KB
Newer Older
1 2
<?php

Crell's avatar
Crell committed
3 4 5 6 7
/**
 * @file
 * Definition of Drupal\Core\CoreBundle.
 */

8 9 10
namespace Drupal\Core;

use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
11
use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
12
use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
13
use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
14
use Drupal\Core\DependencyInjection\Compiler\RegisterRouteEnhancersPass;
15
use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
16
use Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\ContainerInterface;
19
use Symfony\Component\DependencyInjection\Reference;
20
use Symfony\Component\DependencyInjection\Definition;
21
use Symfony\Component\DependencyInjection\Scope;
22 23 24
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;

25
/**
Crell's avatar
Crell committed
26 27
 * Bundle class for mandatory core services.
 *
28 29 30 31
 * 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.
 */
32
class CoreBundle extends Bundle {
33

34 35 36
  /**
   * Implements \Symfony\Component\HttpKernel\Bundle\BundleInterface::build().
   */
37
  public function build(ContainerBuilder $container) {
38

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    // Register active configuration storage.
    $container
      ->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'));

    $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
      ->addArgument(new Reference('config.storage'))
57
      ->addArgument(new Reference('event_dispatcher'))
58
      ->addTag('persist');
59 60 61 62 63 64

    // Register staging configuration storage.
    $container
      ->register('config.storage.staging', 'Drupal\Core\Config\FileStorage')
      ->addArgument(config_get_config_directory(CONFIG_STAGING_DIRECTORY));

65 66 67 68
    // Register the typed configuration data manager.
    $container->register('config.typed', 'Drupal\Core\Config\TypedConfigManager')
      ->addArgument(new Reference('config.storage'));

69 70 71 72 73 74 75 76 77 78 79 80 81
    // 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'));

82 83 84 85
    $container->register('settings', 'Drupal\Component\Utility\Settings')
      ->setFactoryClass('Drupal\Component\Utility\Settings')
      ->setFactoryMethod('getSingleton');

86 87 88 89 90 91
    // Register the State k/v store as a service.
    $container->register('state', 'Drupal\Core\KeyValueStore\KeyValueStoreInterface')
      ->setFactoryService(new Reference('keyvalue'))
      ->setFactoryMethod('get')
      ->addArgument('state');

92 93 94 95 96 97 98 99 100
    // Register the Queue factory.
    $container
      ->register('queue', 'Drupal\Core\Queue\QueueFactory')
      ->addArgument(new Reference('settings'))
      ->addMethodCall('setContainer', array(new Reference('service_container')));
    $container
      ->register('queue.database', 'Drupal\Core\Queue\QueueDatabaseFactory')
      ->addArgument(new Reference('database'));

101 102
    $container->register('path.alias_manager', 'Drupal\Core\Path\AliasManager')
      ->addArgument(new Reference('database'))
103 104
      ->addArgument(new Reference('state'))
      ->addArgument(new Reference('language_manager'));
105

106 107 108 109 110 111 112 113 114 115
    $container->register('http_client_simpletest_subscriber', 'Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber');
    $container->register('http_default_client', 'Guzzle\Http\Client')
      ->addArgument(NULL)
      ->addArgument(array(
        'curl.CURLOPT_TIMEOUT' => 30.0,
        'curl.CURLOPT_MAXREDIRS' => 3,
      ))
      ->addMethodCall('addSubscriber', array(new Reference('http_client_simpletest_subscriber')))
      ->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)'));

116 117 118
    // Register the EntityManager.
    $container->register('plugin.manager.entity', 'Drupal\Core\Entity\EntityManager');

119 120 121
    // 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).
122
    $container->addScope(new Scope('request'));
123
    $container->register('request', 'Symfony\Component\HttpFoundation\Request');
124

125
    $container->register('event_dispatcher', 'Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher')
126
      ->addArgument(new Reference('service_container'));
127
    $container->register('controller_resolver', 'Drupal\Core\ControllerResolver')
128
      ->addArgument(new Reference('service_container'));
129 130 131 132 133 134 135 136 137 138 139 140 141 142

    $container
      ->register('cache.cache', 'Drupal\Core\Cache\CacheBackendInterface')
      ->setFactoryClass('Drupal\Core\Cache\CacheFactory')
      ->setFactoryMethod('get')
      ->addArgument('cache');
    $container
      ->register('cache.bootstrap', 'Drupal\Core\Cache\CacheBackendInterface')
      ->setFactoryClass('Drupal\Core\Cache\CacheFactory')
      ->setFactoryMethod('get')
      ->addArgument('bootstrap');

    $this->registerModuleHandler($container);

143
    $container->register('http_kernel', 'Drupal\Core\HttpKernel')
144
      ->addArgument(new Reference('event_dispatcher'))
145
      ->addArgument(new Reference('service_container'))
146
      ->addArgument(new Reference('controller_resolver'));
147 148 149 150

    // Register the 'language_manager' service.
    $container->register('language_manager', 'Drupal\Core\Language\LanguageManager');

151 152 153 154
    $container->register('database.slave', 'Drupal\Core\Database\Connection')
      ->setFactoryClass('Drupal\Core\Database\Database')
      ->setFactoryMethod('getConnection')
      ->addArgument('slave');
155 156 157 158
    $container->register('typed_data', 'Drupal\Core\TypedData\TypedDataManager')
      ->addMethodCall('setValidationConstraintManager', array(new Reference('validation.constraint')));
    $container->register('validation.constraint', 'Drupal\Core\Validation\ConstraintManager');

159 160 161 162 163
    // Add the user's storage for temporary, non-cache data.
    $container->register('lock', 'Drupal\Core\Lock\DatabaseLockBackend');
    $container->register('user.tempstore', 'Drupal\user\TempStoreFactory')
      ->addArgument(new Reference('database'))
      ->addArgument(new Reference('lock'));
164 165

    $this->registerTwig($container);
166
    $this->registerRouting($container);
167

168
    // Add the entity query factories.
169
    $container->register('entity.query', 'Drupal\Core\Entity\Query\QueryFactory')
170 171 172 173
      ->addArgument(new Reference('plugin.manager.entity'))
      ->addMethodCall('setContainer', array(new Reference('service_container')));
    $container->register('entity.query.config', 'Drupal\Core\Config\Entity\Query\QueryFactory')
      ->addArgument(new Reference('config.storage'));
174

175
    $container->register('router.dumper', 'Drupal\Core\Routing\MatcherDumper')
176
      ->addArgument(new Reference('database'));
177
    $container->register('router.builder', 'Drupal\Core\Routing\RouteBuilder')
178
      ->addArgument(new Reference('router.dumper'))
179
      ->addArgument(new Reference('lock'))
180 181
      ->addArgument(new Reference('event_dispatcher'))
      ->addArgument(new Reference('module_handler'));
182

183 184 185 186 187 188 189 190 191 192 193 194 195 196
    $container
      ->register('cache.path', 'Drupal\Core\Cache\CacheBackendInterface')
      ->setFactoryClass('Drupal\Core\Cache\CacheFactory')
      ->setFactoryMethod('get')
      ->addArgument('path');

    $container->register('path.alias_manager.cached', 'Drupal\Core\CacheDecorator\AliasManagerCacheDecorator')
      ->addArgument(new Reference('path.alias_manager'))
      ->addArgument(new Reference('cache.path'));

    $container->register('path.crud', 'Drupal\Core\Path\Path')
      ->addArgument(new Reference('database'))
      ->addArgument(new Reference('path.alias_manager'));

197 198 199 200 201 202 203 204 205
    // Add password hashing service. The argument to PhpassHashedPassword
    // constructor is the log2 number of iterations for password stretching.
    // This should increase by 1 every Drupal version in order to counteract
    // increases in the speed and power of computers available to crack the
    // hashes. The current password hashing method was introduced in Drupal 7
    // with a log2 count of 15.
    $container->register('password', 'Drupal\Core\Password\PhpassHashedPassword')
      ->addArgument(16);

206 207
    // The following services are tagged as 'route_filter' services and are
    // processed in the RegisterRouteFiltersPass compiler pass.
208
    $container->register('mime_type_matcher', 'Drupal\Core\Routing\MimeTypeMatcher')
209
      ->addTag('route_filter');
210

211 212 213 214 215 216
    $container->register('paramconverter_manager', 'Drupal\Core\ParamConverter\ParamConverterManager')
      ->addTag('route_enhancer');
    $container->register('paramconverter.entity', 'Drupal\Core\ParamConverter\EntityConverter')
      ->addArgument(new Reference('plugin.manager.entity'))
      ->addTag('paramconverter');

217
    $container->register('router_processor_subscriber', 'Drupal\Core\EventSubscriber\RouteProcessorSubscriber')
218
      ->addArgument(new Reference('content_negotiation'))
219
      ->addTag('event_subscriber');
220
    $container->register('router_listener', 'Symfony\Component\HttpKernel\EventListener\RouterListener')
221
      ->addArgument(new Reference('router'))
222
      ->addTag('event_subscriber');
223 224 225
    $container->register('content_negotiation', 'Drupal\Core\ContentNegotiation');
    $container->register('view_subscriber', 'Drupal\Core\EventSubscriber\ViewSubscriber')
      ->addArgument(new Reference('content_negotiation'))
226
      ->addTag('event_subscriber');
227 228 229 230 231
    $container->register('legacy_access_subscriber', 'Drupal\Core\EventSubscriber\LegacyAccessSubscriber')
      ->addTag('event_subscriber');
    $container->register('access_manager', 'Drupal\Core\Access\AccessManager')
      ->addArgument(new Reference('request'))
      ->addMethodCall('setContainer', array(new Reference('service_container')));
232
    $container->register('access_subscriber', 'Drupal\Core\EventSubscriber\AccessSubscriber')
233
      ->addArgument(new Reference('access_manager'))
234
      ->addTag('event_subscriber');
235 236 237 238
    $container->register('access_check.default', 'Drupal\Core\Access\DefaultAccessCheck')
      ->addTag('access_check');
    $container->register('access_check.permission', 'Drupal\Core\Access\PermissionAccessCheck')
      ->addTag('access_check');
239
    $container->register('maintenance_mode_subscriber', 'Drupal\Core\EventSubscriber\MaintenanceModeSubscriber')
240
      ->addTag('event_subscriber');
241
    $container->register('path_subscriber', 'Drupal\Core\EventSubscriber\PathSubscriber')
242
      ->addArgument(new Reference('path.alias_manager.cached'))
243
      ->addTag('event_subscriber');
244
    $container->register('legacy_request_subscriber', 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber')
245
      ->addTag('event_subscriber');
246
    $container->register('legacy_controller_subscriber', 'Drupal\Core\EventSubscriber\LegacyControllerSubscriber')
247
      ->addTag('event_subscriber');
248
    $container->register('finish_response_subscriber', 'Drupal\Core\EventSubscriber\FinishResponseSubscriber')
249 250
      ->addArgument(new Reference('language_manager'))
      ->setScope('request')
251
      ->addTag('event_subscriber');
252
    $container->register('request_close_subscriber', 'Drupal\Core\EventSubscriber\RequestCloseSubscriber')
253
      ->addArgument(new Reference('module_handler'))
254
      ->addTag('event_subscriber');
255
    $container->register('config_global_override_subscriber', 'Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber')
256
      ->addTag('event_subscriber');
257 258 259
    $container->register('language_request_subscriber', 'Drupal\Core\EventSubscriber\LanguageRequestSubscriber')
      ->addArgument(new Reference('language_manager'))
      ->addTag('event_subscriber');
260 261 262 263

    $container->register('exception_controller', 'Drupal\Core\ExceptionController')
      ->addArgument(new Reference('content_negotiation'))
      ->addMethodCall('setContainer', array(new Reference('service_container')));
264
    $container->register('exception_listener', 'Drupal\Core\EventSubscriber\ExceptionListener')
265
      ->addTag('event_subscriber')
266
      ->addArgument(array(new Reference('exception_controller'), 'execute'));
267

268 269
    $container
      ->register('transliteration', 'Drupal\Core\Transliteration\PHPTransliteration');
270

271 272 273 274 275
    // Add Serializer with arguments to be replaced in the compiler pass.
    $container->register('serializer', 'Symfony\Component\Serializer\Serializer')
      ->addArgument(array())
      ->addArgument(array());

276 277 278
    $container->register('serializer.normalizer.complex_data', 'Drupal\Core\Serialization\ComplexDataNormalizer')->addTag('normalizer');
    $container->register('serializer.normalizer.list', 'Drupal\Core\Serialization\ListNormalizer')->addTag('normalizer');
    $container->register('serializer.normalizer.typed_data', 'Drupal\Core\Serialization\TypedDataNormalizer')->addTag('normalizer');
279 280 281 282 283

    $container->register('serializer.encoder.json', 'Drupal\Core\Serialization\JsonEncoder')
      ->addTag('encoder', array('format' => array('json' => 'JSON')));
    $container->register('serializer.encoder.xml', 'Drupal\Core\Serialization\XmlEncoder')
      ->addTag('encoder', array('format' => array('xml' => 'XML')));
284

285 286 287
    $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend')
      ->addArgument(new Reference('database'));

288
    $container->addCompilerPass(new RegisterMatchersPass());
289 290 291
    $container->addCompilerPass(new RegisterRouteFiltersPass());
    // Add a compiler pass for registering event subscribers.
    $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
292 293
    // Add a compiler pass for adding Normalizers and Encoders to Serializer.
    $container->addCompilerPass(new RegisterSerializationClassesPass());
294 295 296
    // Add a compiler pass for registering event subscribers.
    $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
    $container->addCompilerPass(new RegisterAccessChecksPass());
297 298 299
    // Add a compiler pass for upcasting of entity route parameters.
    $container->addCompilerPass(new RegisterParamConvertersPass());
    $container->addCompilerPass(new RegisterRouteEnhancersPass());
300
  }
301

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
  /**
   * Registers the module handler.
   */
  protected function registerModuleHandler(ContainerBuilder $container) {
    // The ModuleHandler manages enabled modules and provides the ability to
    // invoke hooks in all enabled modules.
    if ($container->getParameter('kernel.environment') == 'install') {
      // During installation we use the non-cached version.
      $container->register('module_handler', 'Drupal\Core\Extension\ModuleHandler')
        ->addArgument('%container.modules%');
    }
    else {
      $container->register('module_handler', 'Drupal\Core\Extension\CachedModuleHandler')
        ->addArgument('%container.modules%')
        ->addArgument(new Reference('state'))
        ->addArgument(new Reference('cache.bootstrap'));
    }
  }

321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
  /**
   * Registers the various services for the routing system.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
   */
  protected function registerRouting(ContainerBuilder $container) {
    $container->register('router.request_context', 'Symfony\Component\Routing\RequestContext')
      ->addMethodCall('fromRequest', array(new Reference('request')));

    $container->register('router.route_provider', 'Drupal\Core\Routing\RouteProvider')
      ->addArgument(new Reference('database'));
    $container->register('router.matcher.final_matcher', 'Drupal\Core\Routing\UrlMatcher');
    $container->register('router.matcher', 'Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher')
      ->addArgument(new Reference('router.route_provider'))
      ->addMethodCall('setFinalMatcher', array(new Reference('router.matcher.final_matcher')));
    $container->register('router.generator', 'Drupal\Core\Routing\UrlGenerator')
      ->addArgument(new Reference('router.route_provider'))
      ->addArgument(new Reference('path.alias_manager.cached'));
    $container->register('router.dynamic', 'Symfony\Cmf\Component\Routing\DynamicRouter')
      ->addArgument(new Reference('router.request_context'))
      ->addArgument(new Reference('router.matcher'))
      ->addArgument(new Reference('router.generator'));

    $container->register('legacy_generator', 'Drupal\Core\Routing\NullGenerator');
    $container->register('legacy_url_matcher', 'Drupal\Core\LegacyUrlMatcher');
    $container->register('legacy_router', 'Symfony\Cmf\Component\Routing\DynamicRouter')
            ->addArgument(new Reference('router.request_context'))
            ->addArgument(new Reference('legacy_url_matcher'))
            ->addArgument(new Reference('legacy_generator'));

    $container->register('router', 'Symfony\Cmf\Component\Routing\ChainRouter')
      ->addMethodCall('setContext', array(new Reference('router.request_context')))
      ->addMethodCall('add', array(new Reference('router.dynamic')))
      ->addMethodCall('add', array(new Reference('legacy_router')));
  }

357 358 359 360 361 362 363 364 365 366 367 368 369 370
  /**
   * Registers Twig services.
   */
  protected function registerTwig(ContainerBuilder $container) {
    $container->register('twig.loader.filesystem', 'Twig_Loader_Filesystem')
      ->addArgument(DRUPAL_ROOT);
    $container->setAlias('twig.loader', 'twig.loader.filesystem');

    $container->register('twig', 'Drupal\Core\Template\TwigEnvironment')
      ->addArgument(new Reference('twig.loader'))
      ->addArgument(array(
        // This is saved / loaded via drupal_php_storage().
        // All files can be refreshed by clearing caches.
        // @todo ensure garbage collection of expired files.
371
        'cache' => settings()->get('twig_cache', TRUE),
372 373 374 375 376 377 378
        'base_template_class' => 'Drupal\Core\Template\TwigTemplate',
        // @todo Remove in followup issue
        // @see http://drupal.org/node/1712444.
        'autoescape' => FALSE,
        // @todo Remove in followup issue
        // @see http://drupal.org/node/1806538.
        'strict_variables' => FALSE,
379 380
        'debug' => settings()->get('twig_debug', FALSE),
        'auto_reload' => settings()->get('twig_auto_reload', NULL),
381 382 383 384 385 386
      ))
      ->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension')))
      // @todo Figure out what to do about debugging functions.
      // @see http://drupal.org/node/1804998
      ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')));
  }
katbailey's avatar
katbailey committed
387
}