Question

After upgrading a site to Drupal 9, I started seeing the following error when visiting the site:

Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException: The entity type banner does not have an "revision_created" entity revision metadata key. in Drupal\Core\Entity\RevisionableContentEntityBase::revisionLogBaseFieldDefinitions() (line 35 of core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php).

The site has a custom entity, banner.

I rolled back to Drupal 8.9, created a module to make the same entity revisionable, and added the following code in module.install.

/**
 * Implements hook_update_dependencies().
 */
function mirum_entity_revision_update_dependencies() {
  // The update function that adds the status field must run after
  // content_translation_update_8400() which fixes NULL values for the
  // 'content_translation_status' field.
  if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
    $dependencies['mirum_entity_revision'][8400] = [
      'content_translation' => 8400,
    ];

    return $dependencies;
  }
}

/**
 * Add the 'published' and revisionable metadata fields to banner.
 */
function mirum_entity_revision_update_8400() {
  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();

  // Add the published entity key and revisionable metadata fields to the
  // banner entity type.
  $entity_type = $definition_update_manager->getEntityType('banner');
  $entity_type_id = $entity_type->id();

  $entity_keys = $entity_type->getKeys();
  $entity_keys['published'] = 'status';
  $entity_type->set('entity_keys', $entity_keys);

  $revision_metadata_keys = [
    'revision_user' => 'revision_user',
    'revision_created' => 'revision_created',
    'revision_log_message' => 'revision_log_message'
  ];
  $entity_type->set('revision_metadata_keys', $revision_metadata_keys);

  $definition_update_manager->updateEntityType($entity_type);

  // Add the status field.
  $status = BaseFieldDefinition::create('boolean')
    ->setLabel(t('Publishing status'))
    ->setDescription(t('A boolean indicating the published state.'))
    ->setRevisionable(TRUE)
    ->setTranslatable(TRUE)
    ->setDefaultValue(TRUE);

  $has_content_translation_status_field = \Drupal::moduleHandler()->moduleExists('content_translation') && $definition_update_manager->getFieldStorageDefinition('content_translation_status', $entity_type_id);
  if ($has_content_translation_status_field) {
    $status->setInitialValueFromField('content_translation_status');
  }
  else {
    $status->setInitialValue(TRUE);
  }
  $definition_update_manager->installFieldStorageDefinition('status', $entity_type_id, $entity_type_id, $status);

  // Add the revision metadata fields.
  $revision_created = BaseFieldDefinition::create('created')
    ->setLabel(t('Revision create time'))
    ->setDescription(t('The time that the current revision was created.'))
    ->setRevisionable(TRUE);
  $definition_update_manager->installFieldStorageDefinition('revision_created', $entity_type_id, $entity_type_id, $revision_created);

  $revision_user = BaseFieldDefinition::create('entity_reference')
    ->setLabel(t('Revision user'))
    ->setDescription(t('The user ID of the author of the current revision.'))
    ->setSetting('target_type', 'user')
    ->setRevisionable(TRUE);
  $definition_update_manager->installFieldStorageDefinition('revision_user', $entity_type_id, $entity_type_id, $revision_user);

  $revision_log_message = BaseFieldDefinition::create('string_long')
    ->setLabel(t('Revision log message'))
    ->setDescription(t('Briefly describe the changes you have made.'))
    ->setRevisionable(TRUE)
    ->setDefaultValue('')
    ->setDisplayOptions('form', [
      'type' => 'string_textarea',
      'weight' => 25,
      'settings' => [
        'rows' => 4,
      ],
    ]);
  $definition_update_manager->installFieldStorageDefinition('revision_log_message', $entity_type_id, $entity_type_id, $revision_log_message);

  // Uninstall the 'content_translation_status' field if needed.
  $database = \Drupal::database();
  if ($has_content_translation_status_field) {
    // First we have to remove the field data.
    $database->update($entity_type->getDataTable())
      ->fields(['content_translation_status' => NULL])
      ->execute();

    // A site may have disabled revisionability for this entity type.
    if ($entity_type->isRevisionable()) {
      $database->update($entity_type->getRevisionDataTable())
        ->fields(['content_translation_status' => NULL])
        ->execute();
    }

    $content_translation_status = $definition_update_manager->getFieldStorageDefinition('content_translation_status', $entity_type_id);
    $definition_update_manager->uninstallFieldStorageDefinition($content_translation_status);
  }

  return t('@entity_type_label has been converted to revisionable and publishable.', ['@entity_type_label' => $entity_type->getLabel()]);
}

I activated the module and upgraded again to Drupal 9, but the error persists.

I am using Drush and Composer but because of this error with the entity, none of the Drush commands work.

For example, running drush cr returns the following error.

The entity type banner does not have an "revision_created" entity revision metadata key.

Était-ce utile?

La solution

You have set the missing metakey already in the update hook, but this is not stored in the entity definitions permanently, this is only temporary for the update process:

  $revision_metadata_keys = [
    'revision_user' => 'revision_user',
    'revision_created' => 'revision_created',
    'revision_log_message' => 'revision_log_message'
  ];
  $entity_type->set('revision_metadata_keys', $revision_metadata_keys);

For this you need to include them in the entity annotations:

/mymodule/src/Entity/Banner.php

 * @ContentEntityType(
 *   id = "banner",
 *   ...
 *   revision_metadata_keys = {
 *     "revision_user" = "revision_user",
 *     "revision_created" = "revision_created",
 *     "revision_log_message" = "revision_log_message",
 *   },

Then the command drush cr should update the entity definition without error.

Licencié sous: CC-BY-SA avec attribution
Non affilié à drupal.stackexchange
scroll top