diff --git a/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php b/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php index df1fdebfc3..a4034cd941 100644 --- a/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php +++ b/core/modules/layout_builder/src/Entity/LayoutBuilderEntityViewDisplay.php @@ -3,7 +3,6 @@ namespace Drupal\layout_builder\Entity; use Drupal\Core\Cache\CacheableMetadata; -use Drupal\Core\Cache\RefinableCacheableDependencyInterface; use Drupal\Core\Entity\Entity\EntityViewDisplay as BaseEntityViewDisplay; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\FieldableEntityInterface; @@ -53,7 +52,7 @@ public function __construct(array $values, $entity_type) { * {@inheritdoc} */ public function isOverridable() { - return $this->getThirdPartySetting('layout_builder', 'allow_custom', FALSE); + return $this->isLayoutBuilderEnabled() && $this->getThirdPartySetting('layout_builder', 'allow_custom', FALSE); } /** @@ -68,6 +67,10 @@ public function setOverridable($overridable = TRUE) { * {@inheritdoc} */ public function isLayoutBuilderEnabled() { + // Layout Builder cannot be enabled for the custom view mode. + if ($this->getOriginalMode() === static::CUSTOM_MODE) { + return FALSE; + } return (bool) $this->getThirdPartySetting('layout_builder', 'enabled'); } @@ -239,15 +242,13 @@ protected function contextRepository() { */ public function buildMultiple(array $entities) { $build_list = parent::buildMultiple($entities); - if (!$this->isLayoutBuilderEnabled()) { - return $build_list; - } foreach ($entities as $id => $entity) { $build_list[$id]['_layout_builder'] = $this->buildSections($entity); - // If there are any sections, remove all display configurable fields from - // the existing build. + // If there are any sections, remove all fields with configurable display + // from the existing build. These fields are replicated within sections as + // field blocks by ::setComponent(). if (!Element::isEmpty($build_list[$id]['_layout_builder'])) { foreach ($build_list[$id] as $name => $build_part) { $field_definition = $this->getFieldDefinition($name); @@ -316,12 +317,6 @@ protected function getContextsForEntity(FieldableEntityInterface $entity) { * * @param \Drupal\Core\Entity\FieldableEntityInterface $entity * The entity. - * @param \Drupal\Core\Cache\RefinableCacheableDependencyInterface|null $cacheability - * (optional) Refinable cacheability object, which will be populated based - * on the cacheability of each section storage candidate. - * @param \Drupal\Component\Plugin\Context\ContextInterface[] $contexts - * (optional) The contexts which should be used to determine which storage - * to return. * * @return \Drupal\layout_builder\Section[] * The sections. @@ -330,17 +325,13 @@ protected function getContextsForEntity(FieldableEntityInterface $entity) { * \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::findByContext() * should be used instead. See https://www.drupal.org/node/3022574. */ - protected function getRuntimeSections(FieldableEntityInterface $entity, RefinableCacheableDependencyInterface &$cacheability = NULL, array &$contexts = []) { + protected function getRuntimeSections(FieldableEntityInterface $entity) { @trigger_error('\Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay::getRuntimeSections() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::findByContext() should be used instead. See https://www.drupal.org/node/3022574.', E_USER_DEPRECATED); // For backwards compatibility, mimic the functionality of ::buildSections() // by constructing a cacheable metadata object and retrieving the // entity-based contexts. - if (!$cacheability) { - $cacheability = new CacheableMetadata(); - } - if (!$contexts) { - $contexts = $this->getContextsForEntity($entity); - } + $cacheability = new CacheableMetadata(); + $contexts = $this->getContextsForEntity($entity); $storage = $this->sectionStorageManager()->findByContext($contexts, $cacheability); return $storage ? $storage->getSections() : []; } diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php index b18b17767d..928c456abf 100644 --- a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php +++ b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php @@ -456,8 +456,8 @@ public function access($operation, AccountInterface $account = NULL, $return_as_ * {@inheritdoc} */ public function isApplicable(RefinableCacheableDependencyInterface $cacheability) { - // Defaults are always applicable. - return TRUE; + $cacheability->addCacheableDependency($this); + return $this->isLayoutBuilderEnabled(); } } diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php index 138eb69f83..702b667774 100644 --- a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php +++ b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php @@ -31,7 +31,7 @@ * weight = -20, * context_definitions = { * "entity" = @ContextDefinition("entity"), - * "view_mode" = @ContextDefinition("string", required = FALSE), + * "view_mode" = @ContextDefinition("string"), * } * ) * @@ -285,9 +285,7 @@ protected function getEntityTypes() { * {@inheritdoc} */ public function getDefaultSectionStorage() { - // @todo Expand to work for all view modes in - // https://www.drupal.org/node/2907413. - return LayoutBuilderEntityViewDisplay::collectRenderDisplay($this->getEntity(), 'full'); + return LayoutBuilderEntityViewDisplay::collectRenderDisplay($this->getEntity(), $this->getContextValue('view_mode')); } /** diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php index f701c76926..5817ae5dc0 100644 --- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php +++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php @@ -82,6 +82,20 @@ public function testRenderByContextAwarePluginDelegate() { $this->drupalGet('node/1'); $assert_session->pageTextNotContains('Defaults block title'); $assert_session->pageTextContains('Test block title'); + + // Disabling defaults does not prevent the section storage from running. + $this->drupalPostForm('admin/structure/types/manage/bundle_with_section_field/display/default', ['layout[enabled]' => FALSE], 'Save'); + $page->pressButton('Confirm'); + $assert_session->pageTextContains('Layout Builder has been disabled'); + $this->drupalGet('node/1'); + $assert_session->pageTextNotContains('Defaults block title'); + $assert_session->pageTextContains('Test block title'); + + // Disabling the test storage restores the original output. + $this->container->get('state')->set('layout_builder_test_state', FALSE); + $this->drupalGet('node/1'); + $assert_session->pageTextNotContains('Defaults block title'); + $assert_session->pageTextNotContains('Test block title'); } } diff --git a/core/modules/layout_builder/tests/src/Kernel/LayoutBuilderEntityViewDisplayTest.php b/core/modules/layout_builder/tests/src/Kernel/LayoutBuilderEntityViewDisplayTest.php index 7242839dda..d617d3ff5b 100644 --- a/core/modules/layout_builder/tests/src/Kernel/LayoutBuilderEntityViewDisplayTest.php +++ b/core/modules/layout_builder/tests/src/Kernel/LayoutBuilderEntityViewDisplayTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\layout_builder\Kernel; -use Drupal\Core\Cache\RefinableCacheableDependencyInterface; use Drupal\Core\Config\Schema\SchemaIncompleteException; use Drupal\entity_test\Entity\EntityTest; use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; @@ -25,6 +24,7 @@ protected function getSectionStorage(array $section_data) { 'status' => TRUE, 'third_party_settings' => [ 'layout_builder' => [ + 'enabled' => TRUE, 'sections' => $section_data, ], ], @@ -57,24 +57,8 @@ public function testGetRuntimeSections() { $reflection = new \ReflectionMethod($this->sectionStorage, 'getRuntimeSections'); $reflection->setAccessible(TRUE); - $cacheability = NULL; - $contexts = []; - $args = [$entity, &$cacheability, &$contexts]; - $result = $reflection->invokeArgs($this->sectionStorage, $args); + $result = $reflection->invoke($this->sectionStorage, $entity); - $this->assertInstanceOf(RefinableCacheableDependencyInterface::class, $cacheability); - $this->assertSame([], $cacheability->getCacheContexts()); - $this->assertSame([], $cacheability->getCacheTags()); - $this->assertSame(-1, $cacheability->getCacheMaxAge()); - $expected_contexts = [ - 'view_mode' => $this->sectionStorage->getMode(), - 'entity' => $entity, - 'display' => $this->sectionStorage, - ]; - foreach ($expected_contexts as $key => $expected_context) { - $this->assertArrayHasKey($key, $contexts); - $this->assertEquals($expected_context, $contexts[$key]->getContextValue()); - } $this->assertEquals($this->sectionStorage->getSections(), $result); } diff --git a/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php b/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php index cb8a0d35d7..ece8511dfc 100644 --- a/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php +++ b/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php @@ -10,7 +10,6 @@ use Drupal\layout_builder\Section; use Drupal\layout_builder\SectionComponent; use Drupal\layout_builder\SectionListInterface; -use Drupal\layout_builder\SectionStorage\SectionStorageDefinition; /** * @coversDefaultClass \Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage @@ -47,7 +46,8 @@ protected function setUp() { $this->installSchema('system', ['key_value_expire']); $this->installEntitySchema('entity_test'); - $this->plugin = OverridesSectionStorage::create($this->container, [], 'overrides', new SectionStorageDefinition()); + $definition = $this->container->get('plugin.manager.layout_builder.section_storage')->getDefinition('overrides'); + $this->plugin = OverridesSectionStorage::create($this->container, [], 'overrides', $definition); } /** @@ -118,8 +118,13 @@ public function testGetContexts() { $context = EntityContext::fromEntity($entity); $this->plugin->setContext('entity', $context); - $expected = ['entity' => $context]; - $this->assertSame($expected, $this->plugin->getContexts()); + $expected = [ + 'entity', + 'view_mode', + ]; + $result = $this->plugin->getContexts(); + $this->assertEquals($expected, array_keys($result)); + $this->assertSame($context, $result['entity']); } /** @@ -132,8 +137,13 @@ public function testGetContextsDuringPreview() { $context = EntityContext::fromEntity($entity); $this->plugin->setContext('entity', $context); - $expected = ['layout_builder.entity' => $context]; - $this->assertSame($expected, $this->plugin->getContextsDuringPreview()); + $expected = [ + 'view_mode', + 'layout_builder.entity', + ]; + $result = $this->plugin->getContextsDuringPreview(); + $this->assertEquals($expected, array_keys($result)); + $this->assertSame($context, $result['layout_builder.entity']); } /**