3 namespace Drupal\Core\TypedData;
6 * Provides common functionality for computed item lists.
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
15 trait ComputedItemListTrait {
18 * Whether the values have already been computed or not.
22 protected $valueComputed = FALSE;
25 * Computes the values for an item list.
27 abstract protected function computeValue();
30 * Ensures that values are only computed once.
32 protected function ensureComputedValue() {
33 if ($this->valueComputed === FALSE) {
34 $this->computeValue();
35 $this->valueComputed = TRUE;
42 public function getValue() {
43 $this->ensureComputedValue();
44 return parent::getValue();
50 public function setValue($values, $notify = TRUE) {
51 parent::setValue($values, $notify);
53 // Make sure that subsequent getter calls do not try to compute the values
55 $this->valueComputed = TRUE;
61 public function getString() {
62 $this->ensureComputedValue();
63 return parent::getString();
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.');
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
80 // @see \Drupal\Core\TypedData\Plugin\DataType\ItemList::get().
81 $this->ensureComputedValue();
83 return isset($this->list[$index]) ? $this->list[$index] : NULL;
89 public function set($index, $value) {
90 $this->ensureComputedValue();
91 return parent::set($index, $value);
97 public function appendItem($value = NULL) {
98 $this->ensureComputedValue();
99 return parent::appendItem($value);
105 public function removeItem($index) {
106 $this->ensureComputedValue();
107 return parent::removeItem($index);
113 public function isEmpty() {
114 $this->ensureComputedValue();
115 return parent::isEmpty();
121 public function offsetExists($offset) {
122 $this->ensureComputedValue();
123 return parent::offsetExists($offset);
129 public function getIterator() {
130 $this->ensureComputedValue();
131 return parent::getIterator();
137 public function count() {
138 $this->ensureComputedValue();
139 return parent::count();
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.