Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
The code that needs to figure out whether a deletion is a revert is flawed; taken from EntityAPIControllerExportable::invoke() :
// To ease figuring out whether this is a revert, make sure that the
// entity status is updated in case the providing module has been
// disabled.
if (entity_has_status($this->entityType, $entity, ENTITY_IN_CODE) && !module_exists($entity->{$this->moduleKey})) {
$entity->{$this->statusKey} = ENTITY_CUSTOM;
}
$is_revert = entity_has_status($this->entityType, $entity, ENTITY_IN_CODE);
// ... snip ...
elseif ($hook == 'delete' && !$is_revert) {
field_attach_delete_bundle($type, $entity->{$this->bundleKey});
}
This will not fire if a module (thinking of Features) decides to delete a default entity from its code:
- Feature A contains exportable entities X, Y and Z in code
- Feature A deletes entity Z from its code
- The above code will not flag the entity as ENTITY_CUSTOM because the module still exists
- The above code will flag the deletion as a revert, leaving the fields on the entity which no longer exists
In the Group module, I check for a revert like so; taken from GroupTypeController::delete() :
public function delete($ids, DatabaseTransaction $transaction = NULL) {
$gids = array();
foreach (group_types($ids) as $group_type) {
// If an entity is deleted while it was flagged as ENTITY_IN_CODE, it
// means the entity was either reverted or really deleted. By checking
// for the 'is_rebuild' property, we know it was deleted from within
// _entity_defaults_rebuild() which only deletes the entity if the
// default it came from is no longer available. In any other case, we
// are dealing with a revert or a manual deletion which will only result
// in the entity being rebuilt upon next cache clear.
$entity_in_code = entity_has_status('group_type', $group_type, ENTITY_IN_CODE);
$entity_rebuilt = !empty($group_type->is_rebuild);
// Set this on the group type so other modules can use it.
$group_type->is_revert = $entity_in_code && !$entity_rebuilt;
}
// Delete the group types after setting our flags so those flags are still
// being passed on to other modules implementing hook_group_delete().
parent::delete($ids, $transaction);
}
Perhaps this extra flag should go into EntityAPIControllerExportable::delete()?
Comments
Comment #1
kristiaanvandeneyndeComment #2
kenorb CreditAttribution: kenorb commentedComment #3
kristiaanvandeneyndeJust ran into this one again today :(