Problem/Motivation
As long as the module is installed, \Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay::buildMultiple()
will run for every entity displayed on the site.
The concept of Layout Builder "being enabled" for a given view mode is actually determined by any number of plugins, only 2 of which are provided by core.
This presents a performance hit for cases where the entity is rendered multiple times, or when it is possible to know that no SectionStorage plugin is active.
Proposed resolution
Allow SectionStorage plugins to indicate that they are not relevant for a given entity display (entity type, bundle, and view mode).
Remaining tasks
User interface changes
N/A
API changes
TBD
Data model changes
N/A
Release notes snippet
Original report
We ran into notices on a client site, which result in a combination of content moderation, layout builder, tokens module and pathauto. The notice appeared after saving a new node, and was triggered by token generation of path auto. Problem is that, layout builders builds its sections in \Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay::buildMultiple() - even if it's not enabled.
Another issue / probably a bug is that this triggers entity validation, i.e. when layout builder tries to validate whether a context is satisfied, it validates the entity. Potentially another bug - maybe there is already some issue for it?
This in turn lets the content moderation constraint try to load revision without ID (NULL), what results in the notice. Potentially another bug.
Warning: array_flip(): Can only flip STRING and INTEGER values! in Drupal\Core\Entity\ContentEntityStorageBase->loadMultipleRevisions() (line 584 of core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php).
Drupal\Core\Entity\ContentEntityStorageBase->loadMultipleRevisions(Array) (Line: 551)
Drupal\Core\Entity\ContentEntityStorageBase->loadRevision(NULL) (Line: 156)
Drupal\content_moderation\Plugin\Validation\Constraint\ModerationStateConstraintValidator->getOriginalOrInitialState(Object) (Line: 113)
Drupal\content_moderation\Plugin\Validation\Constraint\ModerationStateConstraintValidator->validate(Object, Object) (Line: 191)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validateConstraints(Object, '00000000438d59cb0000000052d7805e', Array) (Line: 146)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validateNode(Object) (Line: 153)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validateNode(Object, Array, 1) (Line: 99)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validate(Object, Array, NULL) (Line: 90)
Drupal\Core\TypedData\Validation\RecursiveValidator->validate(Object, Array) (Line: 368)
Drupal\Core\Plugin\Context\ContextDefinition->isSatisfiedBy(Object) (Line: 77)
Drupal\Core\Plugin\Context\ContextHandler->Drupal\Core\Plugin\Context\{closure}(Object)
array_filter(Array, Object) (Line: 78)
Drupal\Core\Plugin\Context\ContextHandler->getMatchingContexts(Array, Object) (Line: 65)
Drupal\Core\Plugin\Context\ContextHandler->checkRequirements(Array, Array) (Line: 31)
Drupal\Core\Plugin\Context\ContextHandler->Drupal\Core\Plugin\Context\{closure}(Object)
array_filter(Array, Object) (Line: 37)
Drupal\Core\Plugin\Context\ContextHandler->filterPluginDefinitionsByContexts(Array, Array) (Line: 92)
Drupal\layout_builder\SectionStorage\SectionStorageManager->findByContext(Array, Object) (Line: 297)
Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay->buildSections(Object) (Line: 261)
Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay->buildMultiple(Array) (Line: 28)
Drupal\custom_elements\CustomElementsLayoutBuilderEntityViewDisplay->buildMultiple(Array) (Line: 221)
Drupal\Core\Entity\Entity\EntityViewDisplay->build(Object) (Line: 456)
Drupal\Core\Entity\EntityViewBuilder->viewField(Object, Array) (Line: 243)
Drupal\Core\Field\FieldItemList->view(Array) (Line: 1626)
field_tokens('entity', Array, Array, Array, Object)
call_user_func_array('field_tokens', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('tokens', Array) (Line: 304)
Drupal\Core\Utility\Token->generate('entity', Array, Array, Array, Object) (Line: 941)
token_tokens('node', Array, Array, Array, Object)
call_user_func_array('token_tokens', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('tokens', Array) (Line: 304)
Drupal\Core\Utility\Token->generate('node', Array, Array, Array, Object) (Line: 196)
Drupal\Core\Utility\Token->replace('[node:field_seo_title]', Array, Array, Object) (Line: 212)
Drupal\pathauto\PathautoGenerator->createEntityAlias(Object, 'insert') (Line: 364)
Drupal\pathauto\PathautoGenerator->updateEntityAlias(Object, 'insert') (Line: 86)
pathauto_entity_insert(Object)
call_user_func_array('pathauto_entity_insert', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('entity_insert', Array) (Line: 206)
Drupal\Core\Entity\EntityStorageBase->invokeHook('insert', Object) (Line: 835)
Drupal\Core\Entity\ContentEntityStorageBase->invokeHook('insert', Object) (Line: 526)
Drupal\Core\Entity\EntityStorageBase->doPostSave(Object, ) (Line: 720)
Drupal\Core\Entity\ContentEntityStorageBase->doPostSave(Object, ) (Line: 303)
Drupal\multiversion\Entity\Storage\Sql\NodeStorage->doPostSave(Object, ) (Line: 451)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 838)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object) (Line: 240)
Drupal\multiversion\Entity\Storage\Sql\NodeStorage->save(Object) (Line: 394)
Drupal\Core\Entity\EntityBase->save() (Line: 293)
Drupal\node\NodeForm->save(Array, Object)
call_user_func_array(Array, Array) (Line: 111)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 51)
Anyway, the root of the problem is that layout builder does stuff when it should not, so let's try to fix this here.