annotate core/lib/Drupal/Core/Config/Config.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 4c8ae668cc8c
children c2387f117808
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Config;
Chris@0 4
Chris@0 5 use Drupal\Component\Utility\NestedArray;
Chris@0 6 use Drupal\Core\Cache\Cache;
Chris@0 7 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
Chris@0 8
Chris@0 9 /**
Chris@0 10 * Defines the default configuration object.
Chris@0 11 *
Chris@0 12 * Encapsulates all capabilities needed for configuration handling for a
Chris@0 13 * specific configuration object, including support for runtime overrides. The
Chris@0 14 * overrides are handled on top of the stored configuration so they are not
Chris@0 15 * saved back to storage.
Chris@0 16 *
Chris@0 17 * @ingroup config_api
Chris@0 18 */
Chris@0 19 class Config extends StorableConfigBase {
Chris@0 20
Chris@0 21 /**
Chris@0 22 * An event dispatcher instance to use for configuration events.
Chris@0 23 *
Chris@0 24 * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
Chris@0 25 */
Chris@0 26 protected $eventDispatcher;
Chris@0 27
Chris@0 28 /**
Chris@0 29 * The current runtime data.
Chris@0 30 *
Chris@0 31 * The configuration data from storage merged with module and settings
Chris@0 32 * overrides.
Chris@0 33 *
Chris@0 34 * @var array
Chris@0 35 */
Chris@0 36 protected $overriddenData;
Chris@0 37
Chris@0 38 /**
Chris@0 39 * The current module overrides.
Chris@0 40 *
Chris@0 41 * @var array
Chris@0 42 */
Chris@0 43 protected $moduleOverrides;
Chris@0 44
Chris@0 45 /**
Chris@0 46 * The current settings overrides.
Chris@0 47 *
Chris@0 48 * @var array
Chris@0 49 */
Chris@0 50 protected $settingsOverrides;
Chris@0 51
Chris@0 52 /**
Chris@0 53 * Constructs a configuration object.
Chris@0 54 *
Chris@0 55 * @param string $name
Chris@0 56 * The name of the configuration object being constructed.
Chris@0 57 * @param \Drupal\Core\Config\StorageInterface $storage
Chris@0 58 * A storage object to use for reading and writing the
Chris@0 59 * configuration data.
Chris@0 60 * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
Chris@0 61 * An event dispatcher instance to use for configuration events.
Chris@0 62 * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
Chris@0 63 * The typed configuration manager service.
Chris@0 64 */
Chris@0 65 public function __construct($name, StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) {
Chris@0 66 $this->name = $name;
Chris@0 67 $this->storage = $storage;
Chris@0 68 $this->eventDispatcher = $event_dispatcher;
Chris@0 69 $this->typedConfigManager = $typed_config;
Chris@0 70 }
Chris@0 71
Chris@0 72 /**
Chris@0 73 * {@inheritdoc}
Chris@0 74 */
Chris@0 75 public function initWithData(array $data) {
Chris@0 76 parent::initWithData($data);
Chris@0 77 $this->resetOverriddenData();
Chris@0 78 return $this;
Chris@0 79 }
Chris@0 80
Chris@0 81 /**
Chris@0 82 * {@inheritdoc}
Chris@0 83 */
Chris@0 84 public function get($key = '') {
Chris@0 85 if (!isset($this->overriddenData)) {
Chris@0 86 $this->setOverriddenData();
Chris@0 87 }
Chris@0 88 if (empty($key)) {
Chris@0 89 return $this->overriddenData;
Chris@0 90 }
Chris@0 91 else {
Chris@0 92 $parts = explode('.', $key);
Chris@0 93 if (count($parts) == 1) {
Chris@0 94 return isset($this->overriddenData[$key]) ? $this->overriddenData[$key] : NULL;
Chris@0 95 }
Chris@0 96 else {
Chris@0 97 $value = NestedArray::getValue($this->overriddenData, $parts, $key_exists);
Chris@0 98 return $key_exists ? $value : NULL;
Chris@0 99 }
Chris@0 100 }
Chris@0 101 }
Chris@0 102
Chris@0 103 /**
Chris@0 104 * {@inheritdoc}
Chris@0 105 */
Chris@0 106 public function setData(array $data) {
Chris@0 107 parent::setData($data);
Chris@0 108 $this->resetOverriddenData();
Chris@0 109 return $this;
Chris@0 110 }
Chris@0 111
Chris@0 112 /**
Chris@0 113 * Sets settings.php overrides for this configuration object.
Chris@0 114 *
Chris@0 115 * The overridden data only applies to this configuration object.
Chris@0 116 *
Chris@0 117 * @param array $data
Chris@0 118 * The overridden values of the configuration data.
Chris@0 119 *
Chris@0 120 * @return \Drupal\Core\Config\Config
Chris@0 121 * The configuration object.
Chris@0 122 */
Chris@0 123 public function setSettingsOverride(array $data) {
Chris@0 124 $this->settingsOverrides = $data;
Chris@0 125 $this->resetOverriddenData();
Chris@0 126 return $this;
Chris@0 127 }
Chris@0 128
Chris@0 129 /**
Chris@0 130 * Sets module overrides for this configuration object.
Chris@0 131 *
Chris@0 132 * @param array $data
Chris@0 133 * The overridden values of the configuration data.
Chris@0 134 *
Chris@0 135 * @return \Drupal\Core\Config\Config
Chris@0 136 * The configuration object.
Chris@0 137 */
Chris@0 138 public function setModuleOverride(array $data) {
Chris@0 139 $this->moduleOverrides = $data;
Chris@0 140 $this->resetOverriddenData();
Chris@0 141 return $this;
Chris@0 142 }
Chris@0 143
Chris@0 144 /**
Chris@0 145 * Sets the current data for this configuration object.
Chris@0 146 *
Chris@0 147 * Configuration overrides operate at two distinct layers: modules and
Chris@0 148 * settings.php. Overrides in settings.php take precedence over values
Chris@0 149 * provided by modules. Precedence or different module overrides is
Chris@0 150 * determined by the priority of the config.factory.override tagged services.
Chris@0 151 *
Chris@0 152 * @return \Drupal\Core\Config\Config
Chris@0 153 * The configuration object.
Chris@0 154 */
Chris@0 155 protected function setOverriddenData() {
Chris@0 156 $this->overriddenData = $this->data;
Chris@0 157 if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
Chris@0 158 $this->overriddenData = NestedArray::mergeDeepArray([$this->overriddenData, $this->moduleOverrides], TRUE);
Chris@0 159 }
Chris@0 160 if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
Chris@0 161 $this->overriddenData = NestedArray::mergeDeepArray([$this->overriddenData, $this->settingsOverrides], TRUE);
Chris@0 162 }
Chris@0 163 return $this;
Chris@0 164 }
Chris@0 165
Chris@0 166 /**
Chris@0 167 * Resets the current data, so overrides are re-applied.
Chris@0 168 *
Chris@0 169 * This method should be called after the original data or the overridden data
Chris@0 170 * has been changed.
Chris@0 171 *
Chris@0 172 * @return \Drupal\Core\Config\Config
Chris@0 173 * The configuration object.
Chris@0 174 */
Chris@0 175 protected function resetOverriddenData() {
Chris@0 176 unset($this->overriddenData);
Chris@0 177 return $this;
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * {@inheritdoc}
Chris@0 182 */
Chris@0 183 public function set($key, $value) {
Chris@0 184 parent::set($key, $value);
Chris@0 185 $this->resetOverriddenData();
Chris@0 186 return $this;
Chris@0 187 }
Chris@0 188
Chris@0 189 /**
Chris@0 190 * {@inheritdoc}
Chris@0 191 */
Chris@0 192 public function clear($key) {
Chris@0 193 parent::clear($key);
Chris@0 194 $this->resetOverriddenData();
Chris@0 195 return $this;
Chris@0 196 }
Chris@0 197
Chris@0 198 /**
Chris@0 199 * {@inheritdoc}
Chris@0 200 */
Chris@0 201 public function save($has_trusted_data = FALSE) {
Chris@0 202 // Validate the configuration object name before saving.
Chris@0 203 static::validateName($this->name);
Chris@0 204
Chris@0 205 // If there is a schema for this configuration object, cast all values to
Chris@0 206 // conform to the schema.
Chris@0 207 if (!$has_trusted_data) {
Chris@0 208 if ($this->typedConfigManager->hasConfigSchema($this->name)) {
Chris@0 209 // Ensure that the schema wrapper has the latest data.
Chris@0 210 $this->schemaWrapper = NULL;
Chris@0 211 foreach ($this->data as $key => $value) {
Chris@0 212 $this->data[$key] = $this->castValue($key, $value);
Chris@0 213 }
Chris@0 214 }
Chris@0 215 else {
Chris@0 216 foreach ($this->data as $key => $value) {
Chris@0 217 $this->validateValue($key, $value);
Chris@0 218 }
Chris@0 219 }
Chris@0 220 }
Chris@0 221
Chris@0 222 $this->storage->write($this->name, $this->data);
Chris@0 223 if (!$this->isNew) {
Chris@0 224 Cache::invalidateTags($this->getCacheTags());
Chris@0 225 }
Chris@0 226 $this->isNew = FALSE;
Chris@0 227 $this->eventDispatcher->dispatch(ConfigEvents::SAVE, new ConfigCrudEvent($this));
Chris@0 228 $this->originalData = $this->data;
Chris@0 229 // Potentially configuration schema could have changed the underlying data's
Chris@0 230 // types.
Chris@0 231 $this->resetOverriddenData();
Chris@0 232 return $this;
Chris@0 233 }
Chris@0 234
Chris@0 235 /**
Chris@0 236 * Deletes the configuration object.
Chris@0 237 *
Chris@0 238 * @return \Drupal\Core\Config\Config
Chris@0 239 * The configuration object.
Chris@0 240 */
Chris@0 241 public function delete() {
Chris@0 242 $this->data = [];
Chris@0 243 $this->storage->delete($this->name);
Chris@0 244 Cache::invalidateTags($this->getCacheTags());
Chris@0 245 $this->isNew = TRUE;
Chris@0 246 $this->resetOverriddenData();
Chris@0 247 $this->eventDispatcher->dispatch(ConfigEvents::DELETE, new ConfigCrudEvent($this));
Chris@0 248 $this->originalData = $this->data;
Chris@0 249 return $this;
Chris@0 250 }
Chris@0 251
Chris@0 252 /**
Chris@0 253 * Gets the raw data without overrides.
Chris@0 254 *
Chris@0 255 * @return array
Chris@0 256 * The raw data.
Chris@0 257 */
Chris@0 258 public function getRawData() {
Chris@0 259 return $this->data;
Chris@0 260 }
Chris@0 261
Chris@0 262 /**
Chris@0 263 * Gets original data from this configuration object.
Chris@0 264 *
Chris@0 265 * Original data is the data as it is immediately after loading from
Chris@0 266 * configuration storage before any changes. If this is a new configuration
Chris@0 267 * object it will be an empty array.
Chris@0 268 *
Chris@0 269 * @see \Drupal\Core\Config\Config::get()
Chris@0 270 *
Chris@0 271 * @param string $key
Chris@0 272 * A string that maps to a key within the configuration data.
Chris@0 273 * @param bool $apply_overrides
Chris@0 274 * Apply any overrides to the original data. Defaults to TRUE.
Chris@0 275 *
Chris@0 276 * @return mixed
Chris@0 277 * The data that was requested.
Chris@0 278 */
Chris@0 279 public function getOriginal($key = '', $apply_overrides = TRUE) {
Chris@0 280 $original_data = $this->originalData;
Chris@0 281 if ($apply_overrides) {
Chris@0 282 // Apply overrides.
Chris@0 283 if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
Chris@0 284 $original_data = NestedArray::mergeDeepArray([$original_data, $this->moduleOverrides], TRUE);
Chris@0 285 }
Chris@0 286 if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
Chris@0 287 $original_data = NestedArray::mergeDeepArray([$original_data, $this->settingsOverrides], TRUE);
Chris@0 288 }
Chris@0 289 }
Chris@0 290
Chris@0 291 if (empty($key)) {
Chris@0 292 return $original_data;
Chris@0 293 }
Chris@0 294 else {
Chris@0 295 $parts = explode('.', $key);
Chris@0 296 if (count($parts) == 1) {
Chris@0 297 return isset($original_data[$key]) ? $original_data[$key] : NULL;
Chris@0 298 }
Chris@0 299 else {
Chris@0 300 $value = NestedArray::getValue($original_data, $parts, $key_exists);
Chris@0 301 return $key_exists ? $value : NULL;
Chris@0 302 }
Chris@0 303 }
Chris@0 304 }
Chris@0 305
Chris@14 306 /**
Chris@14 307 * Determines if overrides are applied to a key for this configuration object.
Chris@14 308 *
Chris@14 309 * @param string $key
Chris@14 310 * (optional) A string that maps to a key within the configuration data.
Chris@14 311 * For instance in the following configuration array:
Chris@14 312 * @code
Chris@14 313 * array(
Chris@14 314 * 'foo' => array(
Chris@14 315 * 'bar' => 'baz',
Chris@14 316 * ),
Chris@14 317 * );
Chris@14 318 * @endcode
Chris@14 319 * A key of 'foo.bar' would map to the string 'baz'. However, a key of 'foo'
Chris@14 320 * would map to the array('bar' => 'baz').
Chris@14 321 * If not supplied TRUE will be returned if there are any overrides at all
Chris@14 322 * for this configuration object.
Chris@14 323 *
Chris@14 324 * @return bool
Chris@14 325 * TRUE if there are any overrides for the key, otherwise FALSE.
Chris@14 326 */
Chris@14 327 public function hasOverrides($key = '') {
Chris@14 328 if (empty($key)) {
Chris@14 329 return !(empty($this->moduleOverrides) && empty($this->settingsOverrides));
Chris@14 330 }
Chris@14 331 else {
Chris@14 332 $parts = explode('.', $key);
Chris@14 333 $override_exists = FALSE;
Chris@14 334 if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
Chris@14 335 $override_exists = NestedArray::keyExists($this->moduleOverrides, $parts);
Chris@14 336 }
Chris@14 337 if (!$override_exists && isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
Chris@14 338 $override_exists = NestedArray::keyExists($this->settingsOverrides, $parts);
Chris@14 339 }
Chris@14 340 return $override_exists;
Chris@14 341 }
Chris@14 342 }
Chris@14 343
Chris@0 344 }