Problem/Motivation
The image field currently doesn't store default values provided from field (-storage) config. Instead - if the field is empty - it retrieves the default value on the fly on field formatter level from settings on field level or field storage level. Besides being inconsistent with every other field in core (including entity reference fields), this behavior is really problematic because:
- it is not possible to nullify a default image. Once you attach a default value to an image field, a user can not remove this default value on a single content entity instance at all. Every other field - including entity reference fields - copies the default value to the current entity and then stores it in the DB. This also means that you can remove that default value and the field will stay blank. This is not possible with image fields: There is no option to remove the default value, you can override a default image, but you can not make it empty.
- the logic is on formatter level, which also means that any API on storage level - e.g.
$node->get('field_image')->isEmpty()- returns incorrect values. Same for JSON API, it is not possible to get the default value of an image, a content entity with a default image field returns NULL instead of the default image. A consumer would have to check the field config to get the default value.
Proposed resolution
Completely remove the logic from the formatter, don't compute default values. Store the actual values in the database, even if they are equal to the default value.
There is a related issue (3005528), which tries to move the empty/fallback logic from field widgets into the FieldItemList. This mitigates the 2nd problem, but not the 1st one. For the sake of data integrity the only clean and consistent solution IMHO is to really store the default value in the database on entity creation.
Comments
Comment #5
ro-no-lo commentedIt feels like your issue is turning the "default image" ad absurdum. You want to have it, but also want to have an image blank state, in which case usually the default image should be used.
Comment #6
hudriAbsolutely not. Empty means empty. Period.
The image field should have a default value: When I create a new entity, it should by default be prefilled with this value. When I save the entity, that prefilled default value (and not NULL) has be stored in the database. If I manually remove that prefilled default value before pressing save I want NULL to be stored in the database. This is how every other field in Drupal works, except the image field. This is how a proper data model works.
The image field currently has a computed fallback value, not a default value: When I create a new entity, the image field is prefilled with NULL and incorrectly shows a non-empty value to the user. Subsequently it does not store a real default value, it stores null in the database. Later the field formatter computes a fallback value on the fly. Big difference. That's why the image field is causing all those bugs in JSON API, Metatag, Token module, etc...
Computing a fallback value is part of a custom business logic, doing this in the data storage layer is a major bug.