You are here

class render_cache_hijack_context_reaction_block in Render cache 7

Same name and namespace in other branches
  1. 7.2 modules/utility/render_cache_context/context/plugins/render_cache_hijack_context_reaction_block.inc \render_cache_hijack_context_reaction_block

Hierarchy

Expanded class hierarchy of render_cache_hijack_context_reaction_block

2 string references to 'render_cache_hijack_context_reaction_block'
render_cache_context_context_plugins in modules/render_cache_context/render_cache_context.module
Implementation of hook_context_plugins().
render_cache_context_context_registry_alter in modules/render_cache_context/render_cache_context.module
Implements hook_context_registry_alter().

File

modules/render_cache_context/context/plugins/render_cache_hijack_context_reaction_block.inc, line 3

View source
class render_cache_hijack_context_reaction_block extends context_reaction_block {

  /**
   * {@inheritdoc}
   */
  function block_get_blocks_by_region($region) {
    module_load_include('module', 'block', 'block');
    $build = $this
      ->block_list_build($region);
    if ($this
      ->is_editable_region($region)) {
      $build = $this
        ->editable_region($region, $build);
    }
    return $build;
  }

  /**
   * Support the optional aggressive block list caching.
   *
   * Otherwise system_cron() clears context cache and parent::get_blocks()
   * runs _block_rehash(), which is slow, every 30 minutes.
   *
   * @param string|null $region
   * @param object|null $context
   * @param bool $reset
   *
   * @return array|bool
   */
  function get_blocks($region = NULL, $context = NULL, $reset = FALSE) {
    if (!variable_get('render_cache_cache_block_list', TRUE)) {
      return parent::get_blocks($region, $context, $reset);
    }
    $hash = md5(serialize(array(
      $region,
      $context,
    )));
    $cid = "render_cache:context_reaction_block:block_list:{$hash}";
    if (!$reset) {
      $cache = cache_get($cid);
      if (!empty($cache->data)) {
        return $cache->data;
      }
    }
    $blocks = parent::get_blocks($region, $context, $reset);
    cache_set($cid, $blocks);
    return $blocks;
  }

  /**
   * A caching version of block_list() .
   *
   * @param string $region
   *   The region to get blocks from.
   *
   * @return array
   *   A render array for this region. This render array will only contain
   *   #markup elements.
   */
  function block_list_build($region) {
    global $theme;
    $cache_info_default = render_cache_cache_info_defaults();
    $cache_info_default['keys'] = array(
      'render_cache',
    );
    drupal_alter('render_cache_block_default_cache_info', $cache_info_default, $default_alter_context);
    $markup =& drupal_static('context_reaction_block_list_build');
    $contexts = context_active_contexts();
    $cid_map = array();
    $cache_info_map = array();
    if (!isset($markup)) {
      $info = $this
        ->get_blocks();
      $markup = array();
      $context_blocks = array();
      foreach ($contexts as $context) {
        $options = $this
          ->fetch_from_context($context);
        if (!empty($options['blocks'])) {
          foreach ($options['blocks'] as $context_block) {
            $bid = "{$context_block['module']}-{$context_block['delta']}";
            if (isset($info[$bid])) {
              $block = (object) array_merge((array) $info[$bid], $context_block);
              $block->bid = $bid;
              $block->context = $context->name;
              $block->title = isset($info[$block->bid]->title) ? $info[$block->bid]->title : NULL;
              $alter_context = array(
                'context' => $context,
                'bid' => $bid,
                'module' => $context_block['module'],
                'delta' => $context_block['delta'],
                'granularity' => isset($info[$block->bid]->cache) ? $info[$block->bid]->cache : DRUPAL_NO_CACHE,
              );
              $alter_context['region'] = $block->region;
              $cache_info = $cache_info_default;
              $cache_info['keys'][] = $block->region;
              $cache_info['keys'][] = $bid;
              $cid_map[$bid] = $this
                ->render_cache_get_cid($block, $cache_info, $alter_context);
              $cache_info_map[$bid] = $cache_info;
              $context_blocks[$block->region][$block->bid] = $block;
              $block->cache = DRUPAL_NO_CACHE;
            }
          }
        }
      }
      $cids = array_filter(array_values($cid_map));
      $cached_blocks = $cids ? cache_get_multiple($cids, 'cache_render') : array();
      $this
        ->is_editable_check($context_blocks);
      $active_regions = $this
        ->system_region_list($theme);
      foreach ($context_blocks as $r => $blocks) {
        $markup[$r] = array();

        //only render blocks in an active region
        if (array_key_exists($r, $active_regions)) {

          // Sort blocks.
          uasort($blocks, array(
            'context_reaction_block',
            'block_sort',
          ));
          foreach ($blocks as $bid => $block) {
            $cid = $cid_map[$bid];
            if (isset($cached_blocks[$cid])) {
              $build = $cached_blocks[$cid]->data;
            }
            else {
              $this
                ->build_block($block);

              // Make blocks editable if allowed.
              if ($this
                ->is_editable_region($r)) {
                $this
                  ->editable_block($block);
              }
              $build = $this
                ->render_cache_block($block, $bid, $cid_map[$bid], $cache_info_map[$bid]);
            }

            // Run any post-render callbacks.
            render_cache_process_attached_callbacks($build, $bid);

            // context_reaction_block::get_blocks() uses - between module and
            // delta but core uses underscore and theming expects that.
            $markup[$r]["{$block->module}_{$block->delta}"] = $build;
          }
        }
      }
    }
    return isset($markup[$region]) ? $markup[$region] : array();
  }

