public function Blocks::execute in Context 8.4
Same name and namespace in other branches
- 8 src/Plugin/ContextReaction/Blocks.php \Drupal\context\Plugin\ContextReaction\Blocks::execute()
- 8.0 src/Plugin/ContextReaction/Blocks.php \Drupal\context\Plugin\ContextReaction\Blocks::execute()
Executes the plugin.
Parameters
array $build: The current build of the page.
string|null $title: The page title.
string|null $main_content: The main page content.
Return value
array Blocks that will be built.
Overrides ExecutableInterface::execute
File
- src/
Plugin/ ContextReaction/ Blocks.php, line 186
Class
- Blocks
- Provides a content reaction.
Namespace
Drupal\context\Plugin\ContextReactionCode
public function execute(array $build = [], $title = NULL, $main_content = NULL) {
$cacheability = CacheableMetadata::createFromRenderArray($build);
// Use the currently active theme to fetch blocks.
$theme = $this->themeManager
->getActiveTheme()
->getName();
$regions = $this
->getBlocks()
->getAllByRegion($theme);
// Add each block to the page build.
foreach ($regions as $region => $blocks) {
/** @var $blocks BlockPluginInterface[] */
foreach ($blocks as $block_id => $block) {
$configuration = $block
->getConfiguration();
$block_placement_key = $this
->blockShouldBePlacedUniquely($block) ? $block_id : $block
->getConfiguration()['id'];
if ($block instanceof MainContentBlockPluginInterface) {
if (isset($build['content']['system_main'])) {
unset($build['content']['system_main']);
}
$block
->setMainContent($main_content);
}
// Same as Drupal\block\BlockAccessControlHandler::checkAccess().
try {
// Inject runtime contexts.
// Must be before $block->access() to prevent ContextException.
if ($block instanceof ContextAwarePluginInterface) {
$contexts = $this->contextRepository
->getRuntimeContexts($block
->getContextMapping());
$this->contextHandler
->applyContextMapping($block, $contexts);
}
// Make sure the user is allowed to view the block.
$access = $block
->access($this->account, TRUE);
} catch (MissingValueContextException $e) {
// The contexts exist but have no value. Deny access without
// disabling caching.
$access = AccessResult::forbidden();
} catch (ContextException $e) {
// If any context is missing then we might be missing cacheable
// metadata, and don't know based on what conditions the block is
// accessible or not. Make sure the result cannot be cached.
$access = AccessResult::forbidden()
->setCacheMaxAge(0);
}
$cacheability
->addCacheableDependency($access);
// If the user is not allowed then do not render the block.
if (!$access
->isAllowed()) {
continue;
}
if ($block instanceof TitleBlockPluginInterface) {
if (isset($build['content']['messages'])) {
unset($build['content']['messages']);
}
$block
->setTitle($title);
}
$context_entity = $this->entityTypeManager
->getStorage('context')
->load($configuration['context_id']);
// Create the render array for the block as a whole.
// @see template_preprocess_block().
$block_build = [
'#theme' => 'block',
// Must be defined to avoid array merge error in preRender().
'#attributes' => [],
'#configuration' => $configuration,
'#plugin_id' => $block
->getPluginId(),
'#base_plugin_id' => $block
->getBaseId(),
'#derivative_plugin_id' => $block
->getDerivativeId(),
'#id' => $block
->getConfiguration()['custom_id'],
'#block_plugin' => $block,
// Add a block entity with the configuration of the block plugin so
// modules depending on the block property in e.g.
// hook_block_view_alter will still work.
'#block' => Block::create($this->blocks[$block_id] + [
'plugin' => $block
->getPluginId(),
]),
'#pre_render' => [
[
$this,
'preRenderBlock',
],
],
'#cache' => [
'keys' => [
'context_blocks_reaction',
$configuration['context_id'],
'block',
$block_placement_key,
],
'tags' => Cache::mergeTags($block
->getCacheTags(), !empty($context_entity) ? $context_entity
->getCacheTags() : []),
'contexts' => $block
->getCacheContexts(),
'max-age' => $block
->getCacheMaxAge(),
],
];
// Add additional contextual link, for editing block configuration.
$block_build['#contextual_links']['context_block'] = [
'route_parameters' => [
'context' => $configuration['context_id'],
'reaction_id' => 'blocks',
'block_id' => $block
->getConfiguration()['uuid'],
],
];
if (array_key_exists('weight', $configuration)) {
$block_build['#weight'] = $configuration['weight'];
}
// Invoke block_view_alter().
// If an alter hook wants to modify the block contents, it can append
// another #pre_render hook.
\Drupal::moduleHandler()
->alter([
'block_view',
'block_view_' . $block
->getBaseId(),
], $block_build, $block);
// Allow altering of cacheability metadata or setting #create_placeholder.
\Drupal::moduleHandler()
->alter([
'block_build',
"block_build_" . $block
->getBaseId(),
], $block_build, $block);
$build[$region][$block_placement_key] = $block_build;
// After merging with blocks from Block layout, we want to sort all of
// them again.
$build[$region]['#sorted'] = FALSE;
// The main content block cannot be cached: it is a placeholder for the
// render array returned by the controller. It should be rendered as-is,
// with other placed blocks "decorating" it. Analogous reasoning for the
// title block.
if ($block instanceof MainContentBlockPluginInterface || $block instanceof TitleBlockPluginInterface) {
unset($build[$region][$block_placement_key]['#cache']['keys']);
}
$cacheability
->addCacheableDependency($block);
}
}
$cacheability
->applyTo($build);
return $build;
}