Commit 38e32224 authored by George's avatar George
Browse files

Issue #3315618, Issue ##3291413 - Add in support for block plugins and misc changes for context.

parent 36a5c2da
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -32,8 +32,10 @@
          if (contextType === 'user') {
            contextArgument = drupalSettings.block_ajax.blocks[blockId].current_user;
          }
          if (contextArgument) {
            ajaxUrl += '/' + contextType + '/' + contextArgument;
          }
        }

        // Setup request.
        let request = $.ajax({
+152 −193
Original line number Diff line number Diff line
@@ -4,12 +4,13 @@ namespace Drupal\block_ajax\Controller;

use Drupal\block\BlockInterface;
use Drupal\block_ajax\BlockViewBuilder;
use Drupal\Component\Plugin\ContextAwarePluginBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\block_ajax\Response\AjaxBlockResponse;
use Drupal\Core\Block\BlockManager;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Utility\Token;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\TermInterface;
@@ -57,6 +58,13 @@ class AjaxBlockController extends ControllerBase {
   */
  protected $token;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $account;

  /**
   * Block Ajax Controller Constructor.
   *
@@ -70,19 +78,23 @@ class AjaxBlockController extends ControllerBase {
   *   Block view builder service.
   * @param \Drupal\Core\Utility\Token $token
   *   The token.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user account.
   */
  public function __construct(
    BlockManager $block_manager,
    RendererInterface $renderer,
    EntityTypeManagerInterface $entity_type_manager,
    BlockViewBuilder $block_view_builder,
    Token $token
    Token $token,
    AccountInterface $account
  ) {
    $this->blockManager = $block_manager;
    $this->renderer = $renderer;
    $this->entityTypeManager = $entity_type_manager;
    $this->blockViewBuilder = $block_view_builder;
    $this->token = $token;
    $this->account = $account;
  }

  /**
@@ -94,89 +106,132 @@ class AjaxBlockController extends ControllerBase {
      $container->get('renderer'),
      $container->get('entity_type.manager'),
      $container->get('block_ajax.block_view_builder'),
      $container->get('token')
      $container->get('token'),
      $container->get('current_user')
    );
  }

  /**
   * Implements ajax block update request handler.
   * Get the block instance.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   * @param string $block_id
   *   The block id.
   *   The block/plugin id.
   * @param array $configuration
   *   The block configuration.
   *
   * @return \Drupal\block_ajax\Response\AjaxBlockResponse
   *   Returns the ajax block response.
   * @return array|null
   *   Returns the block render array/instance.
   *
   * @throws \Drupal\Component\Plugin\Exception\ContextException
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\MissingValueContextException
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function loadBlock(
    Request $request,
    string $block_id
  ): AjaxBlockResponse {
    // Response.
    $response = new AjaxBlockResponse();
  protected function getBlockInstance(Request $request, string $block_id, array $configuration): ?array {
    $blockInstance = NULL;

    // Check for block id.
    if (empty($block_id)) {
      return $response;
    }

    // Load block.
    // Load block by block_id.
    $block = $this->entityTypeManager->getStorage('block')->load($block_id);
    if (!$block instanceof BlockInterface) {
      return $response;
      // Attempt to load block plugin.
      $block_plugin = $this->blockManager->createInstance($block_id, $configuration);
      if ($block_plugin instanceof BlockPluginInterface && 'broken' !== $block_plugin->getPluginId()) {
        // Check access.
        $access = $block_plugin->access($this->account, TRUE);
        if ($access->isAllowed()) {
          $blockInstance = $block_plugin->build();
          $blockInstance['#cache']['tags'] = array_merge($block_plugin->getCacheTags(), ['block_ajax']);
        }

      }
    }
    else {
      // Add in custom cache tag.
      $block->addCacheTags(['block_ajax']);

      // Make sure we have plugin id.
      $plugin_id = $request->get('plugin_id', '');
    if (empty($plugin_id)) {
      return $response;
    }

    // Block configuration.
    $configuration = [];

      if (!empty($plugin_id)) {
        // Check if block has special plugin and add it to dependency.
        $plugin = $block->getPlugin();
        if (is_object($plugin) && $plugin->getPluginId() == $plugin_id) {
          $configuration = $plugin->getConfiguration();
        }

    // Grab any configuration passed in.
    if (empty($configuration)) {
      $configuration = $request->get('config', []);
    }

        // Construct and render the block.
        $blockInstance = $this->blockViewBuilder->build($plugin_id, $configuration, TRUE);
    $renderedBlock = $this->renderer->renderRoot($blockInstance);

    // Apply token replacement.
    $renderedBlock = $this->token->replace($renderedBlock);
      }
    }

    // Clean up ajax links.
    $renderedBlock = str_replace('/block/ajax/' . $block_id, '', trim($renderedBlock));
    return $blockInstance;
  }

    // Set max age.
  /**
   * Set response max age.
   *
   * @param \Drupal\block_ajax\Response\AjaxBlockResponse $response
   *   The ajax response.
   * @param array $configuration
   *   The block configuration.
   */
  protected function setResponseMaxAge(AjaxBlockResponse &$response, array $configuration) {
    $max_age = 0;
    if (isset($configuration['block_ajax']['max_age'])) {
      $max_age = $configuration['block_ajax']['max_age'];
    }
    $response->setMaxAge($max_age);
    $response->setSharedMaxAge($max_age);
  }

  /**
   * Implements ajax block update request handler.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   * @param string $block_id
   *   The block id.
   *
   * @return \Drupal\block_ajax\Response\AjaxBlockResponse
   *   Returns the ajax block response.
   *
   * @throws \Drupal\Component\Plugin\Exception\ContextException
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\MissingValueContextException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException|\Drupal\Component\Plugin\Exception\PluginException
   */
  public function loadBlock(
    Request $request,
    string $block_id
  ): AjaxBlockResponse {
    // Response.
    $response = new AjaxBlockResponse();

    // Check for block id.
    if (empty($block_id)) {
      return $response;
    }

    // Block configuration.
    $configuration = $request->get('config', []);

    // Get block instance.
    if ($blockInstance = $this->getBlockInstance($request, $block_id, $configuration)) {
      $renderedBlock = $this->renderer->renderRoot($blockInstance);

      // Apply token replacement.
      $renderedBlock = $this->token->replace($renderedBlock);

      // Clean up ajax links.
      $renderedBlock = str_replace('/block/ajax/' . $block_id, '', trim($renderedBlock));

      // Set data for response.
      $this->setResponseMaxAge($response, $configuration);
      $response->setData([
        'content' => $renderedBlock,
      ]);
    }

    // Returns response.
    return $response;
@@ -198,7 +253,7 @@ class AjaxBlockController extends ControllerBase {
   * @throws \Drupal\Component\Plugin\Exception\ContextException
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\MissingValueContextException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException|\Drupal\Component\Plugin\Exception\PluginException
   */
  public function loadBlockNodeContext(
    Request $request,
@@ -213,37 +268,11 @@ class AjaxBlockController extends ControllerBase {
      return $response;
    }

    // Load block.
    $block = $this->entityTypeManager->getStorage('block')->load($block_id);
    if (!$block instanceof BlockInterface) {
      return $response;
    }

    // Add in custom cache tag.
    $block->addCacheTags(['block_ajax']);

    // Make sure we have plugin id.
    $plugin_id = $request->get('plugin_id', '');
    if (empty($plugin_id)) {
      return $response;
    }

    // Block configuration.
    $configuration = [];

    // Check if block has special plugin and add it to dependency.
    $plugin = $block->getPlugin();
    if (is_object($plugin) && $plugin->getPluginId() == $plugin_id) {
      $configuration = $plugin->getConfiguration();
    }

    // Grab any configuration passed in.
    if (empty($configuration)) {
    $configuration = $request->get('config', []);
    }

    // Construct and render the block.
    $blockInstance = $this->blockViewBuilder->build($plugin_id, $configuration, TRUE);
    // Get block instance.
    if ($blockInstance = $this->getBlockInstance($request, $block_id, $configuration)) {
      $renderedBlock = $this->renderer->renderRoot($blockInstance);

      // Apply token replacement.
@@ -254,18 +283,12 @@ class AjaxBlockController extends ControllerBase {
      // Clean up ajax links.
      $renderedBlock = str_replace('/block/ajax/' . $block_id, '', trim($renderedBlock));

    // Set max age.
    $max_age = 0;
    if (isset($configuration['block_ajax']['max_age'])) {
      $max_age = $configuration['block_ajax']['max_age'];
    }
    $response->setMaxAge($max_age);
    $response->setSharedMaxAge($max_age);

      // Set data for response.
      $this->setResponseMaxAge($response, $configuration);
      $response->setData([
        'content' => $renderedBlock,
      ]);
    }

    // Returns response.
    return $response;
@@ -287,7 +310,7 @@ class AjaxBlockController extends ControllerBase {
   * @throws \Drupal\Component\Plugin\Exception\ContextException
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\MissingValueContextException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException|\Drupal\Component\Plugin\Exception\PluginException
   */
  public function loadBlockTaxonomyTermContext(
    Request $request,
@@ -302,37 +325,11 @@ class AjaxBlockController extends ControllerBase {
      return $response;
    }

    // Load block.
    $block = $this->entityTypeManager->getStorage('block')->load($block_id);
    if (!$block instanceof BlockInterface) {
      return $response;
    }

    // Add in custom cache tag.
    $block->addCacheTags(['block_ajax']);

    // Make sure we have plugin id.
    $plugin_id = $request->get('plugin_id', '');
    if (empty($plugin_id)) {
      return $response;
    }

    // Block configuration.
    $configuration = [];

    // Check if block has special plugin and add it to dependency.
    $plugin = $block->getPlugin();
    if (is_object($plugin) && $plugin->getPluginId() == $plugin_id) {
      $configuration = $plugin->getConfiguration();
    }

    // Grab any configuration passed in.
    if (empty($configuration)) {
    $configuration = $request->get('config', []);
    }

    // Construct and render the block.
    $blockInstance = $this->blockViewBuilder->build($plugin_id, $configuration, TRUE);
    // Get block instance.
    if ($blockInstance = $this->getBlockInstance($request, $block_id, $configuration)) {
      $renderedBlock = $this->renderer->renderRoot($blockInstance);

      // Apply token replacement.
@@ -343,18 +340,12 @@ class AjaxBlockController extends ControllerBase {
      // Clean up ajax links.
      $renderedBlock = str_replace('/block/ajax/' . $block_id, '', trim($renderedBlock));

    // Set max age.
    $max_age = 0;
    if (isset($configuration['block_ajax']['max_age'])) {
      $max_age = $configuration['block_ajax']['max_age'];
    }
    $response->setMaxAge($max_age);
    $response->setSharedMaxAge($max_age);

      // Set data for response.
      $this->setResponseMaxAge($response, $configuration);
      $response->setData([
        'content' => $renderedBlock,
      ]);
    }

    // Returns response.
    return $response;
@@ -376,7 +367,7 @@ class AjaxBlockController extends ControllerBase {
   * @throws \Drupal\Component\Plugin\Exception\ContextException
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\MissingValueContextException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException|\Drupal\Component\Plugin\Exception\PluginException
   */
  public function loadBlockUserContext(
    Request $request,
@@ -391,37 +382,11 @@ class AjaxBlockController extends ControllerBase {
      return $response;
    }

    // Load block.
    $block = $this->entityTypeManager->getStorage('block')->load($block_id);
    if (!$block instanceof BlockInterface) {
      return $response;
    }

    // Add in custom cache tag.
    $block->addCacheTags(['block_ajax']);

    // Make sure we have plugin id.
    $plugin_id = $request->get('plugin_id', '');
    if (empty($plugin_id)) {
      return $response;
    }

    // Block configuration.
    $configuration = [];

    // Check if block has special plugin and add it to dependency.
    $plugin = $block->getPlugin();
    if (is_object($plugin) && $plugin->getPluginId() == $plugin_id) {
      $configuration = $plugin->getConfiguration();
    }

    // Grab any configuration passed in.
    if (empty($configuration)) {
    $configuration = $request->get('config', []);
    }

    // Construct and render the block.
    $blockInstance = $this->blockViewBuilder->build($plugin_id, $configuration, TRUE);
    // Get block instance.
    if ($blockInstance = $this->getBlockInstance($request, $block_id, $configuration)) {
      $renderedBlock = $this->renderer->renderRoot($blockInstance);

      // Apply token replacement.
@@ -432,18 +397,12 @@ class AjaxBlockController extends ControllerBase {
      // Clean up ajax links.
      $renderedBlock = str_replace('/block/ajax/' . $block_id, '', trim($renderedBlock));

    // Set max age.
    $max_age = 0;
    if (isset($configuration['block_ajax']['max_age'])) {
      $max_age = $configuration['block_ajax']['max_age'];
    }
    $response->setMaxAge($max_age);
    $response->setSharedMaxAge($max_age);

      // Set data for response.
      $this->setResponseMaxAge($response, $configuration);
      $response->setData([
        'content' => $renderedBlock,
      ]);
    }

    // Returns response.
    return $response;