Skip to content
Snippets Groups Projects
Commit 5a43052d authored by Dries Buytaert's avatar Dries Buytaert
Browse files

- Patch #1671080 by sun, no_commit_credit, Gábor Hojtsy, Jose Reyero: remove...

- Patch #1671080 by sun, no_commit_credit, Gábor Hojtsy, Jose Reyero: remove StorageDispatcher to simplify configuration system.
parent 54360936
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
...@@ -2437,26 +2437,22 @@ function drupal_container(Container $reset = NULL) { ...@@ -2437,26 +2437,22 @@ function drupal_container(Container $reset = NULL) {
// This will get merged with the full Kernel-built Container on normal page // This will get merged with the full Kernel-built Container on normal page
// requests. // requests.
$container = new ContainerBuilder(); $container = new ContainerBuilder();
// Register configuration storage dispatcher.
$container->setParameter('config.storage.info', array( // Register configuration storage class and options.
'Drupal\Core\Config\DatabaseStorage' => array( // @todo The active store and its options need to be configurable.
// Use either global $conf (recursion warning) or global $config, or a
// bootstrap configuration *file* to allow to set/override this very
// lowest of low level configuration.
$container->setParameter('config.storage.options', array(
'connection' => 'default', 'connection' => 'default',
'target' => 'default', 'target' => 'default',
'read' => TRUE,
'write' => TRUE,
),
'Drupal\Core\Config\FileStorage' => array(
'directory' => config_get_config_directory(),
'read' => TRUE,
'write' => FALSE,
),
)); ));
$container->register('config.storage.dispatcher', 'Drupal\Core\Config\StorageDispatcher') $container->register('config.storage', 'Drupal\Core\Config\DatabaseStorage')
->addArgument('%config.storage.info%'); ->addArgument('%config.storage.options%');
// Register configuration object factory. // Register configuration object factory.
$container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
->addArgument(new Reference('config.storage.dispatcher')); ->addArgument(new Reference('config.storage'));
} }
return $container; return $container;
} }
......
<?php <?php
use Drupal\Core\Config\Config; use Drupal\Core\Config\Config;
use Drupal\Core\Config\DatabaseStorage;
use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\NullStorage; use Drupal\Core\Config\NullStorage;
use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\StorageInterface;
...@@ -26,7 +25,7 @@ function config_install_default_config($type, $name) { ...@@ -26,7 +25,7 @@ function config_install_default_config($type, $name) {
$config_dir = drupal_get_path($type, $name) . '/config'; $config_dir = drupal_get_path($type, $name) . '/config';
if (is_dir($config_dir)) { if (is_dir($config_dir)) {
$source_storage = new FileStorage(array('directory' => $config_dir)); $source_storage = new FileStorage(array('directory' => $config_dir));
$target_storage = new DatabaseStorage(); $target_storage = drupal_container()->get('config.storage');
$null_storage = new NullStorage(); $null_storage = new NullStorage();
// Upon installation, only new config objects need to be created. // Upon installation, only new config objects need to be created.
...@@ -47,8 +46,7 @@ function config_install_default_config($type, $name) { ...@@ -47,8 +46,7 @@ function config_install_default_config($type, $name) {
* @todo Modules need a way to access the active store, whatever it is. * @todo Modules need a way to access the active store, whatever it is.
*/ */
function config_get_storage_names_with_prefix($prefix = '') { function config_get_storage_names_with_prefix($prefix = '') {
$storage = new DatabaseStorage(); return drupal_container()->get('config.storage')->listAll($prefix);
return $storage->listAll($prefix);
} }
/** /**
...@@ -131,17 +129,16 @@ function config_sync_changes(array $config_changes, StorageInterface $source_sto ...@@ -131,17 +129,16 @@ function config_sync_changes(array $config_changes, StorageInterface $source_sto
} }
/** /**
* Imports configuration from FileStorage to DatabaseStorage. * Imports configuration from FileStorage to the active store.
* *
* @return bool|null * @return bool|null
* TRUE if configuration was imported successfully, FALSE in case of a * TRUE if configuration was imported successfully, FALSE in case of a
* synchronization error, or NULL if there are no changes to synchronize. * synchronization error, or NULL if there are no changes to synchronize.
*/ */
function config_import() { function config_import() {
// Retrieve a list of differences between FileStorage and DatabaseStorage. // Retrieve a list of differences between FileStorage and the active store.
// @todo Leverage DI + config.storage.info.
$source_storage = new FileStorage(); $source_storage = new FileStorage();
$target_storage = new DatabaseStorage(); $target_storage = drupal_container()->get('config.storage');
$config_changes = config_sync_get_changes($source_storage, $target_storage); $config_changes = config_sync_get_changes($source_storage, $target_storage);
if (empty($config_changes)) { if (empty($config_changes)) {
...@@ -185,8 +182,6 @@ function config_import() { ...@@ -185,8 +182,6 @@ function config_import() {
* @todo Add support for other extension types; e.g., themes etc. * @todo Add support for other extension types; e.g., themes etc.
*/ */
function config_import_invoke_owner(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) { function config_import_invoke_owner(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) {
$storage_dispatcher = drupal_container()->get('config.storage.dispatcher');
// Allow modules to take over configuration change operations for // Allow modules to take over configuration change operations for
// higher-level configuration data. // higher-level configuration data.
// First pass deleted, then new, and lastly changed configuration, in order to // First pass deleted, then new, and lastly changed configuration, in order to
...@@ -199,13 +194,13 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou ...@@ -199,13 +194,13 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou
// handle the configuration change. // handle the configuration change.
$handled_by_module = FALSE; $handled_by_module = FALSE;
if (module_hook($module, 'config_import_' . $op)) { if (module_hook($module, 'config_import_' . $op)) {
$old_config = new Config($storage_dispatcher); $old_config = new Config($target_storage);
$old_config $old_config
->setName($name) ->setName($name)
->load(); ->load();
$data = $source_storage->read($name); $data = $source_storage->read($name);
$new_config = new Config($storage_dispatcher); $new_config = new Config($target_storage);
$new_config->setName($name); $new_config->setName($name);
if ($data !== FALSE) { if ($data !== FALSE) {
$new_config->setData($data); $new_config->setData($data);
...@@ -222,12 +217,11 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou ...@@ -222,12 +217,11 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou
} }
/** /**
* Exports configuration from DatabaseStorage to FileStorage. * Exports configuration from the active store to FileStorage.
*/ */
function config_export() { function config_export() {
// Retrieve a list of differences between DatabaseStorage and FileStorage. // Retrieve a list of differences between the active store and FileStorage.
// @todo Leverage DI + config.storage.info. $source_storage = drupal_container()->get('config.storage');
$source_storage = new DatabaseStorage();
$target_storage = new FileStorage(); $target_storage = new FileStorage();
$config_changes = config_sync_get_changes($source_storage, $target_storage); $config_changes = config_sync_get_changes($source_storage, $target_storage);
......
...@@ -36,21 +36,21 @@ class Config { ...@@ -36,21 +36,21 @@ class Config {
protected $data = array(); protected $data = array();
/** /**
* The injected storage dispatcher object. * The storage used for reading and writing.
* *
* @var Drupal\Core\Config\StorageDispatcher * @var Drupal\Core\Config\StorageInterface
*/ */
protected $storageDispatcher; protected $storage;
/** /**
* Constructs a configuration object. * Constructs a configuration object.
* *
* @param Drupal\Core\Config\StorageDispatcher $storageDispatcher * @param Drupal\Core\Config\StorageInterface $storage
* A storage dispatcher object to use for reading and writing the * A storage controller object to use for reading and writing the
* configuration data. * configuration data.
*/ */
public function __construct(StorageDispatcher $storageDispatcher) { public function __construct(StorageInterface $storage) {
$this->storageDispatcher = $storageDispatcher; $this->storage = $storage;
} }
/** /**
...@@ -224,7 +224,7 @@ public function clear($key) { ...@@ -224,7 +224,7 @@ public function clear($key) {
* Loads configuration data into this object. * Loads configuration data into this object.
*/ */
public function load() { public function load() {
$data = $this->storageDispatcher->selectStorage('read', $this->name)->read($this->name); $data = $this->storage->read($this->name);
if ($data === FALSE) { if ($data === FALSE) {
$this->isNew = TRUE; $this->isNew = TRUE;
$this->setData(array()); $this->setData(array());
...@@ -241,7 +241,7 @@ public function load() { ...@@ -241,7 +241,7 @@ public function load() {
*/ */
public function save() { public function save() {
$this->sortByKey($this->data); $this->sortByKey($this->data);
$this->storageDispatcher->selectStorage('write', $this->name)->write($this->name, $this->data); $this->storage->write($this->name, $this->data);
$this->isNew = FALSE; $this->isNew = FALSE;
return $this; return $this;
} }
...@@ -271,7 +271,7 @@ public function sortByKey(array &$data) { ...@@ -271,7 +271,7 @@ public function sortByKey(array &$data) {
*/ */
public function delete() { public function delete() {
$this->data = array(); $this->data = array();
$this->storageDispatcher->selectStorage('write', $this->name)->delete($this->name); $this->storage->delete($this->name);
$this->isNew = TRUE; $this->isNew = TRUE;
return $this; return $this;
} }
......
...@@ -15,29 +15,29 @@ ...@@ -15,29 +15,29 @@
* *
* @see Drupal\Core\Config\Config * @see Drupal\Core\Config\Config
* *
* Each configuration object gets a storage dispatcher object injected, which * Each configuration object gets a storage controller object injected, which
* determines the storage controller to use for reading and writing the * is used for reading and writing the configuration data.
* configuration data.
* *
* @see Drupal\Core\Config\StorageDispatcher * @see Drupal\Core\Config\StorageInterface
*/ */
class ConfigFactory { class ConfigFactory {
/** /**
* A storage dispatcher instance to use for reading and writing configuration data. * A storage controller instance for reading and writing configuration data.
* *
* @var Drupal\Core\Config\StorageDispatcher * @var Drupal\Core\Config\StorageInterface
*/ */
protected $storageDispatcher; protected $storage;
/** /**
* Constructs the Config factory. * Constructs the Config factory.
* *
* @param Drupal\Core\Config\StorageDispatcher $storage_dispatcher * @param Drupal\Core\Config\StorageInterface $storage
* The storage dispatcher object to use for reading and writing * The storage controller object to use for reading and writing
* configuration data. * configuration data.
*/ */
public function __construct(StorageDispatcher $storage_dispatcher) { public function __construct(StorageInterface $storage) {
$this->storageDispatcher = $storage_dispatcher; $this->storage = $storage;
} }
/** /**
...@@ -68,7 +68,8 @@ public function get($name) { ...@@ -68,7 +68,8 @@ public function get($name) {
// @todo The decrease of CPU time is interesting, since that means that // @todo The decrease of CPU time is interesting, since that means that
// ContainerBuilder involves plenty of function calls (which are known to // ContainerBuilder involves plenty of function calls (which are known to
// be slow in PHP). // be slow in PHP).
$config = new Config($this->storageDispatcher); $config = new Config($this->storage);
return $config->setName($name); return $config->setName($name);
} }
} }
...@@ -56,8 +56,8 @@ public function read($name) { ...@@ -56,8 +56,8 @@ public function read($name) {
// read without actually having the database available. In this case, // read without actually having the database available. In this case,
// catch the exception and just return an empty array so the caller can // catch the exception and just return an empty array so the caller can
// handle it if need be. // handle it if need be.
// @todo Remove this and use appropriate StorageDispatcher configuration in // @todo Remove this and use appropriate config.storage service definition
// the installer instead. // in the installer instead.
try { try {
$raw = $this->getConnection()->query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name), $this->options)->fetchField(); $raw = $this->getConnection()->query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name), $this->options)->fetchField();
if ($raw !== FALSE) { if ($raw !== FALSE) {
......
<?php
namespace Drupal\Core\Config;
/**
* Dispatches read/write operations to storage controllers.
*
* The storage dispatcher determines which storage out of multiple is configured
* and allowed to handle a particular configuration object, depending on the
* read/write operation being performed.
*
* The information about available storage controllers and their configuration
* options is passed once into the constructor and normally should not change
* within a single request or context. Special use-cases, such as import and
* export operations, should instantiate a custom storage dispatcher tailored
* to their specific needs.
*
* The storage dispatcher instantiates storage controllers on demand, and only
* once per storage.
*
* @see Drupal\Core\Config\StorageInterface
*/
class StorageDispatcher {
/**
* Information about available storage controllers.
*
* @var array
*/
protected $storageInfo;
/**
* Instantiated storage controller objects.
*
* @see Drupal\Core\Config\StorageInterface
*
* @var array
*/
protected $storageInstances;
/**
* Constructs the storage dispatcher object.
*
* @param array $storage_info
* An associative array defining the storage controllers to use and any
* required configuration options for them; e.g.:
* @code
* array(
* 'Drupal\Core\Config\DatabaseStorage' => array(
* 'target' => 'default',
* 'read' => TRUE,
* 'write' => TRUE,
* ),
* 'Drupal\Core\Config\FileStorage' => array(
* 'directory' => 'sites/default/files/config',
* 'read' => TRUE,
* 'write' => FALSE,
* ),
* )
* @endcode
*/
public function __construct(array $storage_info) {
$this->storageInfo = $storage_info;
}
/**
* Returns a storage controller to use for a given operation.
*
* Handles the core functionality of the storage dispatcher by determining
* which storage can handle a particular storage access operation and
* configuration object.
*
* @param string $access_operation
* The operation access level; either 'read' or 'write'. Use 'write' both
* for saving and deleting configuration.
* @param string $name
* The name of the configuration object that is operated on.
*
* @return Drupal\Core\Config\StorageInterface
* The storage controller instance that can handle the requested operation.
*
* @throws Drupal\Core\Config\ConfigException
*
* @todo Allow write operations to write to multiple storages.
*/
public function selectStorage($access_operation, $name) {
// Determine the appropriate storage controller to use.
// Take the first defined storage that allows $op.
foreach ($this->storageInfo as $class => $storage_config) {
if (!empty($storage_config[$access_operation])) {
$storage_class = $class;
break;
}
}
if (!isset($storage_class)) {
throw new ConfigException("Failed to find storage controller that allows $access_operation access for $name.");
}
// Instantiate a new storage controller object, if there is none yet.
if (!isset($this->storageInstances[$storage_class])) {
$this->storageInstances[$storage_class] = new $storage_class($this->storageInfo[$storage_class]);
}
return $this->storageInstances[$storage_class];
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment