Same name and namespace in other branches
  1. 4.6.x modules/block.module \_block_rehash()
  2. 4.7.x modules/block.module \_block_rehash()
  3. 5.x modules/block/block.module \_block_rehash()
  4. 7.x modules/block/block.module \_block_rehash()

Update the 'blocks' 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.

2 calls to _block_rehash()
block_admin_display in modules/block/block.admin.inc
Menu callback for admin/build/block.
block_flush_caches in modules/block/block.module
Implementation of hook_flush_caches().

File

modules/block/block.module, line 233
Controls the boxes that are displayed around the main content.

Code

function _block_rehash($theme = NULL) {
  global $theme_key;
  init_theme();
  if (!isset($theme)) {
    $theme = $theme_key;
  }
  $result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $theme);
  $old_blocks = array();
  while ($old_block = db_fetch_array($result)) {
    $old_blocks[$old_block['module']][$old_block['delta']] = $old_block;
  }
  $blocks = array();

  // Valid region names for the theme.
  $regions = system_region_list($theme);
  foreach (module_list() as $module) {
    $module_blocks = module_invoke($module, 'block', 'list');
    if ($module_blocks) {
      foreach ($module_blocks as $delta => $block) {
        if (empty($old_blocks[$module][$delta])) {

          // If it's a new block, add identifiers.
          $block['module'] = $module;
          $block['delta'] = $delta;
          $block['theme'] = $theme;
          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'] = '';
          }

          // Add defaults and save it into the database.
          drupal_write_record('blocks', $block);

          // Set region to none if not enabled.
          $block['region'] = $block['status'] ? $block['region'] : BLOCK_REGION_NONE;

          // Add to the list of blocks we return.
          $blocks[] = $block;
        }
        else {

          // If it's an existing block, database settings should overwrite
          // the code. The only exceptions are 'cache' which is only definable
          // and updatable in the code, and 'info' which is not stored in
          // the database.
          // Update the cache mode only; the other values don't need to change.
          if (isset($block['cache']) && $block['cache'] != $old_blocks[$module][$delta]['cache']) {
            db_query("UPDATE {blocks} SET cache = %d WHERE bid = %d", $block['cache'], $old_blocks[$module][$delta]['bid']);
          }

          // Add 'info' to this block.
          $old_blocks[$module][$delta]['info'] = $block['info'];

          // If the region name does not exist, disable the block and assign it to none.
          if (!empty($old_blocks[$module][$delta]['region']) && !isset($regions[$old_blocks[$module][$delta]['region']])) {
            drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array(
              '%info' => $old_blocks[$module][$delta]['info'],
              '%region' => $old_blocks[$module][$delta]['region'],
            )), 'warning');
            $old_blocks[$module][$delta]['status'] = 0;
            $old_blocks[$module][$delta]['region'] = BLOCK_REGION_NONE;
          }
          else {
            $old_blocks[$module][$delta]['region'] = $old_blocks[$module][$delta]['status'] ? $old_blocks[$module][$delta]['region'] : BLOCK_REGION_NONE;
          }

          // Add this block to the list of blocks we return.
          $blocks[] = $old_blocks[$module][$delta];

          // Remove this block from the list of blocks to be deleted.
          unset($old_blocks[$module][$delta]);
        }
      }
    }
  }

  // Remove blocks that are no longer defined by the code from the database.
  foreach ($old_blocks as $module => $old_module_blocks) {

    // This cleanup does not apply to disabled modules, to avoid configuration
    // being lost when modules are disabled.
    if (module_exists($module)) {
      foreach ($old_module_blocks as $delta => $block) {
        db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $module, $delta, $theme);
      }
    }
  }
  return $blocks;
}