Spin off from
#2426509: ContentEntityBase::__set() messes with values that happen to be TypedData →
ContentEntityBase::__set(), ItemList::set() and FieldItemBase::__set() all have special logic to downcast assigned values that happen to be a TypedDataInterface to their ->getValue() array before assigning it.
The exact intent of that at each level is not fully clear.
- In ContentEntityBase::__set(), this allows easy copying of field values :
$e1->field = $e2->field; // does: $e1->field->setValue($e2->field->getValue())
(we copy the values, but don't actually reuse the same FieldItemList object)
--> @fago suggested we limit that behavior to FieldItemListInterface instead of "anything that is a TypedData".
Anything else gets passed as is to ItemList->setValue(), and if not an array, gets assigned to the first property of the first item.
- In ItemList::offsetSet()/set(), this allows easy copying of item values:
$e1->field[0] = $e2->field[1]; // does: $e1->field[0]->setValue($e2->field[1]->getValue())
--> Similarly, do we want FieldItemList to override that and limit that behavior to FieldItemInterface ?
- In FieldItemBase::__set(), well, it's not clear to me what this one is for, nor what it allows or forbids :-)
--> Do we want to keep it ?
--> If we do, then by the same reasoning than
#2426509: ContentEntityBase::__set() messes with values that happen to be TypedData →
, it seems that behavior should only be applied to the "official properties" in the FieldItem, not to arbitrary runtime properties
--> What is done there is "downcast if TypedDataInterface **and not EntityInterface**". That part about EntityInterface is moot now, since Entities ar not TypedData anymore.