Problem/Motivation

Reverting a Display Builder entity view override to its default display has two bugs:
Bug 1 — PHP fatal error:
Error: Call to undefined method
Drupal\display_builder_entity_view\Entity\LayoutBuilderEntityViewDisplay::getSources()
at DisplayBuilderSubscriber::onRevert() line 77.
The subscriber loads a display entity and tries to call getSources() on it, but that method belongs to the DisplayBuildableInterface plugin, not the display entity itself.
What the code does:

$display = $this->entityTypeManager->getStorage('entity_view_display')->load($config['display_id']);
$instance->setNewPresent($display->getSources(), 'Revert 2/2');
//                             ^^^^^^^^^^ — LayoutBuilderEntityViewDisplay has no getSources()

Bug 2 — UI not refreshed (caused by subscriber ordering):
Even after fixing the fatal error (by reading the third-party setting directly instead), the builder UI still shows the old overridden layout after revert. A full page reload reveals the correct state.
The root cause is that ApiPublishingController::revert() dispatches DisplayBuilderEvents::ON_REVERT before mutating the instance. Two event subscribers listen with equal priority (0):

  • 1. DisplayBuilderEventsSubscriber::onRevert() — dispatches to islands, which call $instance->getCurrentState() and generate OOB swap responses with stale data
  • 2. DisplayBuilderEntityView\DisplayBuilderSubscriber::onRevert() — clears the entity override field and reloads sources from the base display config

Because both have priority 0, execution order depends on container compilation order (module weight). In most cases the islands read the instance before the revert logic runs, producing OOB swaps with stale content. The data is correctly saved to storage, but the UI shows the old state until a full page reload.

Note that publish() and restore() do not have this problem because they both mutate the instance before dispatching their events.

Steps to reproduce

Proposed resolution

Move the revert logic out of the event subscriber and into a revert() method on the Instance entity, called by the controller before dispatching ON_REVERT. This follows the same pattern as publish() and restore().

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ipumpkin created an issue. See original summary.

pdureau’s picture

Hello ZiQiang,

What you have started, removing DisplayBuilderSubscriber and triggering the revert from ApiPublishingController::revert() like we already do inother ApiPublishingController methods is the way to go 👍

pdureau’s picture

ipumpkin’s picture

Status: Active » Needs review

@pdureau thanks

mogtofu33’s picture

Status: Needs review » Needs work

I think it needs rebase + fix phpstan error, and eventually related tests.

mogtofu33’s picture

ipumpkin’s picture

Status: Needs work » Needs review
mogtofu33’s picture

Assigned: Unassigned » mogtofu33
Status: Needs review » Needs work

I think we are still missing something, as restore after revert is available when it should probably not. And click 'Restore' will delete the override display which is ok, but then the builder is empty.

I check that.

mogtofu33’s picture

Assigned: mogtofu33 » Unassigned
Status: Needs work » Fixed

Seems it needs more for the Restore problem, created #3613399: Entity override Revert -> Restore logic to not block this fix for release.

Thanks for the work.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • mogtofu33 committed a3ad186e on 1.0.x authored by ipumpkin
    fix: #3612675 Revert is broken: PHP error + UI not refreshed
    
    By:...