  /**
   * Build the cache ID and cache information array.
   *
   * @param object $block
   *   The block object
   * @param array $cache_info
   *   The cache information array.
   * @param array $context
   *   The context.
   *
   * @return string
   *   The cache ID.
   */
  protected function render_cache_get_cid($block, &$cache_info, $context) {
    $cache_info += render_cache_cache_info_defaults();
    drupal_alter('render_cache_block_cache_info', $cache_info, $block, $context);
    if ($cache_info['granularity'] == DRUPAL_NO_CACHE) {
      return NULL;
    }
    $cid_parts = array();
    $hash = array();
    if (!empty($cache_info['keys']) && is_array($cache_info['keys'])) {
      $cid_parts = $cache_info['keys'];
    }

    // Add drupal_render cid_parts based on granularity
    $granularity = isset($cache_info['granularity']) ? $cache_info['granularity'] : NULL;
    $cid_parts = array_merge($cid_parts, drupal_render_cid_parts($granularity));
    $hash['module'] = $context['module'];
    $hash['delta'] = $context['delta'];
    $hash['context'] = $context['context']->name;

    // @todo relevant for blocks?
    $hash['render_method'] = !empty($cache_info['render_cache_render_to_markup']);
    if ($hash['render_method']) {
      $hash['render_options'] = serialize($cache_info['render_cache_render_to_markup']);
    }

    // Allow modules to modify $hash for custom invalidating.
    drupal_alter('render_cache_block_hash', $hash, $block, $cache_info, $context);
    $cid_parts[] = sha1(implode('-', $hash));
    drupal_alter('render_cache_block_cid', $cid_parts, $block, $cache_info, $context);
    return implode(':', $cid_parts);
  }

  /**
   * This is a shortened copy of _block_render_blocks().
   *
   * @param stdClass $block
   *   A block object. $block->content and $block->subject will be filled in.
   */
  protected function build_block($block) {
    $array = module_invoke($block->module, 'block_view', $block->delta);

    // Valid PHP function names cannot contain hyphens.
    $delta = str_replace('-', '_', $block->delta);

    // Allow modules to modify the block before it is viewed, via either
    // hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
    drupal_alter(array(
      'block_view',
      "block_view_{$block->module}_{$delta}",
    ), $array, $block);
    if (isset($array) && is_array($array)) {
      foreach ($array as $k => $v) {
        $block->{$k} = $v;
      }
    }
    if (isset($block->content) && $block->content) {

      // Normalize to the drupal_render() structure.
      if (is_string($block->content)) {
        $block->content = array(
          '#markup' => $block->content,
        );
      }

      // Override default block title if a custom display title is present.
      if ($block->title) {

        // Check plain here to allow module generated titles to keep any
        // markup.
        $block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
      }
      if (!isset($block->subject)) {
        $block->subject = '';
      }
    }
  }

