annotate core/lib/Drupal/Core/Config/Config.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents c2387f117808
children
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@16 222 // Potentially configuration schema could have changed the underlying data's
Chris@16 223 // types.
Chris@16 224 $this->resetOverriddenData();
Chris@16 225
Chris@0 226 $this->storage->write($this->name, $this->data);
Chris@0 227 if (!$this->isNew) {
Chris@0 228 Cache::invalidateTags($this->getCacheTags());
Chris@0 229 }
Chris@0 230 $this->isNew = FALSE;
Chris@0 231 $this->eventDispatcher->dispatch(ConfigEvents::SAVE, new ConfigCrudEvent($this));
Chris@0 232 $this->originalData = $this->data;
Chris@0 233 return $this;
Chris@0 234 }
Chris@0 235
Chris@0 236 /**
Chris@0 237 * Deletes the configuration object.
Chris@0 238 *
Chris@0 239 * @return \Drupal\Core\Config\Config
Chris@0 240 * The configuration object.
Chris@0 241 */
Chris@0 242 public function delete() {
Chris@0 243 $this->data = [];
Chris@0 244 $this->storage->delete($this->name);
Chris@0 245 Cache::invalidateTags($this->getCacheTags());
Chris@0 246 $this->isNew = TRUE;
Chris@0 247 $this->resetOverriddenData();
Chris@0 248 $this->eventDispatcher->dispatch(ConfigEvents::DELETE, new ConfigCrudEvent($this));
Chris@0 249 $this->originalData = $this->data;
Chris@0 250 return $this;
Chris@0 251 }
Chris@0 252
Chris@0 253 /**
Chris@0 254 * Gets the raw data without overrides.
Chris@0 255 *
Chris@0 256 * @return array
Chris@0 257 * The raw data.
Chris@0 258 */
Chris@0 259 public function getRawData() {
Chris@0 260 return $this->data;
Chris@0 261 }
Chris@0 262
Chris@0 263 /**
Chris@0 264 * Gets original data from this configuration object.
Chris@0 265 *
Chris@0 266 * Original data is the data as it is immediately after loading from
Chris@0 267 * configuration storage before any changes. If this is a new configuration
Chris@0 268 * object it will be an empty array.
Chris@0 269 *
Chris@0 270 * @see \Drupal\Core\Config\Config::get()
Chris@0 271 *
Chris@0 272 * @param string $key
Chris@0 273 * A string that maps to a key within the configuration data.
Chris@0 274 * @param bool $apply_overrides
Chris@0 275 * Apply any overrides to the original data. Defaults to TRUE.
Chris@0 276 *
Chris@0 277 * @return mixed
Chris@0 278 * The data that was requested.
Chris@0 279 */
Chris@0 280 public function getOriginal($key = '', $apply_overrides = TRUE) {
Chris@0 281 $original_data = $this->originalData;
Chris@0 282 if ($apply_overrides) {
Chris@0 283 // Apply overrides.
Chris@0 284 if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
Chris@0 285 $original_data = NestedArray::mergeDeepArray([$original_data, $this->moduleOverrides], TRUE);
Chris@0 286 }
Chris@0 287 if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
Chris@0 288 $original_data = NestedArray::mergeDeepArray([$original_data, $this->settingsOverrides], TRUE);
Chris@0 289 }
Chris@0 290 }
Chris@0 291
Chris@0 292 if (empty($key)) {
Chris@0 293 return $original_data;
Chris@0 294 }
Chris@0 295 else {
Chris@0 296 $parts = explode('.', $key);
Chris@0 297 if (count($parts) == 1) {
Chris@0 298 return isset($original_data[$key]) ? $original_data[$key] : NULL;
Chris@0 299 }
Chris@0 300 else {
Chris@0 301 $value = NestedArray::getValue($original_data, $parts, $key_exists);
Chris@0 302 return $key_exists ? $value : NULL;
Chris@0 303 }
Chris@0 304 }
Chris@0 305 }
Chris@0 306
Chris@14 307 /**
Chris@14 308 * Determines if overrides are applied to a key for this configuration object.
Chris@14 309 *
Chris@14 310 * @param string $key
Chris@14 311 * (optional) A string that maps to a key within the configuration data.
Chris@14 312 * For instance in the following configuration array:
Chris@14 313 * @code
Chris@14 314 * array(
Chris@14 315 * 'foo' => array(
Chris@14 316 * 'bar' => 'baz',
Chris@14 317 * ),
Chris@14 318 * );
Chris@14 319 * @endcode
Chris@14 320 * A key of 'foo.bar' would map to the string 'baz'. However, a key of 'foo'
Chris@14 321 * would map to the array('bar' => 'baz').
Chris@14 322 * If not supplied TRUE will be returned if there are any overrides at all
Chris@14 323 * for this configuration object.
Chris@14 324 *
Chris@14 325 * @return bool
Chris@14 326 * TRUE if there are any overrides for the key, otherwise FALSE.
Chris@14 327 */
Chris@14 328 public function hasOverrides($key = '') {
Chris@14 329 if (empty($key)) {
Chris@14 330 return !(empty($this->moduleOverrides) && empty($this->settingsOverrides));
Chris@14 331 }
Chris@14 332 else {
Chris@14 333 $parts = explode('.', $key);
Chris@14 334 $override_exists = FALSE;
Chris@14 335 if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
Chris@14 336 $override_exists = NestedArray::keyExists($this->moduleOverrides, $parts);
Chris@14 337 }
Chris@14 338 if (!$override_exists && isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
Chris@14 339 $override_exists = NestedArray::keyExists($this->settingsOverrides, $parts);
Chris@14 340 }
Chris@14 341 return $override_exists;
Chris@14 342 }
Chris@14 343 }
Chris@14 344
Chris@0 345 }