CoreServiceProvider.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace Drupal\Core;
  3. use Drupal\Core\Cache\Context\CacheContextsPass;
  4. use Drupal\Core\Cache\ListCacheBinsPass;
  5. use Drupal\Core\DependencyInjection\Compiler\AuthenticationProviderPass;
  6. use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass;
  7. use Drupal\Core\DependencyInjection\Compiler\CorsCompilerPass;
  8. use Drupal\Core\DependencyInjection\Compiler\GuzzleMiddlewarePass;
  9. use Drupal\Core\DependencyInjection\Compiler\ContextProvidersPass;
  10. use Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass;
  11. use Drupal\Core\DependencyInjection\Compiler\DependencySerializationTraitPass;
  12. use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass;
  13. use Drupal\Core\DependencyInjection\Compiler\StackedSessionHandlerPass;
  14. use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass;
  15. use Drupal\Core\DependencyInjection\Compiler\TwigExtensionPass;
  16. use Drupal\Core\DependencyInjection\ServiceModifierInterface;
  17. use Drupal\Core\DependencyInjection\ServiceProviderInterface;
  18. use Drupal\Core\DependencyInjection\ContainerBuilder;
  19. use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
  20. use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass;
  21. use Drupal\Core\DependencyInjection\Compiler\RegisterEventSubscribersPass;
  22. use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
  23. use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass;
  24. use Drupal\Core\EventSubscriber\PathSubscriber;
  25. use Drupal\Core\Path\AliasManager;
  26. use Drupal\Core\Path\AliasRepository;
  27. use Drupal\Core\Path\AliasWhitelist;
  28. use Drupal\Core\PathProcessor\PathProcessorAlias;
  29. use Drupal\Core\Plugin\PluginManagerPass;
  30. use Drupal\Core\Render\MainContent\MainContentRenderersPass;
  31. use Drupal\Core\Site\Settings;
  32. use Symfony\Component\DependencyInjection\Compiler\PassConfig;
  33. use Symfony\Component\DependencyInjection\Reference;
  34. /**
  35. * ServiceProvider class for mandatory core services.
  36. *
  37. * This is where Drupal core registers all of its compiler passes.
  38. * The service definitions themselves are in core/core.services.yml with a
  39. * few, documented exceptions (typically, install requirements).
  40. *
  41. * Modules wishing to register services to the container should use
  42. * modulename.services.yml in their respective directories.
  43. *
  44. * @ingroup container
  45. */
  46. class CoreServiceProvider implements ServiceProviderInterface, ServiceModifierInterface {
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function register(ContainerBuilder $container) {
  51. $this->registerTest($container);
  52. // Only register the private file stream wrapper if a file path has been set.
  53. if (Settings::get('file_private_path')) {
  54. $container->register('stream_wrapper.private', 'Drupal\Core\StreamWrapper\PrivateStream')
  55. ->addTag('stream_wrapper', ['scheme' => 'private']);
  56. }
  57. // Add the compiler pass that lets service providers modify existing
  58. // service definitions. This pass must come first so that later
  59. // list-building passes are operating on the post-alter services list.
  60. $container->addCompilerPass(new ModifyServiceDefinitionsPass());
  61. $container->addCompilerPass(new ProxyServicesPass());
  62. $container->addCompilerPass(new BackendCompilerPass());
  63. $container->addCompilerPass(new CorsCompilerPass());
  64. $container->addCompilerPass(new StackedKernelPass());
  65. $container->addCompilerPass(new StackedSessionHandlerPass());
  66. $container->addCompilerPass(new MainContentRenderersPass());
  67. // Collect tagged handler services as method calls on consumer services.
  68. $container->addCompilerPass(new TaggedHandlersPass());
  69. $container->addCompilerPass(new RegisterStreamWrappersPass());
  70. $container->addCompilerPass(new GuzzleMiddlewarePass());
  71. $container->addCompilerPass(new TwigExtensionPass());
  72. // Add a compiler pass for registering event subscribers.
  73. $container->addCompilerPass(new RegisterEventSubscribersPass(), PassConfig::TYPE_AFTER_REMOVING);
  74. $container->addCompilerPass(new RegisterAccessChecksPass());
  75. // Add a compiler pass for registering services needing destruction.
  76. $container->addCompilerPass(new RegisterServicesForDestructionPass());
  77. // Add the compiler pass that will process the tagged services.
  78. $container->addCompilerPass(new ListCacheBinsPass());
  79. $container->addCompilerPass(new CacheContextsPass());
  80. $container->addCompilerPass(new ContextProvidersPass());
  81. $container->addCompilerPass(new AuthenticationProviderPass());
  82. // Register plugin managers.
  83. $container->addCompilerPass(new PluginManagerPass());
  84. $container->addCompilerPass(new DependencySerializationTraitPass());
  85. }
  86. /**
  87. * Alters the UUID service to use the most efficient method available.
  88. *
  89. * @param \Drupal\Core\DependencyInjection\ContainerBuilder $container
  90. * The container builder.
  91. */
  92. public function alter(ContainerBuilder $container) {
  93. $uuid_service = $container->getDefinition('uuid');
  94. // Debian/Ubuntu uses the (broken) OSSP extension as their UUID
  95. // implementation. The OSSP implementation is not compatible with the
  96. // PECL functions.
  97. if (function_exists('uuid_create') && !function_exists('uuid_make')) {
  98. $uuid_service->setClass('Drupal\Component\Uuid\Pecl');
  99. }
  100. // Try to use the COM implementation for Windows users.
  101. elseif (function_exists('com_create_guid')) {
  102. $uuid_service->setClass('Drupal\Component\Uuid\Com');
  103. }
  104. // Look for missing services that are now defined by the path_alias module,
  105. // add them as a fallback until the module is installed.
  106. // @todo Remove this in Drupal 9 in https://www.drupal.org/node/3092090.
  107. $services = [
  108. 'path_alias.subscriber' => PathSubscriber::class,
  109. 'path_alias.path_processor' => PathProcessorAlias::class,
  110. 'path_alias.manager' => AliasManager::class,
  111. 'path_alias.whitelist' => AliasWhitelist::class,
  112. 'path_alias.repository' => AliasRepository::class,
  113. ];
  114. foreach ($services as $id => $class) {
  115. if (!$container->hasDefinition($id)) {
  116. $definition = $container->register($id, $class);
  117. // Mark the fallback services as deprecated in order to allow other
  118. // modules to provide additional checks before relying or altering them.
  119. $definition->setDeprecated(TRUE, 'The "%service_id%" service is in fallback mode. See https://drupal.org/node/3092086');
  120. switch ($id) {
  121. case 'path_alias.subscriber':
  122. $definition->addArgument(new Reference('path.alias_manager'));
  123. $definition->addArgument(new Reference('path.current'));
  124. break;
  125. case 'path_alias.path_processor':
  126. $definition->addArgument(new Reference('path.alias_manager'));
  127. break;
  128. case 'path_alias.repository':
  129. $definition->addArgument(new Reference('database'));
  130. break;
  131. case 'path_alias.whitelist':
  132. $definition->addArgument('path_alias_whitelist');
  133. $definition->addArgument(new Reference('cache.bootstrap'));
  134. $definition->addArgument(new Reference('lock'));
  135. $definition->addArgument(new Reference('state'));
  136. $definition->addArgument(new Reference('path_alias.repository'));
  137. break;
  138. case 'path_alias.manager':
  139. $definition->addArgument(new Reference('path_alias.repository'));
  140. $definition->addArgument(new Reference('path_alias.whitelist'));
  141. $definition->addArgument(new Reference('language_manager'));
  142. $definition->addArgument(new Reference('cache.data'));
  143. break;
  144. }
  145. }
  146. }
  147. }
  148. /**
  149. * Registers services and event subscribers for a site under test.
  150. *
  151. * @param \Drupal\Core\DependencyInjection\ContainerBuilder $container
  152. * The container builder.
  153. */
  154. protected function registerTest(ContainerBuilder $container) {
  155. // Do nothing if we are not in a test environment.
  156. if (!drupal_valid_test_ua()) {
  157. return;
  158. }
  159. // Add the HTTP request middleware to Guzzle.
  160. $container
  161. ->register('test.http_client.middleware', 'Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware')
  162. ->addTag('http_client_middleware');
  163. }
  164. }