Version 1
[yaffs-website] / web / core / lib / Drupal / Core / Config / Schema / ArrayElement.php
1 <?php
2
3 namespace Drupal\Core\Config\Schema;
4
5 /**
6  * Defines a generic configuration element that contains multiple properties.
7  */
8 abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface {
9
10   /**
11    * Parsed elements.
12    */
13   protected $elements;
14
15   /**
16    * Gets valid configuration data keys.
17    *
18    * @return array
19    *   Array of valid configuration data keys.
20    */
21   protected function getAllKeys() {
22     return is_array($this->value) ? array_keys($this->value) : [];
23   }
24
25   /**
26    * Builds an array of contained elements.
27    *
28    * @return \Drupal\Core\TypedData\TypedDataInterface[]
29    *   An array of elements contained in this element.
30    */
31   protected function parse() {
32     $elements = [];
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);
37     }
38     return $elements;
39   }
40
41   /**
42    * Gets data definition object for contained element.
43    *
44    * @param int|string $key
45    *   Property name or index of the element.
46    *
47    * @return \Drupal\Core\TypedData\DataDefinitionInterface
48    */
49   protected abstract function getElementDefinition($key);
50
51   /**
52    * {@inheritdoc}
53    */
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);
64         }
65         else {
66           $element = NULL;
67         }
68       }
69     }
70     if (isset($element)) {
71       return $element;
72     }
73     else {
74       throw new \InvalidArgumentException("The configuration property $name doesn't exist.");
75     }
76   }
77
78   /**
79    * {@inheritdoc}
80    */
81   public function getElements() {
82     if (!isset($this->elements)) {
83       $this->elements = $this->parse();
84     }
85     return $this->elements;
86   }
87
88   /**
89    * {@inheritdoc}
90    */
91   public function isEmpty() {
92     return empty($this->value);
93   }
94
95   /**
96    * {@inheritdoc}
97    */
98   public function toArray() {
99     return isset($this->value) ? $this->value : [];
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   public function onChange($name) {
106     // Notify the parent of changes.
107     if (isset($this->parent)) {
108       $this->parent->onChange($this->name);
109     }
110   }
111
112   /**
113    * {@inheritdoc}
114    */
115   public function getIterator() {
116     return new \ArrayIterator($this->getElements());
117   }
118
119   /**
120    * Creates a contained typed configuration object.
121    *
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.
127    * @param string $key
128    *   The key of the contained element.
129    *
130    * @return \Drupal\Core\TypedData\TypedDataInterface
131    */
132   protected function createElement($definition, $value, $key) {
133     return $this->getTypedDataManager()->create($definition, $value, $key, $this);
134   }
135
136   /**
137    * Creates a new data definition object from a type definition array and
138    * actual configuration data.
139    *
140    * @param array $definition
141    *   The base type definition array, for which a data definition should be
142    *   created.
143    * @param $value
144    *   The value of the configuration element.
145    * @param string $key
146    *   The key of the contained element.
147    *
148    * @return \Drupal\Core\TypedData\DataDefinitionInterface
149    */
150   protected function buildDataDefinition($definition, $value, $key) {
151     return $this->getTypedDataManager()->buildDataDefinition($definition, $value, $key, $this);
152   }
153
154   /**
155    * Determines if this element allows NULL as a value.
156    *
157    * @return bool
158    *   TRUE if NULL is a valid value, FALSE otherwise.
159    */
160   public function isNullable() {
161     return isset($this->definition['nullable']) && $this->definition['nullable'] == TRUE;
162   }
163
164 }