diff --git a/core/modules/layout_builder/src/Plugin/Field/FieldFormatter/LayoutSectionFormatter.php b/core/modules/layout_builder/src/Plugin/Field/FieldFormatter/LayoutSectionFormatter.php index 5b07008..a21d12c 100644 --- a/core/modules/layout_builder/src/Plugin/Field/FieldFormatter/LayoutSectionFormatter.php +++ b/core/modules/layout_builder/src/Plugin/Field/FieldFormatter/LayoutSectionFormatter.php @@ -8,6 +8,9 @@ use Drupal\Core\Field\FormatterBase; use Drupal\Core\Layout\LayoutPluginManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Plugin\Context\ContextHandlerInterface; +use Drupal\Core\Plugin\Context\ContextRepositoryInterface; +use Drupal\Core\Plugin\ContextAwarePluginInterface; use Drupal\Core\Session\AccountInterface; use Drupal\layout_builder\LayoutSectionItemInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -47,6 +50,20 @@ class LayoutSectionFormatter extends FormatterBase implements ContainerFactoryPl protected $blockManager; /** + * The plugin context handler. + * + * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface + */ + protected $contextHandler; + + /** + * The context manager service. + * + * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface + */ + protected $contextRepository; + + /** * Constructs a LayoutSectionFormatter object. * * @param \Drupal\Core\Session\AccountInterface $account @@ -55,6 +72,10 @@ class LayoutSectionFormatter extends FormatterBase implements ContainerFactoryPl * The layout plugin manager. * @param \Drupal\Core\Block\BlockManagerInterface $blockManager * THe block plugin manager. + * @param \Drupal\Core\Plugin\Context\ContextHandlerInterface $context_handler + * The ContextHandler for applying contexts to conditions properly. + * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository + * The lazy context repository service. * @param string $plugin_id * The plugin ID for the formatter. * @param mixed $plugin_definition @@ -70,10 +91,12 @@ class LayoutSectionFormatter extends FormatterBase implements ContainerFactoryPl * @param array $third_party_settings * Any third party settings. */ - public function __construct(AccountInterface $account, LayoutPluginManagerInterface $layoutPluginManager, BlockManagerInterface $blockManager, $plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings) { + public function __construct(AccountInterface $account, LayoutPluginManagerInterface $layoutPluginManager, BlockManagerInterface $blockManager, ContextHandlerInterface $context_handler, ContextRepositoryInterface $context_repository, $plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings) { $this->account = $account; $this->layoutPluginManager = $layoutPluginManager; $this->blockManager = $blockManager; + $this->contextHandler = $context_handler; + $this->contextRepository = $context_repository; parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); } @@ -85,6 +108,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('current_user'), $container->get('plugin.manager.core.layout'), $container->get('plugin.manager.block'), + $container->get('context.handler'), + $container->get('context.repository'), $plugin_id, $plugin_definition, $configuration['field_definition'], @@ -125,6 +150,10 @@ protected function buildSection(LayoutSectionItemInterface $item) { foreach ($blocks as $uuid => $configuration) { /** @var \Drupal\Core\Block\BlockPluginInterface $block */ $block = $this->blockManager->createInstance($configuration['plugin_id'], $configuration); + if ($block instanceof ContextAwarePluginInterface) { + $contexts = $this->contextRepository->getRuntimeContexts(array_values($block->getContextMapping())); + $this->contextHandler->applyContextMapping($block, $contexts); + } $access = $block->access($this->account, TRUE); if ($access->isAllowed()) { $regions[$region][$uuid] = $block->build(); diff --git a/core/modules/layout_builder/tests/src/Kernel/LayoutSectionFormatterTest.php b/core/modules/layout_builder/tests/src/Kernel/LayoutSectionFormatterTest.php index c391ed9..da5c9b5 100644 --- a/core/modules/layout_builder/tests/src/Kernel/LayoutSectionFormatterTest.php +++ b/core/modules/layout_builder/tests/src/Kernel/LayoutSectionFormatterTest.php @@ -2,12 +2,12 @@ namespace Drupal\Tests\layout_builder\Kernel; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\entity_test\Entity\EntityTest; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\KernelTests\KernelTestBase; +use Drupal\user\Entity\User; /** * Tests the layout section formatter. @@ -19,7 +19,15 @@ class LayoutSectionFormatterTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = ['field', 'layout_builder', 'layout_discovery', 'entity_test', 'user', 'system']; + public static $modules = [ + 'field', + 'layout_builder', + 'layout_discovery', + 'entity_test', + 'user', + 'system', + 'block_test', + ]; /** * The name of the layout section field. @@ -42,11 +50,13 @@ protected function setUp() { parent::setUp(); $this->installConfig(['field']); + $this->installSchema('system', ['sequences']); $this->installEntitySchema('entity_test'); + $this->installEntitySchema('user'); $entity_type = 'entity_test'; $bundle = $entity_type; - $this->fieldName = Unicode::strtolower($this->randomMachineName()); + $this->fieldName = 'field_my_sections'; $field_storage = FieldStorageConfig::create([ 'field_name' => $this->fieldName, @@ -58,7 +68,7 @@ protected function setUp() { $instance = FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => $bundle, - 'label' => $this->randomMachineName(), + 'label' => 'My Sections', ]); $instance->save(); @@ -73,6 +83,13 @@ protected function setUp() { 'settings' => [], ]); $this->display->save(); + + $test_user = User::create([ + 'name' => 'foobar', + 'mail' => 'foobar@example.com', + ]); + $test_user->save(); + $this->container->get('current_user')->setAccount($test_user); } /** @@ -88,22 +105,18 @@ public function testLayoutSectionFormatter($layout_data, $expected_selector, $ex // Build and render the content. $content = $this->display->build($entity); $this->render($content); + // Pass the main content to the assertions to help with debugging. + $main_content = $this->cssSelect('main')[0]->asXML(); // Find the given selector. - if (!is_array($expected_selector)) { - $expected_selector = [$expected_selector]; - } - foreach ($expected_selector as $selector) { + foreach ((array) $expected_selector as $selector) { $element = $this->cssSelect($selector); - $this->assertNotEmpty($element); + $this->assertNotEmpty($element, $main_content); } // Find the given content. - if (!is_array($expected_content)) { - $expected_content = [$expected_content]; - } - foreach ($expected_content as $content) { - $this->assertRaw($content); + foreach ((array) $expected_content as $content) { + $this->assertRaw($content, $main_content); } } @@ -112,60 +125,85 @@ public function testLayoutSectionFormatter($layout_data, $expected_selector, $ex */ public function providerTestLayoutSectionFormatter() { $data = []; - $data[] = [ + $data['block_with_context'] = [ [ [ 'layout' => 'layout_onecol', 'section' => [ 'content' => [ 'baz' => [ - 'plugin_id' => 'system_powered_by_block' - ] - ] - ] + 'plugin_id' => 'test_context_aware', + 'context_mapping' => [ + 'user' => '@user.current_user_context:current_user', + ], + ], + ], + ], + ], + ], + [ + '.layout--onecol', + '#test_context_aware--username', + ], + [ + 'foobar', + 'User context found', + ], + ]; + $data['single_section_single_block'] = [ + [ + [ + 'layout' => 'layout_onecol', + 'section' => [ + 'content' => [ + 'baz' => [ + 'plugin_id' => 'system_powered_by_block', + ], + ], + ], ], ], '.layout--onecol', 'Powered by', ]; - $data[] = [ + $data['multiple_sections'] = [ [ [ 'layout' => 'layout_onecol', 'section' => [ 'content' => [ 'baz' => [ - 'plugin_id' => 'system_powered_by_block' - ] - ] - ] + 'plugin_id' => 'system_powered_by_block', + ], + ], + ], ], [ 'layout' => 'layout_twocol', 'section' => [ 'left' => [ 'foo' => [ - 'plugin_id' => 'test_content', - 'text' => 'foo text' - ] + 'plugin_id' => 'test_block_instantiation', + 'display_message' => 'foo text', + ], ], 'right' => [ 'bar' => [ - 'plugin_id' => 'test_content', - 'text' => 'bar text' - ] - ] - ] - ] + 'plugin_id' => 'test_block_instantiation', + 'display_message' => 'bar text', + ], + ], + ], + ], ], [ '.layout--onecol', - '.layout--twocol' + '.layout--twocol', ], [ 'Powered by', 'foo text', - 'bar text' + 'bar text', ], ]; return $data;