From be80816a56c4091eaacab9b10ab52b2799406959 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Tue, 5 Jan 2016 15:02:53 +0900 Subject: [PATCH] Issue #2635238 by dsnopek, tim.plunkett: Contexts not mapped in time to use them in BlockInterface::access() --- .../block/src/BlockAccessControlHandler.php | 17 ++++++++++++++++- core/modules/block/src/Tests/BlockUiTest.php | 2 ++ .../src/Plugin/Block/TestContextAwareBlock.php | 13 +++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/core/modules/block/src/BlockAccessControlHandler.php b/core/modules/block/src/BlockAccessControlHandler.php index 92b54a4ae57b..4529647d6d7f 100644 --- a/core/modules/block/src/BlockAccessControlHandler.php +++ b/core/modules/block/src/BlockAccessControlHandler.php @@ -127,7 +127,22 @@ class BlockAccessControlHandler extends EntityAccessControlHandler implements En } elseif ($this->resolveConditions($conditions, 'and') !== FALSE) { // Delegate to the plugin. - $access = $entity->getPlugin()->access($account, TRUE); + $block_plugin = $entity->getPlugin(); + try { + if ($block_plugin instanceof ContextAwarePluginInterface) { + $contexts = $this->contextRepository->getRuntimeContexts(array_values($block_plugin->getContextMapping())); + $this->contextHandler->applyContextMapping($block_plugin, $contexts); + } + $access = $block_plugin->access($account, TRUE); + } + catch (ContextException $e) { + // Setting access to forbidden if any context is missing for the same + // reasons as with conditions (described in the comment above). + // @todo Avoid setting max-age 0 for some or all cases, for example by + // treating available contexts without value differently in + // https://www.drupal.org/node/2521956. + $access = AccessResult::forbidden()->setCacheMaxAge(0); + } } else { $access = AccessResult::forbidden(); diff --git a/core/modules/block/src/Tests/BlockUiTest.php b/core/modules/block/src/Tests/BlockUiTest.php index 4d0f03a1e1bb..6b5566790780 100644 --- a/core/modules/block/src/Tests/BlockUiTest.php +++ b/core/modules/block/src/Tests/BlockUiTest.php @@ -241,6 +241,7 @@ class BlockUiTest extends WebTestBase { $this->drupalGet(''); $this->assertText('Test context-aware block'); + $this->assertText('User context found.'); $this->assertRaw($expected_text); // Test context mapping allows empty selection for optional contexts. @@ -251,6 +252,7 @@ class BlockUiTest extends WebTestBase { $this->drupalPostForm(NULL, $edit, 'Save block'); $this->drupalGet(''); $this->assertText('No context mapping selected.'); + $this->assertNoText('User context found.'); } /** diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php index 013dbae75b8a..dcb79bdb443c 100644 --- a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php +++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php @@ -8,6 +8,8 @@ namespace Drupal\block_test\Plugin\Block; use Drupal\Core\Block\BlockBase; +use Drupal\Core\Session\AccountInterface; +use Drupal\user\UserInterface; /** * Provides a context-aware block. @@ -35,4 +37,15 @@ class TestContextAwareBlock extends BlockBase { ); } + /** + * {@inheritdoc} + */ + protected function blockAccess(AccountInterface $account) { + if ($this->getContextValue('user') instanceof UserInterface) { + drupal_set_message('User context found.'); + } + + return parent::blockAccess($account); + } + }