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

hudri created an issue. See original summary.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.1.10 (June 4, 2021) and Drupal 9.2.10 (November 24, 2021) were the last bugfix releases of those minor version series. Drupal 9 bug reports should be targeted for the 9.3.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ro-no-lo’s picture

It 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.

hudri’s picture

...but also want to have an image blank state, in which case usually the default image should be used

Absolutely 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.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.