You are here

public function Blocks::execute in Context 8

Same name and namespace in other branches
  1. 8.4 src/Plugin/ContextReaction/Blocks.php \Drupal\context\Plugin\ContextReaction\Blocks::execute()
  2. 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

Overrides ExecutableInterface::execute

File

src/Plugin/ContextReaction/Blocks.php, line 141

Class

Blocks
Provides a content reaction that will let you place blocks in the current themes regions.

Namespace

Drupal\context\Plugin\ContextReaction

Code

public function execute(array $build = array(), $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);
      }

      // Make sure the user is allowed to view the block.
      $access = $block
        ->access($this->account, TRUE);
      $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);
      }

      // Inject runtime contexts.
      if ($block instanceof ContextAwarePluginInterface) {
        $contexts = $this->contextRepository
          ->getRuntimeContexts($block
          ->getContextMapping());
        $this->contextHandler
          ->applyContextMapping($block, $contexts);
      }

      // Create the render array for the block as a whole.
      // @see template_preprocess_block().
      $blockBuild = [
        '#theme' => 'block',
        '#attributes' => [
          'class' => [
            $configuration['css_class'],
          ],
        ],
        '#configuration' => $configuration,
        '#plugin_id' => $block
          ->getPluginId(),
        '#base_plugin_id' => $block
          ->getBaseId(),
        '#derivative_plugin_id' => $block
          ->getDerivativeId(),
        '#id' => $block
          ->getConfiguration()['custom_id'],
        '#block_plugin' => $block,
        '#pre_render' => [
          [
            $this,
            'preRenderBlock',
          ],
        ],
        '#cache' => [
          'keys' => [
            'context_blocks_reaction',
            'block',
            $block_placement_key,
          ],
          'tags' => $block
            ->getCacheTags(),
          'contexts' => $block
            ->getCacheContexts(),
          'max-age' => $block
            ->getCacheMaxAge(),
        ],
      ];

      // Add contextual links to block.
      $content = $block
        ->build();
      if (isset($content['#contextual_links'])) {
        $blockBuild['#contextual_links'] = $content['#contextual_links'];
      }

      // Add additional contextual link, for editing block configuration.
      $blockBuild['#contextual_links']['context_block'] = [
        'route_parameters' => [
          'context' => $configuration['context_id'],
          'reaction_id' => 'blocks',
          'block_id' => $block
            ->getConfiguration()['uuid'],
        ],
      ];
      if (array_key_exists('weight', $configuration)) {
        $blockBuild['#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(),
      ], $blockBuild, $block);
      $build[$region][$block_placement_key] = $blockBuild;

      // 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;
}