Chris@0: name; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the name of this configuration object. Chris@0: * Chris@0: * @param string $name Chris@0: * The name of the configuration object. Chris@0: * Chris@0: * @return $this Chris@0: * The configuration object. Chris@0: */ Chris@0: public function setName($name) { Chris@0: $this->name = $name; Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Validates the configuration object name. Chris@0: * Chris@0: * @param string $name Chris@0: * The name of the configuration object. Chris@0: * Chris@0: * @throws \Drupal\Core\Config\ConfigNameException Chris@0: * Chris@0: * @see Config::MAX_NAME_LENGTH Chris@0: */ Chris@0: public static function validateName($name) { Chris@0: // The name must be namespaced by owner. Chris@0: if (strpos($name, '.') === FALSE) { Chris@0: throw new ConfigNameException("Missing namespace in Config object name $name."); Chris@0: } Chris@0: // The name must be shorter than Config::MAX_NAME_LENGTH characters. Chris@0: if (strlen($name) > self::MAX_NAME_LENGTH) { Chris@0: throw new ConfigNameException("Config object name $name exceeds maximum allowed length of " . static::MAX_NAME_LENGTH . " characters."); Chris@0: } Chris@0: Chris@0: // The name must not contain any of the following characters: Chris@0: // : ? * < > " ' / \ Chris@0: if (preg_match('/[:?*<>"\'\/\\\\]/', $name)) { Chris@0: throw new ConfigNameException("Invalid character in Config object name $name."); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets data from this configuration object. Chris@0: * Chris@0: * @param string $key Chris@0: * A string that maps to a key within the configuration data. Chris@0: * For instance in the following configuration array: Chris@0: * @code Chris@0: * array( Chris@0: * 'foo' => array( Chris@0: * 'bar' => 'baz', Chris@0: * ), Chris@0: * ); Chris@0: * @endcode Chris@0: * A key of 'foo.bar' would return the string 'baz'. However, a key of 'foo' Chris@0: * would return array('bar' => 'baz'). Chris@0: * If no key is specified, then the entire data array is returned. Chris@0: * Chris@0: * @return mixed Chris@0: * The data that was requested. Chris@0: */ Chris@0: public function get($key = '') { Chris@0: if (empty($key)) { Chris@0: return $this->data; Chris@0: } Chris@0: else { Chris@0: $parts = explode('.', $key); Chris@0: if (count($parts) == 1) { Chris@0: return isset($this->data[$key]) ? $this->data[$key] : NULL; Chris@0: } Chris@0: else { Chris@0: $value = NestedArray::getValue($this->data, $parts, $key_exists); Chris@0: return $key_exists ? $value : NULL; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Replaces the data of this configuration object. Chris@0: * Chris@0: * @param array $data Chris@0: * The new configuration data. Chris@0: * Chris@0: * @return $this Chris@0: * The configuration object. Chris@0: * Chris@0: * @throws \Drupal\Core\Config\ConfigValueException Chris@0: * If any key in $data in any depth contains a dot. Chris@0: */ Chris@0: public function setData(array $data) { Chris@0: $data = $this->castSafeStrings($data); Chris@0: $this->validateKeys($data); Chris@0: $this->data = $data; Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets a value in this configuration object. Chris@0: * Chris@0: * @param string $key Chris@0: * Identifier to store value in configuration. Chris@0: * @param mixed $value Chris@0: * Value to associate with identifier. Chris@0: * Chris@0: * @return $this Chris@0: * The configuration object. Chris@0: * Chris@0: * @throws \Drupal\Core\Config\ConfigValueException Chris@0: * If $value is an array and any of its keys in any depth contains a dot. Chris@0: */ Chris@0: public function set($key, $value) { Chris@0: $value = $this->castSafeStrings($value); Chris@0: // The dot/period is a reserved character; it may appear between keys, but Chris@0: // not within keys. Chris@0: if (is_array($value)) { Chris@0: $this->validateKeys($value); Chris@0: } Chris@0: $parts = explode('.', $key); Chris@0: if (count($parts) == 1) { Chris@0: $this->data[$key] = $value; Chris@0: } Chris@0: else { Chris@0: NestedArray::setValue($this->data, $parts, $value); Chris@0: } Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Validates all keys in a passed in config array structure. Chris@0: * Chris@0: * @param array $data Chris@0: * Configuration array structure. Chris@0: * Chris@0: * @return null Chris@0: * Chris@0: * @throws \Drupal\Core\Config\ConfigValueException Chris@0: * If any key in $data in any depth contains a dot. Chris@0: */ Chris@0: protected function validateKeys(array $data) { Chris@0: foreach ($data as $key => $value) { Chris@0: if (strpos($key, '.') !== FALSE) { Chris@0: throw new ConfigValueException("$key key contains a dot which is not supported."); Chris@0: } Chris@0: if (is_array($value)) { Chris@0: $this->validateKeys($value); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Unsets a value in this configuration object. Chris@0: * Chris@0: * @param string $key Chris@0: * Name of the key whose value should be unset. Chris@0: * Chris@0: * @return $this Chris@0: * The configuration object. Chris@0: */ Chris@0: public function clear($key) { Chris@0: $parts = explode('.', $key); Chris@0: if (count($parts) == 1) { Chris@0: unset($this->data[$key]); Chris@0: } Chris@0: else { Chris@0: NestedArray::unsetValue($this->data, $parts); Chris@0: } Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Merges data into a configuration object. Chris@0: * Chris@0: * @param array $data_to_merge Chris@0: * An array containing data to merge. Chris@0: * Chris@0: * @return $this Chris@0: * The configuration object. Chris@0: */ Chris@0: public function merge(array $data_to_merge) { Chris@0: // Preserve integer keys so that configuration keys are not changed. Chris@0: $this->setData(NestedArray::mergeDeepArray([$this->data, $data_to_merge], TRUE)); Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getCacheContexts() { Chris@0: return $this->cacheContexts; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getCacheTags() { Chris@0: return Cache::mergeTags(['config:' . $this->name], $this->cacheTags); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getCacheMaxAge() { Chris@0: return $this->cacheMaxAge; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Casts any objects that implement MarkupInterface to string. Chris@0: * Chris@0: * @param mixed $data Chris@0: * The configuration data. Chris@0: * Chris@0: * @return mixed Chris@0: * The data with any safe strings cast to string. Chris@0: */ Chris@0: protected function castSafeStrings($data) { Chris@0: if ($data instanceof MarkupInterface) { Chris@0: $data = (string) $data; Chris@0: } Chris@0: elseif (is_array($data)) { Chris@0: array_walk_recursive($data, function (&$value) { Chris@0: if ($value instanceof MarkupInterface) { Chris@0: $value = (string) $value; Chris@0: } Chris@0: }); Chris@0: } Chris@0: return $data; Chris@0: } Chris@0: Chris@0: }