You are here

public function Blocks::execute in Context 8.0

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

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);
      }
      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' => [],
        '#configuration' => $configuration,
        '#plugin_id' => $block
          ->getPluginId(),
        '#base_plugin_id' => $block
          ->getBaseId(),
        '#derivative_plugin_id' => $block
          ->getDerivativeId(),
        '#block_plugin' => $block,
        '#pre_render' => [
          [
            $this,
            'preRenderBlock',
          ],
        ],
        '#cache' => [
          'keys' => [
            'context_blocks_reaction',
            'block',
            $block_placement_key,
            $block_placement_key,
          ],
          'tags' => $block
            ->getCacheTags(),
          'contexts' => $block
            ->getCacheContexts(),
          'max-age' => $block
            ->getCacheMaxAge(),
        ],
      ];
      if (array_key_exists('weight', $configuration)) {
        $blockBuild['#weight'] = $configuration['weight'];
      }
      $build[$region][$block_placement_key] = $blockBuild;

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