diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 214ce28..b683347 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -2010,6 +2010,28 @@ function install_check_requirements($install_state) {
);
}
}
+
+ // Check that the services.yml file is read and writable.
+ $yml_file = $conf_path . '/services.yml';
+ $readable = drupal_verify_install_file($yml_file, FILE_READABLE);
+ $writable = drupal_verify_install_file($yml_file, FILE_WRITABLE);
+
+ if (!$readable) {
+ $requirements['services file readable'] = array(
+ 'title' => t('Services file'),
+ 'value' => t('The services.yml file is not readable.'),
+ 'severity' => REQUIREMENT_ERROR,
+ 'description' => t('@drupal requires read permissions to %file at all times. If you are unsure how to grant file permissions, consult the online handbook.', array('@drupal' => drupal_install_profile_distribution_name(), '%file' => $yml_file, '@handbook_url' => 'http://drupal.org/server-permissions')),
+ );
+ }
+ if (!$writable) {
+ $requirements['service file writable'] = array(
+ 'title' => t('Services file'),
+ 'value' => t('The service.yml file is not writable.'),
+ 'severity' => REQUIREMENT_ERROR,
+ 'description' => t('The @drupal installer requires write permissions to %file during the installation process. If you are unsure how to grant file permissions, consult the online handbook.', array('@drupal' => drupal_install_profile_distribution_name(), '%file' => $yml_file, '@handbook_url' => 'http://drupal.org/server-permissions')),
+ );
+ }
}
return $requirements;
}
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index a7f5ef4..42c7dea 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -9,6 +9,7 @@
use Drupal\Core\Cache\CacheContextsPass;
use Drupal\Core\Cache\ListCacheBinsPass;
+use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
@@ -49,6 +50,8 @@ public function register(ContainerBuilder $container) {
// list-building passes are operating on the post-alter services list.
$container->addCompilerPass(new ModifyServiceDefinitionsPass());
+ $container->addCompilerPass(new BackendCompilerPass());
+
// Collect tagged handler services as method calls on consumer services.
$container->addCompilerPass(new TaggedHandlersPass());
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/BackendCompilerPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/BackendCompilerPass.php
new file mode 100644
index 0000000..e4aedcb
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/BackendCompilerPass.php
@@ -0,0 +1,63 @@
+hasParameter('default_backend') ? $container->getParameter('default_backend') : NULL;
+ // No default backend was configured, so continue as normal.
+ if (!isset($default_backend)) {
+ return;
+ }
+
+ foreach ($container->findTaggedServiceIds('backend_overridable') as $id => $attributes) {
+ // If the service is already an alias it is not the original backend, so
+ // we don't want to fallback to other storages any longer.
+ if ($container->hasAlias($id)) {
+ continue;
+ }
+ if ($container->hasDefinition("$default_backend.$id") || $container->hasAlias("$default_backend.$id")) {
+ $container->setAlias($id, new Alias("$default_backend.$id"));
+ }
+ }
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
index 23f0d03..c233392 100644
--- a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
@@ -7,6 +7,7 @@
namespace Drupal\Core\Installer\Form;
+use Drupal\Component\Serialization\Yaml;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Database\Database;
use Drupal\Core\Form\FormBase;
@@ -156,6 +157,12 @@ public function submitForm(array &$form, array &$form_state) {
drupal_rewrite_settings($settings);
+ $conf_path = './' . conf_path(FALSE);
+ $services_file = $conf_path . '/services.yml';
+ // @TODO Should we put some logic in here to ensure that the file is read
+ // and writable?
+ file_put_contents($services_file, Yaml::encode(array('parameters' => array('default_backend' => $database['driver']))));
+
// Add the config directories to settings.php.
drupal_install_config_directories();
diff --git a/core/modules/system/src/Tests/Installer/InstallerTest.php b/core/modules/system/src/Tests/Installer/InstallerTest.php
index 760a942..ab5b358 100644
--- a/core/modules/system/src/Tests/Installer/InstallerTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerTest.php
@@ -30,6 +30,9 @@ public function testInstaller() {
$this->assertRaw(t('Congratulations, you installed @drupal!', array(
'@drupal' => drupal_install_profile_distribution_name(),
)));
+
+ // Ensures that the services YML file got written and read.
+ $this->assertEqual(\Drupal::getContainer()->getParameter('default_backend'), \Drupal::database()->driver());
}
}
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/BackendCompilerPassTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/BackendCompilerPassTest.php
new file mode 100644
index 0000000..6f726c1
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/BackendCompilerPassTest.php
@@ -0,0 +1,93 @@
+backendPass = new BackendCompilerPass();
+ }
+
+ /**
+ * Tests the process method.
+ *
+ * @param string $expected_class
+ * The expected used class.
+ * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
+ * The container.
+ *
+ * @dataProvider providerTestProcess
+ *
+ * @covers ::process
+ */
+ public function testProcess($expected_class, ContainerBuilder $container) {
+ $this->backendPass->process($container);
+
+ $this->assertInstanceOf($expected_class, $container->get('service'));
+ }
+
+ /**
+ * Provides test data for testProcess().
+ *
+ * @return array
+ */
+ public function providerTestProcess() {
+ $data = array();
+ // Add a container with no set default_backend.
+ $container = new ContainerBuilder();
+ $prefix = '\\' . __NAMESPACE__ . '\\';
+ $container->setDefinition('service', (new Definition($prefix . 'ServiceClassDefault'))->addTag('backend_overridable'));
+ $container->setDefinition('mysql.service', new Definition($prefix . 'ServiceClassMysql'));
+
+ $data[] = array($prefix . 'ServiceClassDefault', $container);
+
+ // Set the default_backend so the mysql service should be used.
+ $container = clone $container;
+ $container->setParameter('default_backend', 'mysql');
+ $data[] = array($prefix . 'ServiceClassMysql', $container);
+
+ // Configure a manual alias for the service, so ensure that it is not
+ // overridden by the default backend.
+ $container = clone $container;
+ $container->setDefinition('mariadb.service', new Definition($prefix . 'ServiceClassMariaDb'));
+ $container->setAlias('service', new Alias('mariadb.service'));
+ $data[] = array($prefix . 'ServiceClassMariaDb', $container);
+
+ return $data;
+ }
+
+}
+
+class ServiceClassDefault {
+}
+
+class ServiceClassMysql extends ServiceClassDefault {
+}
+
+class ServiceClassMariaDb extends ServiceClassMysql {
+}