Commit ecf2fa72 authored by catch's avatar catch

Revert "Issue #2241633 by sun: Simplify site-specific service overrides."

This reverts commit c5c075df.
parent 78594ab6
......@@ -28,13 +28,7 @@ public function process(ContainerBuilder $container) {
if (!($kernel instanceof DrupalKernelInterface)) {
return;
}
$providers = $kernel->getServiceProviders('app');
foreach ($providers as $provider) {
if ($provider instanceof ServiceModifierInterface) {
$provider->alter($container);
}
}
$providers = $kernel->getServiceProviders('site');
$providers = $kernel->getServiceProviders();
foreach ($providers as $provider) {
if ($provider instanceof ServiceModifierInterface) {
$provider->alter($container);
......
......@@ -109,6 +109,13 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
*/
protected $configStorage;
/**
* The list of the classnames of the service providers in this kernel.
*
* @var array
*/
protected $serviceProviderClasses;
/**
* Whether the container can be dumped.
*
......@@ -124,33 +131,14 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
protected $containerNeedsDumping;
/**
* List of discovered services.yml pathnames.
*
* This is a nested array whose top-level keys are 'app' and 'site', denoting
* the origin of a service provider. Site-specific providers have to be
* collected separately, because they need to be processed last, so as to be
* able to override services from application service providers.
* Holds the list of YAML files containing service definitions.
*
* @var array
*/
protected $serviceYamls;
/**
* List of discovered service provider class names.
*
* This is a nested array whose top-level keys are 'app' and 'site', denoting
* the origin of a service provider. Site-specific providers have to be
* collected separately, because they need to be processed last, so as to be
* able to override services from application service providers.
*
* @var array
*/
protected $serviceProviderClasses;
/**
* List of instantiated service provider classes.
*
* @see \Drupal\Core\DrupalKernel::$serviceProviderClasses
* The array of registered service providers.
*
* @var array
*/
......@@ -215,18 +203,16 @@ public function getContainer() {
* {@inheritdoc}
*/
public function discoverServiceProviders() {
$this->serviceYamls = array(
'app' => array(),
'site' => array(),
$serviceProviders = array(
'CoreServiceProvider' => new CoreServiceProvider(),
);
$this->serviceProviderClasses = array(
'app' => array(),
'site' => array(),
$this->serviceYamls = array(
'core/core.services.yml'
);
$this->serviceYamls['app']['core'] = 'core/core.services.yml';
$this->serviceProviderClasses['app']['core'] = 'Drupal\Core\CoreServiceProvider';
$this->serviceProviderClasses = array('Drupal\Core\CoreServiceProvider');
// Retrieve enabled modules and register their namespaces.
// Ensure we know what modules are enabled and that their namespaces are
// registered.
if (!isset($this->moduleList)) {
$extensions = $this->getConfigStorage()->read('core.extension');
$this->moduleList = isset($extensions['module']) ? $extensions['module'] : array();
......@@ -240,35 +226,34 @@ public function discoverServiceProviders() {
$name = "{$camelized}ServiceProvider";
$class = "Drupal\\{$module}\\{$name}";
if (class_exists($class)) {
$this->serviceProviderClasses['app'][$module] = $class;
$serviceProviders[$name] = new $class();
$this->serviceProviderClasses[] = $class;
}
$filename = dirname($module_filenames[$module]) . "/$module.services.yml";
if (file_exists($filename)) {
$this->serviceYamls['app'][$module] = $filename;
$this->serviceYamls[] = $filename;
}
}
// Add site-specific service providers.
// Add site specific or test service providers.
if (!empty($GLOBALS['conf']['container_service_providers'])) {
foreach ($GLOBALS['conf']['container_service_providers'] as $class) {
if (class_exists($class)) {
$this->serviceProviderClasses['site'][] = $class;
}
foreach ($GLOBALS['conf']['container_service_providers'] as $name => $class) {
$serviceProviders[$name] = new $class();
$this->serviceProviderClasses[] = $class;
}
}
// Add site specific or test YAMLs.
if (!empty($GLOBALS['conf']['container_yamls'])) {
$this->serviceYamls['site'] = $GLOBALS['conf']['container_yamls'];
}
if (file_exists($site_services_yml = conf_path() . '/services.yml')) {
$this->serviceYamls['site'][] = $site_services_yml;
$this->serviceYamls = array_merge($this->serviceYamls, $GLOBALS['conf']['container_yamls']);
}
return $serviceProviders;
}
/**
* {@inheritdoc}
*/
public function getServiceProviders($origin) {
return $this->serviceProviders[$origin];
public function getServiceProviders() {
return $this->serviceProviders;
}
/**
......@@ -511,6 +496,7 @@ protected function buildContainer() {
$this->initializeServiceProviders();
$container = $this->getContainerBuilder();
$container->set('kernel', $this);
$container->setParameter('container.service_providers', $this->serviceProviderClasses);
$container->setParameter('container.modules', $this->getModulesParameter());
// Get a list of namespaces and put it onto the container.
......@@ -545,22 +531,11 @@ protected function buildContainer() {
$container->register('class_loader')->setSynthetic(TRUE);
$container->register('kernel', 'Symfony\Component\HttpKernel\KernelInterface')->setSynthetic(TRUE);
$container->register('service_container', 'Symfony\Component\DependencyInjection\ContainerInterface')->setSynthetic(TRUE);
// Register application services.
$yaml_loader = new YamlFileLoader($container);
foreach ($this->serviceYamls['app'] as $filename) {
$yaml_loader->load($filename);
}
foreach ($this->serviceProviders['app'] as $provider) {
if ($provider instanceof ServiceProviderInterface) {
$provider->register($container);
}
}
// Register site-specific service overrides.
foreach ($this->serviceYamls['site'] as $filename) {
foreach ($this->serviceYamls as $filename) {
$yaml_loader->load($filename);
}
foreach ($this->serviceProviders['site'] as $provider) {
foreach ($this->serviceProviders as $provider) {
if ($provider instanceof ServiceProviderInterface) {
$provider->register($container);
}
......@@ -588,15 +563,13 @@ protected function buildContainer() {
* @throws \LogicException
*/
protected function initializeServiceProviders() {
$this->discoverServiceProviders();
$this->serviceProviders = array(
'app' => array(),
'site' => array(),
);
foreach ($this->serviceProviderClasses as $origin => $classes) {
foreach ($classes as $name => $class) {
$this->serviceProviders[$origin][$name] = new $class;
$this->serviceProviders = array();
foreach ($this->discoverServiceProviders() as $name => $provider) {
if (isset($this->serviceProviders[$name])) {
throw new \LogicException(sprintf('Trying to register two service providers with the same name "%s"', $name));
}
$this->serviceProviders[$name] = $provider;
}
}
......
......@@ -38,13 +38,10 @@ public function discoverServiceProviders();
/**
* Returns all registered service providers.
*
* @param string $origin
* The origin for which to return service providers; one of 'app' or 'site'.
*
* @return array
* An associative array of ServiceProvider objects, keyed by name.
*/
public function getServiceProviders($origin);
public function getServiceProviders();
/**
* Gets the current container.
......
<?php
/**
* @file
* Contains \Drupal\system\Tests\DrupalKernel\DrupalKernelSiteTest.
*/
namespace Drupal\system\Tests\DrupalKernel;
use Drupal\simpletest\DrupalUnitTestBase;
/**
* Tests site-specific service overrides.
*/
class DrupalKernelSiteTest extends DrupalUnitTestBase {
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'DrupalKernel site service overrides',
'description' => 'Tests site-specific service overrides.',
'group' => 'DrupalKernel',
);
}
/**
* Tests services.yml in site directory.
*/
public function testServicesYml() {
$this->assertFalse($this->container->has('site.service.yml'));
// A service provider class always has precedence over services.yml files.
// DrupalUnitTestBase::buildContainer() swaps out many services with
// in-memory implementations already, so those cannot be tested.
$this->assertIdentical(get_class($this->container->get('cache.backend.database')), 'Drupal\Core\Cache\DatabaseBackendFactory');
$class = __CLASS__;
$doc = <<<EOD
services:
# Add a new service.
site.service.yml:
class: $class
# Swap out a core service.
cache.backend.database:
class: Drupal\Core\Cache\MemoryBackendFactory
EOD;
file_put_contents($this->siteDirectory . '/services.yml', $doc);
// Rebuild the container.
$this->kernel->updateModules(array());
$this->assertTrue($this->container->has('site.service.yml'));
$this->assertIdentical(get_class($this->container->get('cache.backend.database')), 'Drupal\Core\Cache\MemoryBackendFactory');
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment