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.

5 calls to _block_rehash()
BlockHashTestCase::doRehash in modules/block/block.test
Performs a block rehash and checks several related assertions.
BlockHashTestCase::testBlockRehash in modules/block/block.test
Tests that block rehashing does not write to the database too often.
block_admin_display_prepare_blocks in modules/block/block.admin.inc
Prepares a list of blocks for display on the blocks administration page.
block_flush_caches in modules/block/block.module
Implements hook_flush_caches().
dashboard_show_disabled in modules/dashboard/dashboard.module
Ajax callback: Shows disabled blocks in the dashboard customization mode.

File

modules/block/block.module, line 372

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');
        $delta_list = array();
        foreach ($module_blocks as $delta => $block) {
            // Compile a condition to retrieve this block from the database.
            // Add identifiers.
            $delta_list[] = $delta;
            $block['module'] = $module;
            $block['delta'] = $delta;
            $block['theme'] = $theme;
            $current_blocks[$module][$delta] = $block;
        }
        if (!empty($delta_list)) {
            $condition = db_and()->condition('module', $module)
                ->condition('delta', $delta_list);
            $or->condition($condition);
        }
    }
    // Save the blocks defined in code for alter context.
    $code_blocks = $current_blocks;
    $database_blocks = db_select('block', 'b', array(
        'fetch' => PDO::FETCH_ASSOC,
    ))->fields('b')
        ->condition($or)
        ->condition('theme', $theme)
        ->execute();
    $original_database_blocks = array();
    foreach ($database_blocks as $block) {
        $module = $block['module'];
        $delta = $block['delta'];
        $original_database_blocks[$module][$delta] = $block;
        // The cache mode can only by set from hook_block_info(), so that has
        // precedence over the database's value.
        if (isset($current_blocks[$module][$delta]['cache'])) {
            $block['cache'] = $current_blocks[$module][$delta]['cache'];
        }
        // Preserve info which is not in the database.
        $block['info'] = $current_blocks[$module][$delta]['info'];
        // Blocks stored in the database override the blocks defined in code.
        $current_blocks[$module][$delta] = $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) {
            // Make sure certain attributes are set.
            $block += array(
                'pages' => '',
                'weight' => 0,
                'status' => 0,
            );
            // Check for active blocks in regions that are not available.
            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.
            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();
            }
            // If the block is new or differs from the original database block, save
            // it. To determine whether there was a change it is enough to examine
            // the values for the keys in the original database record as that
            // contained every database field.
            if (!$primary_keys || array_diff_assoc($original_database_blocks[$module][$delta], $block)) {
                drupal_write_record('block', $block, $primary_keys);
                // Make it possible to test this.
                $block['saved'] = TRUE;
            }
            // 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;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.