diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 8ddeb1759e66703d14f87074881711018e667dba..a3ae42d05aceb1d0e6f369b39548f485813c5c26 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -530,12 +530,8 @@ public function discoverServiceProviders() { } } } - if ($container_yamls = Settings::get('container_yamls')) { - $this->serviceYamls['site'] = $container_yamls; - } - $site_services_yml = $this->getSitePath() . '/services.yml'; - if (file_exists($site_services_yml) && is_readable($site_services_yml)) { - $this->serviceYamls['site'][] = $site_services_yml; + if (!$this->addServiceFiles(Settings::get('container_yamls'))) { + throw new \Exception('The container_yamls setting is missing from settings.php'); } } @@ -1295,4 +1291,21 @@ protected static function setupTrustedHosts(Request $request, $hostPatterns) { return TRUE; } + + /** + * Add service files. + * + * @param $service_yamls + * A list of service files. + * + * @return bool + * TRUE if the list was an array, FALSE otherwise. + */ + protected function addServiceFiles($service_yamls) { + if (is_array($service_yamls)) { + $this->serviceYamls['site'] = array_filter($service_yamls, 'file_exists'); + return TRUE; + } + return FALSE; + } } diff --git a/core/lib/Drupal/Core/Installer/InstallerKernel.php b/core/lib/Drupal/Core/Installer/InstallerKernel.php index 4063611b44bbe19421a3db29f36327118a338e9d..41e8cbe9cdc2d88a6fecd3ac03672206c9df4e2f 100644 --- a/core/lib/Drupal/Core/Installer/InstallerKernel.php +++ b/core/lib/Drupal/Core/Installer/InstallerKernel.php @@ -40,4 +40,11 @@ public function resetConfigStorage() { $this->configStorage = NULL; } + /** + * {@inheritdoc} + */ + protected function addServiceFiles($service_yamls) { + // In the beginning there is no settings.php and no service YAMLs. + return parent::addServiceFiles($service_yamls ?: []); + } } diff --git a/core/lib/Drupal/Core/Test/TestRunnerKernel.php b/core/lib/Drupal/Core/Test/TestRunnerKernel.php index a6dc573c0795ffe632971e25b88c29f955c9be7d..fa9fd51f20e9800224e9e7fd5d57cf753dcaac2a 100644 --- a/core/lib/Drupal/Core/Test/TestRunnerKernel.php +++ b/core/lib/Drupal/Core/Test/TestRunnerKernel.php @@ -55,6 +55,7 @@ public function boot() { if (!Settings::getAll()) { new Settings(array( 'hash_salt' => 'run-tests', + 'container_yamls' => [], // If there is no settings.php, then there is no parent site. In turn, // there is no public files directory; use a custom public files path. 'file_public_path' => 'sites/default/files', diff --git a/core/modules/simpletest/src/KernelTestBase.php b/core/modules/simpletest/src/KernelTestBase.php index e5d076aca4db729c10ab705abf5806fc605be5aa..d2c53412faf8e81a3315ce111034722765cce80d 100644 --- a/core/modules/simpletest/src/KernelTestBase.php +++ b/core/modules/simpletest/src/KernelTestBase.php @@ -135,11 +135,16 @@ protected function prepareConfigDirectories() { protected function setUp() { $this->keyValueFactory = new KeyValueMemoryFactory(); + // Back up settings from TestBase::prepareEnvironment(). + $settings = Settings::getAll(); + // Allow for test-specific overrides. $settings_services_file = DRUPAL_ROOT . '/' . $this->originalSite . '/testing.services.yml'; if (file_exists($settings_services_file)) { // Copy the testing-specific service overrides in place. - copy($settings_services_file, DRUPAL_ROOT . '/' . $this->siteDirectory . '/services.yml'); + $testing_services_file = DRUPAL_ROOT . '/' . $this->siteDirectory . '/services.yml'; + copy($settings_services_file, $testing_services_file); + $this->settingsSet('container_yamls', [$testing_services_file]); } // Create and set new configuration directories. @@ -149,8 +154,6 @@ protected function setUp() { // @todo Remove the indirection; implement ServiceProviderInterface instead. $GLOBALS['conf']['container_service_providers']['TestServiceProvider'] = 'Drupal\simpletest\TestServiceProvider'; - // Back up settings from TestBase::prepareEnvironment(). - $settings = Settings::getAll(); // Bootstrap a new kernel. Don't use createFromRequest so we don't mess with settings. $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php'; $this->kernel = new DrupalKernel('testing', $class_loader, FALSE); diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php index 92598452a8208a9bef3604b4cdf05753481536a1..b4901af4314e3b742570032459b69a40750d1618 100644 --- a/core/modules/simpletest/src/TestBase.php +++ b/core/modules/simpletest/src/TestBase.php @@ -1210,6 +1210,7 @@ private function prepareEnvironment() { new Settings(array( // For performance, simply use the database prefix as hash salt. 'hash_salt' => $this->databasePrefix, + 'container_yamls' => [], )); drupal_set_time_limit($this->timeLimit); diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php index 59ee3f34dc0d6fc1e50cf5a42204a3f9b045628d..cc2138d84a7949293eaff42378a6cab0d7270143 100644 --- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php +++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelSiteTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\DrupalKernel; +use Drupal\Core\Site\Settings; use Drupal\simpletest\KernelTestBase; /** @@ -20,6 +21,9 @@ class DrupalKernelSiteTest extends KernelTestBase { * Tests services.yml in site directory. */ public function testServicesYml() { + $container_yamls = Settings::get('container_yamls'); + $container_yamls[] = $this->siteDirectory . '/services.yml'; + $this->settingsSet('container_yamls', $container_yamls); $this->assertFalse($this->container->has('site.service.yml')); // A service provider class always has precedence over services.yml files. // KernelTestBase::buildContainer() swaps out many services with in-memory diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php index 44ae20fd96f56a7ce144bce05e9650e657fadfe2..af8ce27481af16cf67b8109ad820673c6e911d8a 100644 --- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php +++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php @@ -54,6 +54,7 @@ protected function getTestKernel(Request $request, array $modules_enabled = NULL // Manually create kernel to avoid replacing settings. $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php'; $kernel = DrupalKernel::createFromRequest($request, $class_loader, 'testing'); + $this->settingsSet('container_yamls', []); $this->settingsSet('hash_salt', $this->databasePrefix); if (isset($modules_enabled)) { $kernel->updateModules($modules_enabled); @@ -169,6 +170,7 @@ public function testRepeatedBootWithDifferentEnvironment() { foreach ($environments as $environment) { $kernel = DrupalKernel::createFromRequest($request, $class_loader, $environment); + $this->settingsSet('container_yamls', []); $this->settingsSet('hash_salt', $this->databasePrefix); $kernel->boot(); } diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/DiscoverServiceProvidersTest.php b/core/tests/Drupal/Tests/Core/DrupalKernel/DiscoverServiceProvidersTest.php new file mode 100644 index 0000000000000000000000000000000000000000..31e0b9d409989e8572b3f70821dec73d13f43b34 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/DrupalKernel/DiscoverServiceProvidersTest.php @@ -0,0 +1,59 @@ +<?php + +/** + * @file + * Contains \Drupal\Tests\Core\DrupalKernel\DiscoverServiceProvidersTest. + */ + +namespace Drupal\Tests\Core\DrupalKernel; + +use Drupal\Core\DrupalKernel; +use Drupal\Core\Site\Settings; +use Drupal\Tests\UnitTestCase; + +/** + * @coversDefaultClass \Drupal\Core\DrupalKernel + * @group DrupalKernel + */ +class DiscoverServiceProvidersTest extends UnitTestCase { + + /** + * Tests discovery with user defined container yaml. + * + * @covers ::discoverServiceProviders() + */ + public function testDiscoverServiceCustom() { + new Settings(array( + 'container_yamls' => array( + __DIR__ . '/fixtures/custom.yml' + ), + )); + + $kernel = new DrupalKernel('prod', new \Composer\Autoload\ClassLoader()); + $kernel->discoverServiceProviders(); + + $expect = array( + 'app' => array( + 'core' => 'core/core.services.yml', + ), + 'site' => array( + __DIR__ . '/fixtures/custom.yml', + ), + ); + + $this->assertAttributeSame($expect, 'serviceYamls', $kernel); + } + + /** + * Tests the exception when container_yamls is not set. + * + * @covers ::discoverServiceProviders() + * @expectedException \Exception + */ + public function testDiscoverServiceNoContainerYamls() { + new Settings([]); + $kernel = new DrupalKernel('prod', new \Composer\Autoload\ClassLoader()); + $kernel->discoverServiceProviders(); + } + +} diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/fixtures/custom.yml b/core/tests/Drupal/Tests/Core/DrupalKernel/fixtures/custom.yml new file mode 100644 index 0000000000000000000000000000000000000000..3950896fb4107bde43f65f9efb7095fefcc5ada5 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/DrupalKernel/fixtures/custom.yml @@ -0,0 +1,3 @@ +parameters: + test.config: + test: true diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 7cc10be7260ccade7699c9d7831d6328f6b770d4..8a3dfa494dda815ef0588bd4414fb27be1e338ba 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -594,6 +594,11 @@ # $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; # $config['system.performance']['fast_404']['html'] = '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>'; +/** + * Load services definition file. + */ +$settings['container_yamls'][] = __DIR__ . '/services.yml'; + /** * Load local development override configuration, if available. *