diff --git a/core/includes/config.inc b/core/includes/config.inc index 51476b7..771de70 100644 --- a/core/includes/config.inc +++ b/core/includes/config.inc @@ -65,7 +65,7 @@ function config_get_storage_names_with_prefix($prefix = '') { * A configuration object. */ function config($name) { - return drupal_container()->get('config.factory')->get($name)->load(); + return drupal_container()->get('config.factory')->get($name); } /** @@ -155,14 +155,9 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou // handle the configuration change. $handled_by_module = FALSE; if (module_hook($module, 'config_import_' . $op)) { - $old_config = new Config($storage_dispatcher); - $old_config - ->setName($name) - ->load(); - + $old_config = new Config($name, $storage_dispatcher); $data = $source_storage->read($name); - $new_config = new Config($storage_dispatcher); - $new_config->setName($name); + $new_config = new Config($name, $storage_dispatcher); if ($data !== FALSE) { $new_config->setData($data); } diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index a749a4b..12e47f4 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -31,7 +31,17 @@ class Config { * * @var array */ - protected $data = array(); + protected $data; + + /** + * The overridden data of the configuration object. + */ + protected $override; + + /** + * The current runtime data ($data + $override) + */ + protected $current; /** * The injected storage dispatcher object. @@ -43,11 +53,14 @@ class Config { /** * Constructs a configuration object. * + * @param $name + * The name of this configuration object. * @param Drupal\Core\Config\StorageDispatcher $storageDispatcher * A storage dispatcher object to use for reading and writing the * configuration data. */ - public function __construct(StorageDispatcher $storageDispatcher) { + public function __construct($name, StorageDispatcher $storageDispatcher) { + $this->name = $name; $this->storageDispatcher = $storageDispatcher; } @@ -59,17 +72,10 @@ class Config { } /** - * Sets the name of this configuration object. - */ - public function setName($name) { - $this->name = $name; - return $this; - } - - /** * Returns whether this configuration object is new. */ public function isNew() { + $this->build(); return $this->isNew; } @@ -101,27 +107,18 @@ class Config { * The data that was requested. */ public function get($key = '') { - global $conf; - - $name = $this->getName(); - if (isset($conf[$name])) { - $merged_data = drupal_array_merge_deep($this->data, $conf[$name]); - } - else { - $merged_data = $this->data; - } - + $this->build(); if (empty($key)) { - return $merged_data; + return $this->current; } else { $parts = explode('.', $key); if (count($parts) == 1) { - return isset($merged_data[$key]) ? $merged_data[$key] : NULL; + return isset($this->current[$key]) ? $this->current[$key] : NULL; } else { $key_exists = NULL; - $value = drupal_array_get_nested_value($merged_data, $parts, $key_exists); + $value = drupal_array_get_nested_value($this->current, $parts, $key_exists); return $key_exists ? $value : NULL; } } @@ -135,7 +132,18 @@ class Config { */ public function setData(array $data) { $this->data = $data; - return $this; + return $this->rebuild(); + } + + /** + * Sets some values for this configuration object only for this request. + * + * @param array $data + * The overrideen values of the configuration data. + */ + public function setOverride(array $data) { + $this->override = $data; + return $this->rebuild(); } /** @@ -159,7 +167,7 @@ class Config { else { drupal_array_set_nested_value($this->data, $parts, $value); } - return $this; + return $this->rebuild(); } /** @@ -208,6 +216,7 @@ class Config { * Name of the key whose value should be unset. */ public function clear($key) { + $this->build(); $parts = explode('.', $key); if (count($parts) == 1) { unset($this->data[$key]); @@ -215,7 +224,7 @@ class Config { else { drupal_array_unset_nested_value($this->data, $parts); } - return $this; + return $this->rebuild(); } /** @@ -238,10 +247,11 @@ class Config { * Saves the configuration object. */ public function save() { + $this->build(); $this->sortByKey($this->data); $this->storageDispatcher->selectStorage('write', $this->name)->write($this->name, $this->data); $this->isNew = FALSE; - return $this; + return $this->rebuild(); } /** @@ -271,6 +281,32 @@ class Config { $this->data = array(); $this->storageDispatcher->selectStorage('write', $this->name)->delete($this->name); $this->isNew = TRUE; + return $this->rebuild(); + } + + /** + * Build the data for this configuration object. + * + * Loads the base data if not loaded, and builds the current runtime configuration + * computing the overridden values. + */ + public function build() { + if (!isset($this->current)) { + if (!isset($this->data)) { + $this->load(); + } + $this->current = $this->data; + if (!empty($this->override)) { + $this->current = drupal_array_merge_deep($this->current, $this->override); + } + } + return $this; + } + /** + * Mark the current data to be rebuilt. + */ + public function rebuild() { + unset($this->current); return $this; } } diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 1fbca62..d6b046c 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -50,6 +50,8 @@ class ConfigFactory { * A configuration object with the given $name. */ public function get($name) { + global $conf; + // @todo Caching the instantiated objects per name might cut off a fair // amount of CPU time and memory. Only the data within the configuration // object changes, so the additional cost of instantiating duplicate @@ -68,7 +70,11 @@ class ConfigFactory { // @todo The decrease of CPU time is interesting, since that means that // ContainerBuilder involves plenty of function calls (which are known to // be slow in PHP). - $config = new Config($this->storageDispatcher); - return $config->setName($name); + $config = new Config($name, $this->storageDispatcher); + // Add any overridden values in global $conf + if (isset($conf[$name])) { + $config->setOverride($conf[$name]); + } + return $config; } }