diff --git a/core/lib/Drupal/Core/Block/BlockBase.php b/core/lib/Drupal/Core/Block/BlockBase.php index ba1026b55649827f7f378cce0be0a335120fb0a8..68745432a3dae12e2169219ea0e1b77fcc1f6cc2 100644 --- a/core/lib/Drupal/Core/Block/BlockBase.php +++ b/core/lib/Drupal/Core/Block/BlockBase.php @@ -119,7 +119,7 @@ public function calculateDependencies() { /** * {@inheritdoc} */ - public function access(AccountInterface $account) { + public function access(AccountInterface $account, $return_as_object = FALSE) { // @todo Remove self::blockAccess() and force individual plugins to return // their own AccessResult logic. Until that is done in // https://www.drupal.org/node/2375689 the access will be set uncacheable. @@ -129,7 +129,9 @@ public function access(AccountInterface $account) { else { $access = AccessResult::forbidden(); } - return $access->setCacheable(FALSE); + + $access->setCacheable(FALSE); + return $return_as_object ? $access : $access->isAllowed(); } /** diff --git a/core/lib/Drupal/Core/Block/BlockPluginInterface.php b/core/lib/Drupal/Core/Block/BlockPluginInterface.php index a42027e10c53c2e6524228b3852459024b5e4bb8..10ec23ef2c32e33c273369fd635ce8cb3a2cea58 100644 --- a/core/lib/Drupal/Core/Block/BlockPluginInterface.php +++ b/core/lib/Drupal/Core/Block/BlockPluginInterface.php @@ -46,13 +46,19 @@ public function label(); * * @param \Drupal\Core\Session\AccountInterface $account * The user session for which to check access. + * @param bool $return_as_object + * (optional) Defaults to FALSE. * - * @return \Drupal\Core\Access\AccessResultInterface - * An access result object instantiated and configured by the block plugin. + * @return bool|\Drupal\Core\Access\AccessResultInterface + * The access result. Returns a boolean if $return_as_object is FALSE (this + * is the default) and otherwise an AccessResultInterface object. + * When a boolean is returned, the result of AccessInterface::isAllowed() is + * returned, i.e. TRUE means access is explicitly allowed, FALSE means + * access is either explicitly forbidden or "no opinion". * * @see \Drupal\block\BlockAccessControlHandler */ - public function access(AccountInterface $account); + public function access(AccountInterface $account, $return_as_object = FALSE); /** * Builds and returns the renderable array for this block plugin. diff --git a/core/modules/block/src/BlockAccessControlHandler.php b/core/modules/block/src/BlockAccessControlHandler.php index 6160f84bb01f8b79e8682dc63eb94be0abd221be..6ec53f67eab36f26b3ce48323f1a10292e92fec3 100644 --- a/core/modules/block/src/BlockAccessControlHandler.php +++ b/core/modules/block/src/BlockAccessControlHandler.php @@ -100,7 +100,7 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A } if ($this->resolveConditions($conditions, 'and') !== FALSE) { // Delegate to the plugin. - $access = $entity->getPlugin()->access($account); + $access = $entity->getPlugin()->access($account, TRUE); } else { $access = AccessResult::forbidden(); diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php index 53d1e5736aa336528266427d211bee7907b41d63..5c8d900dfd4080d086d73519fd7d34082c95afd3 100644 --- a/core/modules/block/src/Tests/BlockTest.php +++ b/core/modules/block/src/Tests/BlockTest.php @@ -436,4 +436,18 @@ public function testUninstallTheme() { $this->assertIdentical(NULL, Block::load($block->id())); } + /** + * Tests the block access. + */ + public function testBlockAccess() { + $this->drupalPlaceBlock('test_access', ['region' => 'help']); + + $this->drupalGet('<front>'); + $this->assertNoText('Hello test world'); + + \Drupal::state()->set('test_block_access', TRUE); + $this->drupalGet('<front>'); + $this->assertText('Hello test world'); + } + } diff --git a/core/modules/block/src/Tests/BlockTestBase.php b/core/modules/block/src/Tests/BlockTestBase.php index 0aabffaa5349edc17b6058ac805b6c7b2e7b8b1c..1f3cb74c2e508ce4da12655400d087323ea8c5ba 100644 --- a/core/modules/block/src/Tests/BlockTestBase.php +++ b/core/modules/block/src/Tests/BlockTestBase.php @@ -19,7 +19,7 @@ abstract class BlockTestBase extends WebTestBase { * * @var array */ - public static $modules = array('block', 'filter', 'test_page_test', 'help'); + public static $modules = array('block', 'filter', 'test_page_test', 'help', 'block_test'); /** * A list of theme regions to test. diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php new file mode 100644 index 0000000000000000000000000000000000000000..b3ed511e7b0b00047a8d9dc545ce5608a6724dc9 --- /dev/null +++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php @@ -0,0 +1,82 @@ +<?php + +/** + * @file + * Contains \Drupal\block_test\Plugin\Block\TestAccessBlock. + */ + +namespace Drupal\block_test\Plugin\Block; + +use Drupal\Core\Block\BlockBase; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Session\AccountInterface; +use Drupal\Core\State\StateInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Provides a block to test access. + * + * @Block( + * id = "test_access", + * admin_label = @Translation("Test block access") + * ) + */ +class TestAccessBlock extends BlockBase implements ContainerFactoryPluginInterface { + + /** + * Tests the test access block. + * + * + * @param array $configuration + * The plugin configuration, i.e. an array with configuration values keyed + * by configuration option name. The special key 'context' may be used to + * initialize the defined contexts by setting it to an array of context + * values keyed by context names. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\State\StateInterface $state + * The state. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, StateInterface $state) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + + $this->state = $state; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('state') + ); + } + + /** + * {@inheritdoc} + */ + protected function blockAccess(AccountInterface $account) { + return $this->state->get('test_block_access', FALSE); + } + + /** + * {@inheritdoc} + */ + public function build() { + return ['#markup' => 'Hello test world']; + } + + /** + * {@inheritdoc} + */ + public function isCacheable() { + return TRUE; + } + +} +