  /**
   * Render and cache a block.
   *
   * @param stdClass $block
   *   A block object.
   * @param string $bid
   *   The block id in $module-$delta format.
   * @param string $cid
   *   The cache id.
   * @param array $cache_info
   *   The cache information array.
   *
   * @return string
   *   The rendered HTML for the block.
   */
  protected function render_cache_block($block, $bid, $cid, $cache_info) {
    if (is_string($block->content)) {
      $block->content = array(
        '#markup' => $block->content,
      );
    }
    $build = $block->content;
    unset($block->content);
    $build += array(
      '#attached' => array(),
    );
    if ($bid != 'system-main' && $bid != 'system-help') {
      $build['#contextual_links']['block'] = array(
        'admin/structure/block/manage',
        array(
          $block->module,
          $block->delta,
        ),
      );
    }
    $build['#block'] = $block;
    $build['#theme_wrappers'][] = 'block';
    if (!empty($cid)) {
      $build['#cache'] = $cache_info;
      $build['#cache']['cid'] = $cid;
      return array(
        '#markup' => drupal_render($build),
        '#attached' => drupal_render_collect_attached($build, TRUE),
      );
    }
    return $build;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
context_reaction::$description property
context_reaction::$plugin property
context_reaction::$title property
context_reaction::fetch_from_context function Retrieve options from the context provided. 1
context_reaction::get_contexts function Retrieve active contexts that have values for this reaction.
context_reaction::__clone function Clone our references when we're being cloned.
context_reaction::__construct function Constructor. Do not override.
context_reaction_block::block_list function An alternative version of block_list() that provides any context enabled blocks.
context_reaction_block::block_sort static function Sort callback.
context_reaction_block::context_block_ajax_rendering_allowed private function Allow modules to selectively allow ajax rendering of a specific block
context_reaction_block::editable_block protected function Add markup for making a block editable.
context_reaction_block::editable_region protected function Add markup for making a region editable.
context_reaction_block::editor_form function Context editor form for blocks. 1
context_reaction_block::editor_form_submit function Submit handler context editor form. 1
context_reaction_block::execute function Execute.
context_reaction_block::is_editable_check function Determine if there is an active context editor block, and set a flag. We will set a flag so that we can make sure that blocks with empty content have some default content. This is needed so the save of the context inline editor does not remove the…
context_reaction_block::is_editable_region protected function Determine whether inline editing requirements are met and that the current user may edit.
context_reaction_block::is_enabled_region protected function Return a list of enabled regions for which blocks should be built. Split out into a separate method for easy overrides in extending classes. 1
context_reaction_block::json_decode protected function Compatibility wrapper around json_decode().
context_reaction_block::max_block_weight protected function Generate the safe weight range for a block being added to a region such that there are enough potential unique weights to support all blocks.
context_reaction_block::options_form function Options form. Overrides context_reaction::options_form 1
context_reaction_block::options_form_submit function Options form submit handler. Overrides context_reaction::options_form_submit 1
context_reaction_block::rebuild_needed function Check or set whether a rebuild of the block info cache is needed.
context_reaction_block::render_ajax function Block renderer for AJAX requests. Triggered when $_GET['context_block'] is set. See ->execute() for how this is called.
context_reaction_block::settings_form function Settings form for variables. Overrides context_reaction::settings_form
context_reaction_block::system_region_list protected function Provide caching for system_region_list since it can get called frequently. Evaluate for removal once https://drupal.org/node/1873450 lands or system_region_list is otherwise cached in core
render_cache_hijack_context_reaction_block::block_get_blocks_by_region function Get a renderable array of a region containing all enabled blocks. Overrides context_reaction_block::block_get_blocks_by_region
render_cache_hijack_context_reaction_block::block_list_build function A caching version of block_list() .
render_cache_hijack_context_reaction_block::build_block protected function This is a shortened copy of _block_render_blocks().
render_cache_hijack_context_reaction_block::get_blocks function Support the optional aggressive block list caching. Overrides context_reaction_block::get_blocks
render_cache_hijack_context_reaction_block::render_cache_block protected function Render and cache a block.
render_cache_hijack_context_reaction_block::render_cache_get_cid protected function Build the cache ID and cache information array.