function _block_rehash

Updates the 'block' DB table with the blocks currently exported by modules.

Parameters

$theme: The theme to rehash blocks for. If not provided, defaults to the currently used theme.

Return value

Blocks currently exported by modules.

3 calls to _block_rehash()
block_admin_display_prepare_blocks in drupal/core/modules/block/block.admin.inc
Prepares a list of blocks for display on the blocks administration page.
block_rebuild in drupal/core/modules/block/block.module
Implements hook_rebuild().
hook_rebuild in drupal/core/modules/system/system.api.php
Rebuild data based upon refreshed caches.

File

drupal/core/modules/block/block.module, line 405
Controls the visual building blocks a page is constructed with.

Code

function _block_rehash($theme = NULL) {
  global $theme_key;
  drupal_theme_initialize();
  if (!isset($theme)) {

    // If theme is not specifically set, rehash for the current theme.
    $theme = $theme_key;
  }
  $regions = system_region_list($theme);

  // These are the blocks the function will return.
  $blocks = array();

  // These are the blocks defined by code and modified by the database.
  $current_blocks = array();

  // These are {block}.bid values to be kept.
  $bids = array();
  $or = db_or();

  // Gather the blocks defined by modules.
  foreach (module_implements('block_info') as $module) {
    $module_blocks = module_invoke($module, 'block_info');
    foreach ($module_blocks as $delta => $block) {

      // Compile a condition to retrieve this block from the database.
      $condition = db_and()
        ->condition('module', $module)
        ->condition('delta', $delta);
      $or
        ->condition($condition);

      // Add identifiers.
      $block['module'] = $module;
      $block['delta'] = $delta;
      $block['theme'] = $theme;
      $current_blocks[$module][$delta] = $block;
    }
  }

  // Save the blocks defined in code for alter context.
  $code_blocks = $current_blocks;
  $database_blocks = db_select('block', 'b')
    ->fields('b')
    ->condition($or)
    ->condition('theme', $theme)
    ->execute();
  foreach ($database_blocks as $block) {

    // Preserve info which is not in the database.
    $block->info = $current_blocks[$block->module][$block->delta]['info'];

    // The cache mode can only by set from hook_block_info(), so that has
    // precedence over the database's value.
    if (isset($current_blocks[$block->module][$block->delta]['cache'])) {
      $block->cache = $current_blocks[$block->module][$block->delta]['cache'];
    }

    // Blocks stored in the database override the blocks defined in code.
    $current_blocks[$block->module][$block->delta] = get_object_vars($block);

    // Preserve this block.
    $bids[$block->bid] = $block->bid;
  }
  drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
  foreach ($current_blocks as $module => $module_blocks) {
    foreach ($module_blocks as $delta => $block) {
      if (!isset($block['pages'])) {

        // {block}.pages is type 'text', so it cannot have a
        // default value, and not null, so we need to provide
        // value if the module did not.
        $block['pages'] = '';
      }

      // Make sure weight is set.
      if (!isset($block['weight'])) {
        $block['weight'] = 0;
      }
      if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) {
        drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array(
          '%info' => $block['info'],
          '%region' => $block['region'],
        )), 'warning');

        // Disabled modules are moved into the BLOCK_REGION_NONE later so no
        // need to move the block to another region.
        $block['status'] = 0;
      }

      // Set region to none if not enabled and make sure status is set.
      if (empty($block['status'])) {
        $block['status'] = 0;
        $block['region'] = BLOCK_REGION_NONE;
      }

      // There is no point saving disabled blocks. Still, we need to save them
      // because the 'title' attribute is saved to the {blocks} table.
      if (isset($block['bid'])) {

        // If the block has a bid property, it comes from the database and
        // the record needs to be updated, so set the primary key to 'bid'
        // before passing to drupal_write_record().
        $primary_keys = array(
          'bid',
        );

        // Remove a block from the list of blocks to keep if it became disabled.
        unset($bids[$block['bid']]);
      }
      else {
        $primary_keys = array();
      }
      drupal_write_record('block', $block, $primary_keys);

      // Add to the list of blocks we return.
      $blocks[] = $block;
    }
  }
  if ($bids) {

    // Remove disabled that are no longer defined by the code from the
    // database.
    db_delete('block')
      ->condition('bid', $bids, 'NOT IN')
      ->condition('theme', $theme)
      ->execute();
  }
  return $blocks;
}