3 namespace Drupal\Core\Config\Schema;
6 * Defines a generic configuration element that contains multiple properties.
8 abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface {
16 * Gets valid configuration data keys.
19 * Array of valid configuration data keys.
21 protected function getAllKeys() {
22 return is_array($this->value) ? array_keys($this->value) : [];
26 * Builds an array of contained elements.
28 * @return \Drupal\Core\TypedData\TypedDataInterface[]
29 * An array of elements contained in this element.
31 protected function parse() {
33 foreach ($this->getAllKeys() as $key) {
34 $value = isset($this->value[$key]) ? $this->value[$key] : NULL;
35 $definition = $this->getElementDefinition($key);
36 $elements[$key] = $this->createElement($definition, $value, $key);
42 * Gets data definition object for contained element.
44 * @param int|string $key
45 * Property name or index of the element.
47 * @return \Drupal\Core\TypedData\DataDefinitionInterface
49 protected abstract function getElementDefinition($key);
54 public function get($name) {
55 $parts = explode('.', $name);
56 $root_key = array_shift($parts);
57 $elements = $this->getElements();
58 if (isset($elements[$root_key])) {
59 $element = $elements[$root_key];
60 // If $property_name contained a dot recurse into the keys.
61 while ($element && ($key = array_shift($parts)) !== NULL) {
62 if ($element instanceof TypedConfigInterface) {
63 $element = $element->get($key);
70 if (isset($element)) {
74 throw new \InvalidArgumentException("The configuration property $name doesn't exist.");
81 public function getElements() {
82 if (!isset($this->elements)) {
83 $this->elements = $this->parse();
85 return $this->elements;
91 public function isEmpty() {
92 return empty($this->value);
98 public function toArray() {
99 return isset($this->value) ? $this->value : [];
105 public function onChange($name) {
106 // Notify the parent of changes.
107 if (isset($this->parent)) {
108 $this->parent->onChange($this->name);
115 public function getIterator() {
116 return new \ArrayIterator($this->getElements());
120 * Creates a contained typed configuration object.
122 * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
123 * The data definition object.
124 * @param mixed $value
125 * (optional) The data value. If set, it has to match one of the supported
126 * data type format as documented for the data type classes.
128 * The key of the contained element.
130 * @return \Drupal\Core\TypedData\TypedDataInterface
132 protected function createElement($definition, $value, $key) {
133 return $this->getTypedDataManager()->create($definition, $value, $key, $this);
137 * Creates a new data definition object from a type definition array and
138 * actual configuration data.
140 * @param array $definition
141 * The base type definition array, for which a data definition should be
144 * The value of the configuration element.
146 * The key of the contained element.
148 * @return \Drupal\Core\TypedData\DataDefinitionInterface
150 protected function buildDataDefinition($definition, $value, $key) {
151 return $this->getTypedDataManager()->buildDataDefinition($definition, $value, $key, $this);
155 * Determines if this element allows NULL as a value.
158 * TRUE if NULL is a valid value, FALSE otherwise.
160 public function isNullable() {
161 return isset($this->definition['nullable']) && $this->definition['nullable'] == TRUE;