diff --git a/core/INSTALL.txt b/core/INSTALL.txt
index 1880473..e906f2a 100644
--- a/core/INSTALL.txt
+++ b/core/INSTALL.txt
@@ -147,26 +147,30 @@ INSTALLATION
b. Missing settings file.
- Drupal will try to automatically create a settings.php configuration file,
- which is normally in the directory sites/default (to avoid problems when
- upgrading, Drupal is not packaged with this file). If auto-creation fails,
- you will need to create this file yourself, using the file
- sites/default/default.settings.php as a template.
+ Drupal will try to automatically create a settings.php/services.yml
+ configuration file, which is normally in the directory sites/default (to
+ avoid problems when upgrading, Drupal is not packaged with this file). If
+ auto-creation fails, you will need to create this file yourself, using the
+ files sites/default/default.settings.php and
+ sites/default/default.services.yml as a template.
For example, on a Unix/Linux command line, you can make a copy of the
- default.settings.php file with the command:
+ default.settings.php and default.services.yml files with the commands:
cp sites/default/default.settings.php sites/default/settings.php
+ cp sites/default/default.services.yml sites/default/services.yml
Next, grant write privileges to the file to everyone (including the web
server) with the command:
chmod a+w sites/default/settings.php
+ chmod a+w sites/default/services.yml
Be sure to set the permissions back after the installation is finished!
Sample command:
chmod go-w sites/default/settings.php
+ chmod go-w sites/default/services.yml
c. Write permissions after install.
@@ -176,6 +180,7 @@ INSTALLATION
from a Unix/Linux command line:
chmod go-w sites/default/settings.php
+ chmod go-w sites/default/services.yml
chmod go-w sites/default
4. Verify that the site is working.
diff --git a/core/core.services.yml b/core/core.services.yml
index 6ff5dd5..8ea2e90 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1,3 +1,9 @@
+parameters:
+ twig.config: {}
+ factory.keyvalue:
+ default: keyvalue.database
+ factory.keyvalue.expirable:
+ default: keyvalue.expirable.database
services:
cache_factory:
class: Drupal\Core\Cache\CacheFactory
@@ -156,13 +162,13 @@ services:
arguments: ['@request_stack', '@url_generator']
keyvalue:
class: Drupal\Core\KeyValueStore\KeyValueFactory
- arguments: ['@service_container', '@settings']
+ arguments: ['@service_container', '%factory.keyvalue%']
keyvalue.database:
class: Drupal\Core\KeyValueStore\KeyValueDatabaseFactory
arguments: ['@serialization.phpserialize', '@database']
keyvalue.expirable:
class: Drupal\Core\KeyValueStore\KeyValueExpirableFactory
- arguments: ['@service_container', '@settings']
+ arguments: ['@service_container', '%factory.keyvalue.expirable%']
keyvalue.expirable.database:
class: Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory
arguments: ['@serialization.phpserialize', '@database']
@@ -906,6 +912,28 @@ services:
arguments: ['@module_handler']
info_parser:
class: Drupal\Core\Extension\InfoParser
+ twig:
+ class: Drupal\Core\Template\TwigEnvironment
+ arguments: ['@twig.loader', '@module_handler', '@theme_handler', '%twig.config%']
+ tags:
+ - { name: service_collector, tag: 'twig.extension', call: addExtension }
+ twig.extension:
+ class: Drupal\Core\Template\TwigExtension
+ tags:
+ - { name: twig.extension, priority: 100 }
+ calls:
+ - [setGenerators, ['@url_generator']]
+ # @todo Figure out what to do about debugging functions.
+ # @see http://drupal.org/node/1804998
+ twig.extension.debug:
+ class: Twig_Extension_Debug
+ tags:
+ - { name: twig.extension }
+ twig.loader:
+ alias: twig.loader.filesystem
+ twig.loader.filesystem:
+ class: Twig_Loader_Filesystem
+ arguments: ['%app.root%']
element_info:
class: Drupal\Core\Render\ElementInfo
arguments: ['@module_handler']
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 5dee15d..b3cfbb7 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1887,128 +1887,168 @@ function install_check_requirements($install_state) {
// Check the profile requirements.
$requirements = drupal_check_profile($profile, $install_state);
- // If Drupal is not set up already, we need to create a settings file.
- if (!$install_state['settings_verified']) {
- $readable = FALSE;
- $writable = FALSE;
- $conf_path = './' . conf_path(FALSE);
- $settings_file = $conf_path . '/settings.php';
- $default_settings_file = './sites/default/default.settings.php';
- $file = $conf_path;
- $exists = FALSE;
- // Verify that the directory exists.
- if (drupal_verify_install_file($conf_path, FILE_EXIST, 'dir')) {
- // Check if a settings.php file already exists.
- $file = $settings_file;
- if (drupal_verify_install_file($settings_file, FILE_EXIST)) {
- // If it does, make sure it is writable.
- $readable = drupal_verify_install_file($settings_file, FILE_READABLE);
- $writable = drupal_verify_install_file($settings_file, FILE_WRITABLE);
- $exists = TRUE;
- }
- }
+ $default_files = array();
+ $default_files['settings.php'] = array(
+ 'file' => 'settings.php',
+ 'file_default' => 'default.settings.php',
+ 'title_default' => t('Default settings file'),
+ 'description_default' => t('The default settings file does not exist.'),
+ 'title' => t('Settings file'),
+ );
+ $default_files['services.yml'] = array(
+ 'file' => 'services.yml',
+ 'file_default' => 'default.services.yml',
+ 'title_default' => t('Default services file'),
+ 'description_default' => t('The default services file does not exist.'),
+ 'title' => t('Services file'),
+ );
- // If default.settings.php does not exist, or is not readable, throw an
- // error.
- if (!drupal_verify_install_file($default_settings_file, FILE_EXIST|FILE_READABLE)) {
- $requirements['default settings file exists'] = array(
- 'title' => t('Default settings file'),
- 'value' => t('The default settings file does not exist.'),
- 'severity' => REQUIREMENT_ERROR,
- 'description' => t('The @drupal installer requires that the %default-file file not be modified in any way from the original download.', array('@drupal' => drupal_install_profile_distribution_name(), '%default-file' => $default_settings_file)),
- );
- }
- // Otherwise, if settings.php does not exist yet, we can try to copy
- // default.settings.php to create it.
- elseif (!$exists) {
- $copied = drupal_verify_install_file($conf_path, FILE_EXIST|FILE_WRITABLE, 'dir') && @copy($default_settings_file, $settings_file);
- if ($copied) {
- // If the new settings file has the same owner as default.settings.php,
- // this means default.settings.php is owned by the webserver user.
- // This is an inherent security weakness because it allows a malicious
- // webserver process to append arbitrary PHP code and then execute it.
- // However, it is also a common configuration on shared hosting, and
- // there is nothing Drupal can do to prevent it. In this situation,
- // having settings.php also owned by the webserver does not introduce
- // any additional security risk, so we keep the file in place.
- if (fileowner($default_settings_file) === fileowner($settings_file)) {
+ // If Drupal is not set up already, we need to create a settings file.
+ foreach ($default_files as $file => $default_file_info) {
+ if (!$install_state['settings_verified']) {
+ $readable = FALSE;
+ $writable = FALSE;
+ $conf_path = './' . conf_path(FALSE);
+ $settings_file = $conf_path . "/{$default_file_info['file']}";
+ $default_settings_file = "./sites/default/{$default_file_info['file_default']}";
+ $file = $conf_path;
+ $exists = FALSE;
+ // Verify that the directory exists.
+ if (drupal_verify_install_file($conf_path, FILE_EXIST, 'dir')) {
+ // Check if a $file file already exists.
+ $file = $settings_file;
+ if (drupal_verify_install_file($settings_file, FILE_EXIST)) {
+ // If it does, make sure it is writable.
$readable = drupal_verify_install_file($settings_file, FILE_READABLE);
$writable = drupal_verify_install_file($settings_file, FILE_WRITABLE);
$exists = TRUE;
}
- // If settings.php and default.settings.php have different owners, this
- // probably means the server is set up "securely" (with the webserver
- // running as its own user, distinct from the user who owns all the
- // Drupal PHP files), although with either a group or world writable
- // sites directory. Keeping settings.php owned by the webserver would
- // therefore introduce a security risk. It would also cause a usability
- // problem, since site owners who do not have root access to the file
- // system would be unable to edit their settings file later on. We
- // therefore must delete the file we just created and force the
- // administrator to log on to the server and create it manually.
- else {
- $deleted = @drupal_unlink($settings_file);
- // We expect deleting the file to be successful (since we just
- // created it ourselves above), but if it fails somehow, we set a
- // variable so we can display a one-time error message to the
- // administrator at the bottom of the requirements list. We also try
- // to make the file writable, to eliminate any conflicting error
- // messages in the requirements list.
- $exists = !$deleted;
- if ($exists) {
- $settings_file_ownership_error = TRUE;
+ }
+
+ // If the default $file does not exist, or is not readable, throw an
+ // error.
+ if (!drupal_verify_install_file($default_settings_file, FILE_EXIST | FILE_READABLE)) {
+ $requirements["default $file file exists"] = array(
+ 'title' => $default_file_info['title_default'],
+ 'value' => $default_file_info['description_default'],
+ 'severity' => REQUIREMENT_ERROR,
+ 'description' => t('The @drupal installer requires that the %default-file file not be modified in any way from the original download.', array(
+ '@drupal' => drupal_install_profile_distribution_name(),
+ '%default-file' => $default_settings_file
+ )),
+ );
+ }
+ // Otherwise, if $file does not exist yet, we can try to copy
+ // default.$file to create it.
+ elseif (!$exists) {
+ $copied = drupal_verify_install_file($conf_path, FILE_EXIST | FILE_WRITABLE, 'dir') && @copy($default_settings_file, $settings_file);
+ if ($copied) {
+ // If the new $file file has the same owner as default.$file
+ // this means default.$file is owned by the webserver user.
+ // This is an inherent security weakness because it allows a malicious
+ // webserver process to append arbitrary PHP code and then execute it.
+ // However, it is also a common configuration on shared hosting, and
+ // there is nothing Drupal can do to prevent it. In this situation,
+ // having $file also owned by the webserver does not introduce
+ // any additional security risk, so we keep the file in place.
+ if (fileowner($default_settings_file) === fileowner($settings_file)) {
$readable = drupal_verify_install_file($settings_file, FILE_READABLE);
$writable = drupal_verify_install_file($settings_file, FILE_WRITABLE);
+ $exists = TRUE;
+ }
+ // If $file and default.$file have different owners, this
+ // probably means the server is set up "securely" (with the webserver
+ // running as its own user, distinct from the user who owns all the
+ // Drupal PHP files), although with either a group or world writable
+ // sites directory. Keeping $file owned by the webserver would
+ // therefore introduce a security risk. It would also cause a usability
+ // problem, since site owners who do not have root access to the file
+ // system would be unable to edit their settings file later on. We
+ // therefore must delete the file we just created and force the
+ // administrator to log on to the server and create it manually.
+ else {
+ $deleted = @drupal_unlink($settings_file);
+ // We expect deleting the file to be successful (since we just
+ // created it ourselves above), but if it fails somehow, we set a
+ // variable so we can display a one-time error message to the
+ // administrator at the bottom of the requirements list. We also try
+ // to make the file writable, to eliminate any conflicting error
+ // messages in the requirements list.
+ $exists = !$deleted;
+ if ($exists) {
+ $settings_file_ownership_error = TRUE;
+ $readable = drupal_verify_install_file($settings_file, FILE_READABLE);
+ $writable = drupal_verify_install_file($settings_file, FILE_WRITABLE);
+ }
}
}
}
- }
- // If settings.php does not exist, throw an error.
- if (!$exists) {
- $requirements['settings file exists'] = array(
- 'title' => t('Settings file'),
- 'value' => t('The settings file does not exist.'),
- 'severity' => REQUIREMENT_ERROR,
- 'description' => t('The @drupal installer requires that you create a settings file as part of the installation process. Copy the %default_file file to %file. More details about installing Drupal are available in INSTALL.txt.', array('@drupal' => drupal_install_profile_distribution_name(), '%file' => $file, '%default_file' => $default_settings_file, '@install_txt' => base_path() . 'core/INSTALL.txt')),
- );
- }
- else {
- $requirements['settings file exists'] = array(
- 'title' => t('Settings file'),
- 'value' => t('The %file file exists.', array('%file' => $file)),
- );
- // If settings.php is not readable, throw an error.
- if (!$readable) {
- $requirements['settings file readable'] = array(
- 'title' => t('Settings file'),
- 'value' => t('The settings 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' => $file, '@handbook_url' => 'http://drupal.org/server-permissions')),
- );
- }
- // If settings.php is not writable, throw an error.
- if (!$writable) {
- $requirements['settings file writable'] = array(
- 'title' => t('Settings file'),
- 'value' => t('The settings 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' => $file, '@handbook_url' => 'http://drupal.org/server-permissions')),
+ // If settings.php does not exist, throw an error.
+ if (!$exists) {
+ $requirements["$file file exists"] = array(
+ 'title' => $default_file_info['title'],
+ 'value' => t('The %file does not exist.', array('%file' => $default_file_info['title'])),
+ 'severity' => REQUIREMENT_ERROR,
+ 'description' => t('The @drupal installer requires that you create a %file as part of the installation process. Copy the %default_file file to %file. More details about installing Drupal are available in INSTALL.txt.', array(
+ '@drupal' => drupal_install_profile_distribution_name(),
+ '%file' => $file,
+ '%default_file' => $default_settings_file,
+ '@install_txt' => base_path() . 'core/INSTALL.txt'
+ )),
);
}
else {
- $requirements['settings file'] = array(
- 'title' => t('Settings file'),
- 'value' => t('The settings file is writable.'),
- );
- }
- if (!empty($settings_file_ownership_error)) {
- $requirements['settings file ownership'] = array(
- 'title' => t('Settings file'),
- 'value' => t('The settings file is owned by the web server.'),
- 'severity' => REQUIREMENT_ERROR,
- 'description' => t('The @drupal installer failed to create a settings file with proper file ownership. Log on to your web server, remove the existing %file file, and create a new one by copying the %default_file file to %file. More details about installing Drupal are available in INSTALL.txt. If you have problems with the file permissions on your server, consult the online handbook.', array('@drupal' => drupal_install_profile_distribution_name(), '%file' => $file, '%default_file' => $default_settings_file, '@install_txt' => base_path() . 'core/INSTALL.txt', '@handbook_url' => 'http://drupal.org/server-permissions')),
+ $requirements["$file file exists"] = array(
+ 'title' => $default_file_info['title'],
+ 'value' => t('The %file exists.', array('%file' => $file)),
);
+ // If settings.php is not readable, throw an error.
+ if (!$readable) {
+ $requirements["$file file readable"] = array(
+ 'title' => $default_file_info['title'],
+ 'value' => t('The %file is not readable.', array('%file' => $default_file_info['title'])),
+ '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' => $file,
+ '@handbook_url' => 'http://drupal.org/server-permissions'
+ )),
+ );
+ }
+ // If settings.php is not writable, throw an error.
+ if (!$writable) {
+ $requirements["$file file writeable"] = array(
+ 'title' => $default_file_info['title'],
+ 'value' => t('The %file is not writable.', array('%file' => $default_file_info['title'])),
+ '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' => $file,
+ '@handbook_url' => 'http://drupal.org/server-permissions'
+ )),
+ );
+ }
+ else {
+ $requirements["$file file"] = array(
+ 'title' => $default_file_info['title'],
+ 'value' => t('The @file is writable.', array('@file' => $default_file_info['title'])),
+ );
+ }
+ if (!empty($settings_file_ownership_error)) {
+ $requirements["$file file ownership"] = array(
+ 'title' => $default_file_info['title'],
+ 'value' => t('The @file is owned by the web server.', array('@file' => $default_file_info['title'])),
+ 'severity' => REQUIREMENT_ERROR,
+ 'description' => t('The @drupal installer failed to create a %file file with proper file ownership. Log on to your web server, remove the existing %file file, and create a new one by copying the %default_file file to %file. More details about installing Drupal are available in INSTALL.txt. If you have problems with the file permissions on your server, consult the online handbook.', array(
+ '@drupal' => drupal_install_profile_distribution_name(),
+ '%file' => $file,
+ '%default_file' => $default_settings_file,
+ '@install_txt' => base_path() . 'core/INSTALL.txt',
+ '@handbook_url' => 'http://drupal.org/server-permissions'
+ )),
+ );
+ }
}
}
}
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 11b9e3e..7912ef3 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -43,7 +43,8 @@ class CoreServiceProvider implements ServiceProviderInterface {
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
- $this->registerTwig($container);
+ $container->setParameter('app.root', DRUPAL_ROOT);
+
$this->registerUuid($container);
$this->registerTest($container);
@@ -77,44 +78,6 @@ public function register(ContainerBuilder $container) {
}
/**
- * Registers Twig services.
- *
- * This method is public and static so that it can be reused in the installer.
- */
- public static function registerTwig(ContainerBuilder $container) {
- $container->register('twig.loader.filesystem', 'Twig_Loader_Filesystem')
- ->addArgument(DRUPAL_ROOT);
- $container->setAlias('twig.loader', 'twig.loader.filesystem');
-
- $twig_extension = new Definition('Drupal\Core\Template\TwigExtension');
- $twig_extension->addMethodCall('setGenerators', array(new Reference('url_generator')));
-
- $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.
- // When in the installer, twig_cache must be FALSE until we know the
- // files folder is writable.
- 'cache' => drupal_installation_attempted() ? FALSE : Settings::get('twig_cache', TRUE),
- 'autoescape' => TRUE,
- 'debug' => Settings::get('twig_debug', FALSE),
- 'auto_reload' => Settings::get('twig_auto_reload', NULL),
- ))
- ->addArgument(new Reference('module_handler'))
- ->addArgument(new Reference('theme_handler'))
- ->addMethodCall('addExtension', array($twig_extension))
- // @todo Figure out what to do about debugging functions.
- // @see http://drupal.org/node/1804998
- ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')))
- ->addTag('service_collector', array(
- 'tag' => 'twig.extension',
- 'call' => 'addExtension',
- ));
- }
-
- /**
* Determines and registers the UUID service.
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
index 75282d2..d4ae53e 100644
--- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
+++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
@@ -53,6 +53,14 @@ public function __construct(ContainerBuilder $container)
}
/**
+ * Resets the internal cache. This method is mostly useful for tests.
+ */
+ public static function reset()
+ {
+ static::$yaml = array();
+ }
+
+ /**
* Loads a Yaml file.
*
* @param mixed $file The resource
diff --git a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
index 6c393b1..d64bcbb 100644
--- a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
+++ b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
@@ -60,6 +60,11 @@ public function register(ContainerBuilder $container) {
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
+ // Disable Twig cache (php storage does not exist yet).
+ $twig_config = $container->getParameter('twig.config');
+ $twig_config['cache'] = FALSE;
+ $container->setParameter('twig.config', $twig_config);
+
// Disable configuration overrides.
// ConfigFactory would to try to load language overrides and InstallStorage
// throws an exception upon trying to load a non-existing file.
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php
index 717ee04..5ed35cd 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueFactory.php
@@ -29,7 +29,7 @@ class KeyValueFactory implements KeyValueFactoryInterface {
* This is a setting name that will be used if the specific setting does not
* exist. The setting value will be the id of a service.
*/
- const DEFAULT_SETTING = 'keyvalue_default';
+ const DEFAULT_SETTING = 'default';
/**
* The default service id.
@@ -51,21 +51,23 @@ class KeyValueFactory implements KeyValueFactoryInterface {
protected $container;
/**
- * The read-only settings container.
+ * Collection-specific storage override options.
*
- * @var \Drupal\Core\Site\Settings
+ * Keys are collection names, values are service IDs.
+ *
+ * @var array
*/
protected $settings;
/**
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The service container.
- * @param \Drupal\Core\Site\Settings $settings
- * The read-only settings container.
+ * @param array $options
+ * (optional) Collection-specific storage override options.
*/
- function __construct(ContainerInterface $container, Settings $settings) {
+ function __construct(ContainerInterface $container, array $options = array()) {
$this->container = $container;
- $this->settings = $settings;
+ $this->options = $options;
}
/**
@@ -73,14 +75,16 @@ function __construct(ContainerInterface $container, Settings $settings) {
*/
public function get($collection) {
if (!isset($this->stores[$collection])) {
- if ($service_name = $this->settings->get(static::SPECIFIC_PREFIX . $collection)) {
+ if (isset($this->options[$collection])) {
+ $service_id = $this->options[$collection];
}
- elseif ($service_name = $this->settings->get(static::DEFAULT_SETTING)) {
+ elseif (isset($this->options[static::DEFAULT_SETTING])) {
+ $service_id = $this->options[static::DEFAULT_SETTING];
}
else {
- $service_name = static::DEFAULT_SERVICE;
+ $service_id = static::DEFAULT_SERVICE;
}
- $this->stores[$collection] = $this->container->get($service_name)->get($collection);
+ $this->stores[$collection] = $this->container->get($service_id)->get($collection);
}
return $this->stores[$collection];
}
diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php
index d8da1ca..fba0173 100644
--- a/core/lib/Drupal/Core/Template/TwigEnvironment.php
+++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php
@@ -41,7 +41,7 @@ class TwigEnvironment extends \Twig_Environment {
* Constructs a TwigEnvironment object and stores cache and storage
* internally.
*/
- public function __construct(\Twig_LoaderInterface $loader = NULL, $options = array(), ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) {
+ public function __construct(\Twig_LoaderInterface $loader = NULL, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, $options = array()) {
// @todo Pass as arguments from the DIC.
$this->cache_object = \Drupal::cache();
@@ -68,6 +68,16 @@ public function __construct(\Twig_LoaderInterface $loader = NULL, $options = arr
$this->templateClasses = array();
$this->stringLoader = new \Twig_Loader_String();
+ $options += array(
+ // @todo Ensure garbage collection of expired files.
+ 'cache' => TRUE,
+ // @todo Remove this.
+ // @see http://drupal.org/node/1712444
+ 'autoescape' => FALSE,
+ 'debug' => FALSE,
+ 'auto_reload' => NULL,
+ );
+
parent::__construct($loader, $options);
}
diff --git a/core/modules/simpletest/src/KernelTestBase.php b/core/modules/simpletest/src/KernelTestBase.php
index 616d064..154f7cf 100644
--- a/core/modules/simpletest/src/KernelTestBase.php
+++ b/core/modules/simpletest/src/KernelTestBase.php
@@ -260,7 +260,9 @@ public function containerBuild(ContainerBuilder $container) {
->addArgument(Database::getConnection())
->addArgument('config');
- $this->settingsSet('keyvalue_default', 'keyvalue.memory');
+ $keyvalue_config = $container->getParameter('factory.keyvalue') ?: array();
+ $keyvalue_config['default'] = 'keyvalue.memory';
+ $container->setParameter('factory.keyvalue', $keyvalue_config);
$container->set('keyvalue.memory', $this->keyValueFactory);
if (!$container->has('keyvalue')) {
// TestBase::setUp puts a completely empty container in
@@ -280,7 +282,7 @@ public function containerBuild(ContainerBuilder $container) {
$container
->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory')
->addArgument(new Reference('service_container'))
- ->addArgument(new Reference('settings'));
+ ->addArgument(new Parameter('factory.keyvalue'));
$container->register('state', 'Drupal\Core\State\State')
->addArgument(new Reference('keyvalue'));
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index e0b6858..0b41508 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -8,9 +8,11 @@
namespace Drupal\simpletest;
use Drupal\Component\Serialization\Json;
+use Drupal\Component\Serialization\Yaml;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\String;
+use Drupal\Core\DependencyInjection\YamlFileLoader;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\ConnectionNotDefinedException;
@@ -815,6 +817,7 @@ protected function setUp() {
// Not using File API; a potential error must trigger a PHP warning.
$directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php');
+ copy(DRUPAL_ROOT . '/sites/default/default.services.yml', $directory . '/services.yml');
// All file system paths are created by System module during installation.
// @see system_requirements()
@@ -1022,6 +1025,26 @@ protected function writeSettings(array $settings) {
}
/**
+ * Changes parameters in the services.yml file.
+ *
+ * @param $name
+ * The name of the parameter.
+ * @param $value
+ * The value of the parameter.
+ */
+ protected function containerParameterSet($name, $value) {
+ $filename = $this->siteDirectory . '/services.yml';
+ chmod($filename, 0666);
+
+ $services = Yaml::decode(file_get_contents($filename));
+ $services['parameters'][$name] = $value;
+ file_put_contents($filename, Yaml::encode($services));
+
+ // Clear the YML file cache.
+ YamlFileLoader::reset();
+ }
+
+ /**
* Queues custom translations to be written to settings.php.
*
* Use WebTestBase::writeCustomTranslations() to apply and write the queued
diff --git a/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageExpirableTest.php b/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
index b18befa..86a2bfb 100644
--- a/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
+++ b/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
@@ -7,6 +7,7 @@
namespace Drupal\system\Tests\KeyValueStore;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
use Symfony\Component\DependencyInjection\Reference;
/**
@@ -18,8 +19,9 @@ class DatabaseStorageExpirableTest extends StorageTestBase {
protected function setUp() {
parent::setUp();
+
$this->factory = 'keyvalue.expirable';
- module_load_install('system');
+ include_once DRUPAL_ROOT . '/core/modules/system/system.install';
$schema = system_schema();
db_create_table('key_value_expire', $schema['key_value_expire']);
$this->container
@@ -33,7 +35,9 @@ protected function setUp() {
->addArgument(new Reference('database'));
$this->container
->register('serialization.phpserialize', 'Drupal\Component\Serialization\PhpSerialize');
- $this->settingsSet('keyvalue_expirable_default', 'keyvalue.expirable.database');
+ $parameter = array();
+ $parameter[KeyValueFactory::DEFAULT_SETTING] = 'keyvalue.expirable.database';
+ $this->container->setParameter('factory.keyvalue.expirable', $parameter);
}
protected function tearDown() {
diff --git a/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageTest.php b/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageTest.php
index f3f61be..3bdab70 100644
--- a/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageTest.php
+++ b/core/modules/system/src/Tests/KeyValueStore/DatabaseStorageTest.php
@@ -7,6 +7,7 @@
namespace Drupal\system\Tests\KeyValueStore;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
use Symfony\Component\DependencyInjection\Reference;
/**
@@ -18,7 +19,7 @@ class DatabaseStorageTest extends StorageTestBase {
protected function setUp() {
parent::setUp();
- module_load_install('system');
+ include_once DRUPAL_ROOT . '/core/modules/system/system.install';
$schema = system_schema();
db_create_table('key_value', $schema['key_value']);
$this->container
@@ -32,7 +33,9 @@ protected function setUp() {
->addArgument(new Reference('database'));
$this->container
->register('serialization.phpserialize', 'Drupal\Component\Serialization\PhpSerialize');
- $this->settingsSet('keyvalue_default', 'keyvalue.database');
+ $parameter = array();
+ $parameter[KeyValueFactory::DEFAULT_SETTING] = 'keyvalue.database';
+ $this->container->setParameter('factory.keyvalue', $parameter);
}
protected function tearDown() {
diff --git a/core/modules/system/src/Tests/KeyValueStore/MemoryStorageTest.php b/core/modules/system/src/Tests/KeyValueStore/MemoryStorageTest.php
index 10b2a15..770d758 100644
--- a/core/modules/system/src/Tests/KeyValueStore/MemoryStorageTest.php
+++ b/core/modules/system/src/Tests/KeyValueStore/MemoryStorageTest.php
@@ -6,6 +6,7 @@
*/
namespace Drupal\system\Tests\KeyValueStore;
+use Drupal\Core\KeyValueStore\KeyValueFactory;
/**
* Tests the key-value memory storage.
@@ -25,7 +26,9 @@ protected function setUp() {
parent::setUp();
$this->container
->register('keyvalue.memory', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory');
- $this->settingsSet('keyvalue_default', 'keyvalue.memory');
+ $parameter = array();
+ $parameter[KeyValueFactory::DEFAULT_SETTING] = 'keyvalue.memory';
+ $this->container->setParameter('factory.keyvalue', $parameter);
}
}
diff --git a/core/modules/system/src/Tests/KeyValueStore/StorageTestBase.php b/core/modules/system/src/Tests/KeyValueStore/StorageTestBase.php
index 0190e6b..0d3bcd0 100644
--- a/core/modules/system/src/Tests/KeyValueStore/StorageTestBase.php
+++ b/core/modules/system/src/Tests/KeyValueStore/StorageTestBase.php
@@ -9,6 +9,7 @@
use Drupal\simpletest\UnitTestBase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
/**
@@ -58,11 +59,11 @@ protected function setUp() {
$this->container
->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory')
->addArgument(new Reference('service_container'))
- ->addArgument(new Reference('settings'));
+ ->addArgument('%factory.keyvalue%');
$this->container
->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueExpirableFactory')
->addArgument(new Reference('service_container'))
- ->addArgument(new Reference('settings'));
+ ->addArgument('%factory.keyvalue.expirable%');
// Define two data collections,
$this->collections = array(0 => 'zero', 1 => 'one');
diff --git a/core/modules/system/src/Tests/Theme/TwigDebugMarkupTest.php b/core/modules/system/src/Tests/Theme/TwigDebugMarkupTest.php
index 2836c2c..653e802 100644
--- a/core/modules/system/src/Tests/Theme/TwigDebugMarkupTest.php
+++ b/core/modules/system/src/Tests/Theme/TwigDebugMarkupTest.php
@@ -31,7 +31,9 @@ function testTwigDebugMarkup() {
theme_enable(array('test_theme'));
\Drupal::config('system.theme')->set('default', 'test_theme')->save();
// Enable debug, rebuild the service container, and clear all caches.
- $this->settingsSet('twig_debug', TRUE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['debug'] = TRUE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
$this->resetAll();
@@ -67,7 +69,9 @@ function testTwigDebugMarkup() {
$this->assertTrue(strpos($output, '* node--foo--bar' . $extension . PHP_EOL . ' * node--foo' . $extension . PHP_EOL . ' * node--3--full' . $extension . PHP_EOL . ' * node--3' . $extension . PHP_EOL . ' * node--page--full' . $extension . PHP_EOL . ' * node--page' . $extension . PHP_EOL . ' * node--full' . $extension . PHP_EOL . ' x node' . $extension) !== FALSE, 'Suggested template files found in order and base template shown as current template.');
// Disable debug, rebuild the service container, and clear all caches.
- $this->settingsSet('twig_debug', FALSE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['debug'] = FALSE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
$this->resetAll();
diff --git a/core/modules/system/src/Tests/Theme/TwigSettingsTest.php b/core/modules/system/src/Tests/Theme/TwigSettingsTest.php
index 630fc14..597ba5b 100644
--- a/core/modules/system/src/Tests/Theme/TwigSettingsTest.php
+++ b/core/modules/system/src/Tests/Theme/TwigSettingsTest.php
@@ -29,14 +29,18 @@ class TwigSettingsTest extends WebTestBase {
*/
function testTwigAutoReloadOverride() {
// Enable auto reload and rebuild the service container.
- $this->settingsSet('twig_auto_reload', TRUE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['auto_reload'] = TRUE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
// Check isAutoReload() via the Twig service container.
$this->assertTrue($this->container->get('twig')->isAutoReload(), 'Automatic reloading of Twig templates enabled.');
// Disable auto reload and check the service container again.
- $this->settingsSet('twig_auto_reload', FALSE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['auto_reload'] = FALSE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
$this->assertFalse($this->container->get('twig')->isAutoReload(), 'Automatic reloading of Twig templates disabled.');
@@ -47,7 +51,9 @@ function testTwigAutoReloadOverride() {
*/
function testTwigDebugOverride() {
// Enable debug and rebuild the service container.
- $this->settingsSet('twig_debug', TRUE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['debug'] = TRUE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
// Check isDebug() via the Twig service container.
@@ -55,12 +61,16 @@ function testTwigDebugOverride() {
$this->assertTrue($this->container->get('twig')->isAutoReload(), 'Twig automatic reloading is enabled when debug is enabled.');
// Override auto reload when debug is enabled.
- $this->settingsSet('twig_auto_reload', FALSE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['auto_reload'] = FALSE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
$this->assertFalse($this->container->get('twig')->isAutoReload(), 'Twig automatic reloading can be disabled when debug is enabled.');
// Disable debug and check the service container again.
- $this->settingsSet('twig_debug', FALSE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['debug'] = FALSE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
$this->assertFalse($this->container->get('twig')->isDebug(), 'Twig debug disabled.');
@@ -99,7 +109,9 @@ function testTwigCacheOverride() {
$this->assertTrue(PhpStorageFactory::get('twig')->exists($cache_filename), 'Cached Twig template found.');
// Disable the Twig cache and rebuild the service container.
- $this->settingsSet('twig_cache', FALSE);
+ $parameters = $this->container->getParameter('twig.config');
+ $parameters['cache'] = FALSE;
+ $this->containerParameterSet('twig.config', $parameters);
$this->rebuildContainer();
// This should return false after rebuilding the service container.
diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml
new file mode 100644
index 0000000..1087bc5
--- /dev/null
+++ b/sites/default/default.services.yml
@@ -0,0 +1,62 @@
+parameters:
+ twig.config:
+ # Twig debugging:
+ #
+ # When debugging is enabled:
+ # - The markup of each Twig template is surrounded by HTML comments that
+ # contain theming information, such as template file name suggestions.
+ # - Note that this debugging markup will cause automated tests that directly
+ # check rendered HTML to fail. When running automated tests, 'twig_debug'
+ # should be set to FALSE.
+ # - The dump() function can be used in Twig templates to output information
+ # about template variables.
+ # - Twig templates are automatically recompiled whenever the source code
+ # changes (see twig_auto_reload below).
+ #
+ # Note: changes to this setting will only take effect once the cache is
+ # cleared.
+ #
+ # For more information about debugging Twig templates, see
+ # http://drupal.org/node/1906392.
+ #
+ # Not recommended in production environments
+ # @default false
+ debug: false
+ # Twig auto-reload:
+ #
+ # Automatically recompile Twig templates whenever the source code changes.
+ # If you don't provide a value for twig_auto_reload, it will be determined
+ # based on the value of twig_debug.
+ #
+ # Note: changes to this setting will only take effect once the cache is
+ # cleared.
+ #
+ # Not recommended in production environments
+ # @default null
+ auto_reload: null
+ # Twig cache:
+ #
+ # By default, Twig templates will be compiled and stored in the filesystem
+ # to increase performance. Disabling the Twig cache will recompile the
+ # templates from source each time they are used. In most cases the
+ # twig_auto_reload setting above should be enabled rather than disabling the
+ # Twig cache.
+ #
+ # Note: changes to this setting will only take effect once the cache is
+ # cleared.
+ #
+ # Not recommended in production environments
+ # @default true
+ cache: true
+ factory.keyvalue:
+ {}
+ # Default key/value storage service to use.
+ # @default keyvalue.database
+ #default: keyvalue.database
+ # Collection-specific overrides.
+ #state: keyvalue.database
+ factory.keyvalue.expirable:
+ {}
+ # Default key/value expirable storage service to use.
+ # @default keyvalue.database.expirable
+ #default: keyvalue.database.expirable
diff --git a/sites/example.settings.local.php b/sites/example.settings.local.php
index 19f398c..b602a97 100644
--- a/sites/example.settings.local.php
+++ b/sites/example.settings.local.php
@@ -33,56 +33,3 @@
* using these parameters in a request to rebuild.php.
*/
$settings['rebuild_access'] = TRUE;
-
-/**
- * Twig debugging:
- *
- * When debugging is enabled:
- * - The markup of each Twig template is surrounded by HTML comments that
- * contain theming information, such as template file name suggestions.
- * - Note that this debugging markup will cause automated tests that directly
- * check rendered HTML to fail. When running automated tests, 'twig_debug'
- * should be set to FALSE.
- * - The dump() function can be used in Twig templates to output information
- * about template variables.
- * - Twig templates are automatically recompiled whenever the source code
- * changes (see twig_auto_reload below).
- *
- * Note: changes to this setting will only take effect once the cache is
- * cleared.
- *
- * For more information about debugging Twig templates, see
- * http://drupal.org/node/1906392.
- *
- * Not recommended in production environments (Default: FALSE).
- */
-# $settings['twig_debug'] = TRUE;
-
-/**
- * Twig auto-reload:
- *
- * Automatically recompile Twig templates whenever the source code changes. If
- * you don't provide a value for twig_auto_reload, it will be determined based
- * on the value of twig_debug.
- *
- * Note: changes to this setting will only take effect once the cache is
- * cleared.
- *
- * Not recommended in production environments (Default: NULL).
- */
-# $settings['twig_auto_reload'] = TRUE;
-
-/**
- * Twig cache:
- *
- * By default, Twig templates will be compiled and stored in the filesystem to
- * increase performance. Disabling the Twig cache will recompile the templates
- * from source each time they are used. In most cases the twig_auto_reload
- * setting above should be enabled rather than disabling the Twig cache.
- *
- * Note: changes to this setting will only take effect once the cache is
- * cleared.
- *
- * Not recommended in production environments (Default: TRUE).
- */
-# $settings['twig_cache'] = FALSE;