Saving non-revisionable entities without loading metatags form loses metatags customization

Created on 11 April 2025, about 1 month ago

Problem/Motivation

Data loss for non-revisionable entities if not loading the form by pressing the "Customize meta tags" button.

Warning: Undefined array key "value" in Drupal\metatag_async_widget\Plugin\Field\FieldWidget\AsyncMetatagFirehose->massageFormValues() (line 253 of modules/contrib/metatag_async_widget/src/Plugin/Field/FieldWidget/AsyncMetatagFirehose.php).

The fix from https://www.drupal.org/project/metatag_async_widget/issues/3479093 🐛 Saving nodes without loading metatags form loses metatags customization Active applies default values to the metatag field before saving an entity. For this, the entity is loaded:

if ($this->entityTypeManager->getDefinition($entityType)->isRevisionable()) {
  /** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
  $entity = $storage->loadRevision($entityRevisionID);
}
else {
  $entity = $storage->load($entityID);
}

...and then the existing values are fetched:

// Get current field value from the entity.
if ($originalValues = $entity->get($this->fieldDefinition->getName())->getValue()) {
  $value = $originalValues[$key]['value'];
}

For some reason that escapes me, $originalValues has different structures for revisionable and non-revisionable entities:

  1. an array of original values, if the entity IS revisionable
  2. an array containing an array of original values, if the entity IS NOT revisionable

This is extra weird to me because if we just access the entity from the form object instead of loading it from storage, the value always has the 2nd format regardless if the entity is revisionable or non-revisionable, AND if we test any entity other than the one we're handling at this point (of any entity type) by loading it from storage it will always have the 1st format.

Proposed resolution

Either:

  1. Use loadUnchanged() instead of load() for non-revisionable entities.
  2. Get the entity from $form_state->getFormObject()->getEntity() and accomodate the 2nd format.
🐛 Bug report
Status

Active

Version

1.2

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024