f6660c4cca6886bdbaed43f8fc1ae27943107848
[yaffs-website] / web / core / lib / Drupal / Core / TypedData / ComputedItemListTrait.php
1 <?php
2
3 namespace Drupal\Core\TypedData;
4
5 /**
6  * Provides common functionality for computed item lists.
7  *
8  * @see \Drupal\Core\TypedData\ListInterface
9  * @see \Drupal\Core\TypedData\Plugin\DataType\ItemList
10  * @see \Drupal\Core\Field\FieldItemListInterface
11  * @see \Drupal\Core\Field\FieldItemList
12  *
13  * @ingroup typed_data
14  */
15 trait ComputedItemListTrait {
16
17   /**
18    * Whether the values have already been computed or not.
19    *
20    * @var bool
21    */
22   protected $valueComputed = FALSE;
23
24   /**
25    * Computes the values for an item list.
26    */
27   abstract protected function computeValue();
28
29   /**
30    * Ensures that values are only computed once.
31    */
32   protected function ensureComputedValue() {
33     if ($this->valueComputed === FALSE) {
34       $this->computeValue();
35       $this->valueComputed = TRUE;
36     }
37   }
38
39   /**
40    * {@inheritdoc}
41    */
42   public function getValue() {
43     $this->ensureComputedValue();
44     return parent::getValue();
45   }
46
47   /**
48    * {@inheritdoc}
49    */
50   public function setValue($values, $notify = TRUE) {
51     parent::setValue($values, $notify);
52
53     // Make sure that subsequent getter calls do not try to compute the values
54     // again.
55     $this->valueComputed = TRUE;
56   }
57
58   /**
59    * {@inheritdoc}
60    */
61   public function getString() {
62     $this->ensureComputedValue();
63     return parent::getString();
64   }
65
66   /**
67    * {@inheritdoc}
68    */
69   public function get($index) {
70     if (!is_numeric($index)) {
71       throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.');
72     }
73
74     // Unlike the base implementation of
75     // \Drupal\Core\TypedData\ListInterface::get(), we do not add an empty item
76     // automatically because computed item lists need to behave like
77     // non-computed ones. For example, calling isEmpty() on a computed item list
78     // should return TRUE when the values were computed and the item list is
79     // truly empty.
80     // @see \Drupal\Core\TypedData\Plugin\DataType\ItemList::get().
81     $this->ensureComputedValue();
82
83     return isset($this->list[$index]) ? $this->list[$index] : NULL;
84   }
85
86   /**
87    * {@inheritdoc}
88    */
89   public function set($index, $value) {
90     $this->ensureComputedValue();
91     return parent::set($index, $value);
92   }
93
94   /**
95    * {@inheritdoc}
96    */
97   public function appendItem($value = NULL) {
98     $this->ensureComputedValue();
99     return parent::appendItem($value);
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   public function removeItem($index) {
106     $this->ensureComputedValue();
107     return parent::removeItem($index);
108   }
109
110   /**
111    * {@inheritdoc}
112    */
113   public function isEmpty() {
114     $this->ensureComputedValue();
115     return parent::isEmpty();
116   }
117
118   /**
119    * {@inheritdoc}
120    */
121   public function offsetExists($offset) {
122     $this->ensureComputedValue();
123     return parent::offsetExists($offset);
124   }
125
126   /**
127    * {@inheritdoc}
128    */
129   public function getIterator() {
130     $this->ensureComputedValue();
131     return parent::getIterator();
132   }
133
134   /**
135    * {@inheritdoc}
136    */
137   public function count() {
138     $this->ensureComputedValue();
139     return parent::count();
140   }
141
142   /**
143    * {@inheritdoc}
144    */
145   public function applyDefaultValue($notify = TRUE) {
146     // Default values do not make sense for computed item lists. However, this
147     // method can be overridden if needed.
148     return $this;
149   }
150
151 }