Problem/Motivation
Layout Builder uses "inline blocks" - block content entities that only "exist" within the context of the layout builder entity that contains them. E.g., these blocks are non-reusable and are deleted when the layout builder entity using them is deleted. However, they're not deleted immediately, but instead only when cron runs.
So, there's a period of time where the inline block still exists in the database, but it's parent entity doesn't. In other words, inline blocks are really only "soft deleted" when their parent entity is deleted.
If a soft-deleted inline block is an entity usage source, then the usage report page will throw an exception:
TypeError: Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency::isLayoutCompatibleEntity(): Argument #1 ($entity) must be of type Drupal\Core\Entity\EntityInterface, null given, called in .../docroot/core/modules/layout_builder/src/EventSubscriber/SetInlineBlockDependency.php on line 134 in Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency->isLayoutCompatibleEntity() (line 36 of core/modules/layout_builder/src/LayoutEntityHelperTrait.php).
Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency->getInlineBlockDependency(Object) (Line: 95)
Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency->onGetDependency(Object, 'block_content.get_dependency', Object)
call_user_func(Array, Object, 'block_content.get_dependency', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'block_content.get_dependency') (Line: 92)
Drupal\block_content\BlockContentAccessControlHandler->checkAccess(Object, 'view', Object) (Line: 109)
Drupal\Core\Entity\EntityAccessControlHandler->access(Object, 'view', Object, ) (Line: 739)
Drupal\Core\Entity\ContentEntityBase->access('view label') (Line: 486)
Drupal\entity_usage\Controller\ListUsageController->getSourceEntityLink(Object) (Line: 296)
Drupal\entity_usage\Controller\ListUsageController->getRows('media', '1') (Line: 146)
Drupal\entity_usage\Controller\ListUsageController->listUsagePage('media', '1') (Line: 54)
...
Steps to reproduce
Register an entity usage with an inline block as the source of the usage. Then, delete the layout builder entity that has the block on it, but don't run cron. Visit the usage page for the used entity.
Proposed resolution
A simple solution is when showing the usage row for an inline block, ask the `InlineBlockUsage` service if there's any usage for the block. If there's not, then don't display it. The downside to this approach is that querying the entity_usage table to get a count of usages for an entity is no longer accurate and will include usage counts for the deleted blocks still.
The other solution would be to delete the entity usage tracking data for the soft-deleted block immediately when its parent is deleted. This would involve some additional code in EntityUsage::deleteBySourceEntity
, but I think it might get messy and complex.
Remaining tasks
User interface changes
API changes
Data model changes