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
16 * This trait has been added in Drupal 8.4.3 as an internal helper and should
17 * not be used outside of core.
19 trait ComputedItemListTrait {
22 * Whether the values have already been computed or not.
26 protected $valueComputed = FALSE;
29 * Computes the values for an item list.
31 abstract protected function computeValue();
34 * Ensures that values are only computed once.
36 protected function ensureComputedValue() {
37 if ($this->valueComputed === FALSE) {
38 $this->computeValue();
39 $this->valueComputed = TRUE;
46 public function getValue() {
47 $this->ensureComputedValue();
48 return parent::getValue();
54 public function setValue($values, $notify = TRUE) {
55 parent::setValue($values, $notify);
57 // Make sure that subsequent getter calls do not try to compute the values
59 $this->valueComputed = TRUE;
65 public function getString() {
66 $this->ensureComputedValue();
67 return parent::getString();
73 public function get($index) {
74 if (!is_numeric($index)) {
75 throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.');
78 // Unlike the base implementation of
79 // \Drupal\Core\TypedData\ListInterface::get(), we do not add an empty item
80 // automatically because computed item lists need to behave like
81 // non-computed ones. For example, calling isEmpty() on a computed item list
82 // should return TRUE when the values were computed and the item list is
84 // @see \Drupal\Core\TypedData\Plugin\DataType\ItemList::get().
85 $this->ensureComputedValue();
87 return isset($this->list[$index]) ? $this->list[$index] : NULL;
93 public function set($index, $value) {
94 $this->ensureComputedValue();
95 return parent::set($index, $value);
101 public function appendItem($value = NULL) {
102 $this->ensureComputedValue();
103 return parent::appendItem($value);
109 public function removeItem($index) {
110 $this->ensureComputedValue();
111 return parent::removeItem($index);
117 public function isEmpty() {
118 $this->ensureComputedValue();
119 return parent::isEmpty();
125 public function offsetExists($offset) {
126 $this->ensureComputedValue();
127 return parent::offsetExists($offset);
133 public function getIterator() {
134 $this->ensureComputedValue();
135 return parent::getIterator();
141 public function count() {
142 $this->ensureComputedValue();
143 return parent::count();
149 public function applyDefaultValue($notify = TRUE) {
150 // Default values do not make sense for computed item lists. However, this
151 // method can be overridden if needed.