Problem/Motivation
I am using Custom Field as a light version of Paragraphs to store headings/text/images, and using Migrate to populate this data from another CMS. When I have an image field, the image is optional (ie. not always populated), and I am migrating multiple entities, it is possible for the second entity onwards to be corrupted and store the incorrect file ID. This is due to cache corruption inside TypedDataManager.
To improve performance TypedDataManager::getPropertyInstance()
stores prototypes of each possible field item. In my case the prototype key is entity:node:article:field_image_and_text.1:image
- this is the image on delta 1 of my field_image_and_text
field.
The prototype is constructed and CustomImageField::__construct() is called. This also calls
$this->value = $parent->{$this->getName()};
which copies the value from the parent typed data item. This value is an array containing the entity ID and alt text from the first image.
However, this then corrupts the prototype cache, and this value is cloned to subsequent entities that use this typed data object. When this is later saved to the database, the array is cast to an integer 1, and you end up with file ID 1 being output.
This is an edge case that probably doesn't outside of Migrate: you need to be creating multiple entities in the same request, one with an image at a particular delta, then a later entity without an image in the same delta.
Steps to reproduce
See above!
Proposed resolution
Remove this line from CustomImageField::__construct()
$this->value = $parent->{$this->getName()};
Remaining tasks
Are there any other custom image data types that are affected by this?
User interface changes
API changes
Data model changes