Commit 5c529585 authored by webchick's avatar webchick
Browse files

#560746 follow-up by chx: Split hook_block_info_alter() into list_ and...

#560746 follow-up by chx: Split hook_block_info_alter() into list_ and info_alter() and clean up block_rehash().
parent 98df60e7
...@@ -69,6 +69,25 @@ function hook_block_info() { ...@@ -69,6 +69,25 @@ function hook_block_info() {
return $blocks; return $blocks;
} }
/**
* Change block definition before saving to the database.
*
* @param $blocks
* A multidimensional array of blocks keyed by the defining module and delta
* the value is a block as seen in hook_block_info(). This hook is fired
* after the blocks are collected from hook_block_info() and the database,
* right before saving back to the database.
* @param $theme
* The theme these blocks belong to.
* @param $code_blocks
* The blocks as defined in hook_block_info before overwritten by the
* database data.
*/
function hook_block_info_alter(&$blocks, $theme, $code_blocks) {
// Disable the login block.
$blocks['user']['login']['status'] = 0;
}
/** /**
* Configuration form for the block. * Configuration form for the block.
* *
...@@ -240,7 +259,7 @@ function hook_block_view_MODULE_DELTA_alter(&$data, $block) { ...@@ -240,7 +259,7 @@ function hook_block_view_MODULE_DELTA_alter(&$data, $block) {
* This example shows how to achieve language specific visibility setting for * This example shows how to achieve language specific visibility setting for
* blocks. * blocks.
*/ */
function hook_block_info_alter(&$blocks) { function hook_block_list_alter(&$blocks) {
global $language, $theme_key; global $language, $theme_key;
$result = db_query('SELECT module, delta, language FROM {my_table}'); $result = db_query('SELECT module, delta, language FROM {my_table}');
......
...@@ -317,80 +317,100 @@ function _block_rehash($theme = NULL) { ...@@ -317,80 +317,100 @@ function _block_rehash($theme = NULL) {
global $theme_key; global $theme_key;
drupal_theme_initialize(); drupal_theme_initialize();
if (!isset($theme)) { if (!isset($theme)) {
// If theme is not specifically set, rehash for the current theme. // If theme is not specifically set, rehash for the current theme.
$theme = $theme_key; $theme = $theme_key;
} }
$old_blocks = array();
$result = db_query("SELECT * FROM {block} WHERE theme = :theme", array(':theme' => $theme));
foreach ($result as $old_block) {
$old_block = is_object($old_block) ? get_object_vars($old_block) : $old_block;
$old_blocks[$old_block['module']][$old_block['delta']] = $old_block;
}
$blocks = array();
// Valid region names for the theme.
$regions = system_region_list($theme); $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) { foreach (module_implements('block_info') as $module) {
$module_blocks = module_invoke($module, 'block_info'); $module_blocks = module_invoke($module, 'block_info');
if ($module_blocks) { foreach ($module_blocks as $delta => $block) {
foreach ($module_blocks as $delta => $block) { // Compile a condition to retrieve this block from the database.
if (empty($old_blocks[$module][$delta])) { $condition = db_and()
// If it's a new block, add identifiers. ->condition('module', $module)
$block['module'] = $module; ->condition('delta', $delta);
$block['delta'] = $delta; $or->condition($condition);
$block['theme'] = $theme; // Add identifiers.
if (!isset($block['pages'])) { $block['module'] = $module;
// {block}.pages is type 'text', so it cannot have a $block['delta'] = $delta;
// default value, and not null, so we need to provide $block['theme'] = $theme;
// value if the module did not. $current_blocks[$module][$delta] = $block;
$block['pages'] = '';
}
// Add defaults and save it into the database.
drupal_write_record('block', $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. But aside from 'info' everything that's definable in
// code is stored in the database and we do not store 'info', so we
// do not need to update the database here.
// 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]);
}
}
} }
} }
// Save the blocks defined in code for alter context.
// Remove blocks that are no longer defined by the code from the database. $code_blocks = $current_blocks;
foreach ($old_blocks as $module => $old_module_blocks) { $database_blocks = db_select('block', 'b')
foreach ($old_module_blocks as $delta => $block) { ->fields('b')
db_delete('block') ->condition($or)
->condition('module', $module) ->condition('theme', $theme)
->condition('delta', $delta) ->execute();
->condition('theme', $theme) foreach ($database_blocks as $block) {
->execute(); // Preserve info which is not in the database.
$block->info = $current_blocks[$block->module][$block->delta]['info'];
// 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']])) {
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 bock 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
// beecause 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; return $blocks;
} }
...@@ -624,7 +644,7 @@ function _block_load_blocks() { ...@@ -624,7 +644,7 @@ function _block_load_blocks() {
$block_info = $result->fetchAllAssoc('bid'); $block_info = $result->fetchAllAssoc('bid');
// Allow modules to modify the block list. // Allow modules to modify the block list.
drupal_alter('block_info', $block_info); drupal_alter('block_list', $block_info);
$blocks = array(); $blocks = array();
foreach ($block_info as $block) { foreach ($block_info as $block) {
...@@ -634,12 +654,12 @@ function _block_load_blocks() { ...@@ -634,12 +654,12 @@ function _block_load_blocks() {
} }
/** /**
* Implements hook_block_info_alter(). * Implements hook_block_list_alter().
* *
* Check the page, user role and user specific visibilty settings. * Check the page, user role and user specific visibilty settings.
* Remove the block if the visibility conditions are not met. * Remove the block if the visibility conditions are not met.
*/ */
function block_block_info_alter(&$blocks) { function block_block_list_alter(&$blocks) {
global $user, $theme_key; global $user, $theme_key;
// Build an array of roles for each block. // Build an array of roles for each block.
......
...@@ -73,13 +73,13 @@ function dashboard_menu_alter(&$items) { ...@@ -73,13 +73,13 @@ function dashboard_menu_alter(&$items) {
} }
/** /**
* Implements hook_block_info_alter(). * Implements hook_block_list_alter().
* *
* Skip rendering dashboard blocks when not on the dashboard page itself. This * Skip rendering dashboard blocks when not on the dashboard page itself. This
* prevents expensive dashboard blocks from causing performance issues on pages * prevents expensive dashboard blocks from causing performance issues on pages
* where they will never be displayed. * where they will never be displayed.
*/ */
function dashboard_block_info_alter(&$blocks) { function dashboard_block_list_alter(&$blocks) {
if (!dashboard_is_visible()) { if (!dashboard_is_visible()) {
foreach ($blocks as $key => $block) { foreach ($blocks as $key => $block) {
if (in_array($block->region, dashboard_regions())) { if (in_array($block->region, dashboard_regions())) {
......
...@@ -2293,12 +2293,12 @@ function node_modules_uninstalled($modules) { ...@@ -2293,12 +2293,12 @@ function node_modules_uninstalled($modules) {
} }
/** /**
* Implements hook_block_info_alter(). * Implements hook_block_list_alter().
* *
* Check the content type specific visibilty settings. * Check the content type specific visibilty settings.
* Remove the block if the visibility conditions are not met. * Remove the block if the visibility conditions are not met.
*/ */
function node_block_info_alter(&$blocks) { function node_block_list_alter(&$blocks) {
global $theme_key; global $theme_key;
// Build an array of node types for each block. // Build an array of node types for each block.
......
...@@ -223,9 +223,9 @@ function overlay_page_alter(&$page) { ...@@ -223,9 +223,9 @@ function overlay_page_alter(&$page) {
} }
/** /**
* Implements hook_block_info_alter(). * Implements hook_block_list_alter().
*/ */
function overlay_block_info_alter(&$blocks) { function overlay_block_list_alter(&$blocks) {
// If we are limiting rendering to a subset of page regions, hide all blocks // If we are limiting rendering to a subset of page regions, hide all blocks
// which appear in regions not on that list. Note that overlay_page_alter() // which appear in regions not on that list. Note that overlay_page_alter()
// does a more comprehensive job of preventing unwanted regions from being // does a more comprehensive job of preventing unwanted regions from being
...@@ -666,7 +666,7 @@ function _overlay_region_list($type) { ...@@ -666,7 +666,7 @@ function _overlay_region_list($type) {
* and all regions of the page will be rendered. * and all regions of the page will be rendered.
* *
* @see overlay_page_alter() * @see overlay_page_alter()
* @see overlay_block_info_alter() * @see overlay_block_list_alter()
* @see overlay_set_regions_to_render() * @see overlay_set_regions_to_render()
*/ */
function overlay_get_regions_to_render() { function overlay_get_regions_to_render() {
...@@ -688,7 +688,7 @@ function overlay_get_regions_to_render() { ...@@ -688,7 +688,7 @@ function overlay_get_regions_to_render() {
* are not being limited. * are not being limited.
* *
* @see overlay_page_alter() * @see overlay_page_alter()
* @see overlay_block_info_alter() * @see overlay_block_list_alter()
* @see overlay_get_regions_to_render() * @see overlay_get_regions_to_render()
*/ */
function overlay_set_regions_to_render($regions = NULL) { function overlay_set_regions_to_render($regions = NULL) {
...@@ -716,7 +716,7 @@ function overlay_set_regions_to_render($regions = NULL) { ...@@ -716,7 +716,7 @@ function overlay_set_regions_to_render($regions = NULL) {
*/ */
function overlay_render_region($region) { function overlay_render_region($region) {
// Indicate the region that we will be rendering, so that other regions will // Indicate the region that we will be rendering, so that other regions will
// be hidden by overlay_page_alter() and overlay_block_info_alter(). // be hidden by overlay_page_alter() and overlay_block_list_alter().
overlay_set_regions_to_render(array($region)); overlay_set_regions_to_render(array($region));
// Do what is necessary to force drupal_render_page() to only display HTML // Do what is necessary to force drupal_render_page() to only display HTML
// from the requested region. Specifically, declare that the main page // from the requested region. Specifically, declare that the main page
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment