Commit 40fb3a93 authored by Dries's avatar Dries
Browse files

- Patch #684774 by andypost, sun: critical bug: block visibility settings...

- Patch #684774 by andypost, sun: critical bug: block visibility settings cannot be properly extended.
parent fdb422b8
......@@ -446,6 +446,8 @@ function block_add_block_form_submit($form, &$form_state) {
'format' => $form_state['values']['format'],
))
->execute();
// Store block delta to allow other modules to work with new block.
$form_state['values']['delta'] = $delta;
$query = db_insert('block')->fields(array('visibility', 'pages', 'custom', 'title', 'module', 'theme', 'status', 'weight', 'delta', 'cache'));
foreach (list_themes() as $key => $theme) {
......
......@@ -252,7 +252,7 @@ function hook_block_info_alter(&$blocks) {
foreach ($blocks as $key => $block) {
// Any module using this alter should inspect the data before changing it,
// to ensure it is what they expect.
if ($block->theme != $theme_key || $block->status != 1) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {
// This block was added by a contrib module, leave it in the list.
continue;
}
......
......@@ -131,34 +131,6 @@ function block_schema() {
),
);
$schema['block_node_type'] = array(
'description' => 'Sets up display criteria for blocks based on content types',
'fields' => array(
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => "The block's origin module, from {block}.module.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The block's unique delta within module, from {block}.delta.",
),
'type' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The machine-readable name of this type from {node_type}.type.",
),
),
'primary key' => array('module', 'delta', 'type'),
'indexes' => array(
'type' => array('type'),
),
);
$schema['block_custom'] = array(
'description' => 'Stores contents of custom-made blocks.',
'fields' => array(
......@@ -230,42 +202,6 @@ function block_update_7000() {
->execute();
}
/**
* Add the block_node_type table.
*/
function block_update_7001() {
$schema['block_node_type'] = array(
'description' => 'Sets up display criteria for blocks based on content types',
'fields' => array(
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => "The block's origin module, from {block}.module.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The block's unique delta within module, from {block}.delta.",
),
'type' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The machine-readable name of this type from {node_type}.type.",
),
),
'primary key' => array('module', 'delta', 'type'),
'indexes' => array(
'type' => array('type'),
),
);
db_create_table('block_node_type', $schema['block_node_type']);
}
/**
* Rename {blocks} table to {block}, {blocks_roles} to {block_role} and
* {boxes} to {block_custom}.
......
......@@ -637,7 +637,7 @@ function _block_load_blocks() {
/**
* Implements hook_block_info_alter().
*
* Check the page, user role, content type 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.
*/
function block_block_info_alter(&$blocks) {
......@@ -650,15 +650,8 @@ function block_block_info_alter(&$blocks) {
$block_roles[$record->module][$record->delta][] = $record->rid;
}
// Build an array of node types for each block.
$block_node_types = array();
$result = db_query('SELECT module, delta, type FROM {block_node_type}');
foreach ($result as $record) {
$block_node_types[$record->module][$record->delta][] = $record->type;
}
foreach ($blocks as $key => $block) {
if ($block->theme != $theme_key || $block->status != 1) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {
// This block was added by a contrib module, leave it in the list.
continue;
}
......@@ -672,34 +665,6 @@ function block_block_info_alter(&$blocks) {
continue;
}
// If a block has no node types associated, it is displayed for every type.
// For blocks with node types associated, if the node type does not match
// the settings from this block, remove it from the block list.
if (isset($block_node_types[$block->module][$block->delta])) {
$node = menu_get_object();
if (!empty($node)) {
// This is a node or node edit page.
if (!in_array($node->type, $block_node_types[$block->module][$block->delta])) {
// This block should not be displayed for this node type.
unset($blocks[$key]);
continue;
}
}
elseif (arg(0) == 'node' && arg(1) == 'add' && in_array(arg(2), array_keys(node_type_get_types()))) {
// This is a node creation page
if (!in_array(arg(2), $block_node_types[$block->module][$block->delta])) {
// This block should not be displayed for this node type.
unset($blocks[$key]);
continue;
}
}
else {
// This is not a node page, remove the block.
unset($blocks[$key]);
continue;
}
}
// Use the user's block visibility setting, if necessary.
if ($block->custom != 0) {
if ($user->uid && isset($user->block[$block->module][$block->delta])) {
......
......@@ -353,6 +353,34 @@ function node_schema() {
'primary key' => array('type'),
);
$schema['block_node_type'] = array(
'description' => 'Sets up display criteria for blocks based on content types',
'fields' => array(
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => "The block's origin module, from {block}.module.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The block's unique delta within module, from {block}.delta.",
),
'type' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The machine-readable name of this type from {node_type}.type.",
),
),
'primary key' => array('module', 'delta', 'type'),
'indexes' => array(
'type' => array('type'),
),
);
return $schema;
}
......@@ -609,6 +637,41 @@ function node_update_7009() {
->execute();
}
/**
* Add the {block_node_type} table.
*/
function node_update_7010() {
$schema['block_node_type'] = array(
'description' => 'Sets up display criteria for blocks based on content types',
'fields' => array(
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => "The block's origin module, from {block}.module.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The block's unique delta within module, from {block}.delta.",
),
'type' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The machine-readable name of this type from {node_type}.type.",
),
),
'primary key' => array('module', 'delta', 'type'),
'indexes' => array(
'type' => array('type'),
),
);
db_create_table('block_node_type', $schema['block_node_type']);
}
/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.
......
......@@ -2190,6 +2190,8 @@ function theme_node_recent_content($variables) {
* Implements hook_form_FORMID_alter().
*
* Adds node-type specific visibility options to add block form.
*
* @see block_add_block_form()
*/
function node_form_block_add_block_form_alter(&$form, &$form_state) {
node_form_block_admin_configure_alter($form, $form_state);
......@@ -2199,6 +2201,8 @@ function node_form_block_add_block_form_alter(&$form, &$form_state) {
* Implements hook_form_FORMID_alter().
*
* Adds node-type specific visibility options to block configuration form.
*
* @see block_admin_configure()
*/
function node_form_block_admin_configure_alter(&$form, &$form_state) {
$default_type_options = db_query("SELECT type FROM {block_node_type} WHERE module = :module AND delta = :delta", array(
......@@ -2220,13 +2224,15 @@ function node_form_block_admin_configure_alter(&$form, &$form_state) {
'#options' => node_type_get_names(),
'#description' => t('Show this block only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
);
$form['#submit'][] = 'node_block_admin_configure_submit';
$form['#submit'][] = 'node_form_block_admin_configure_submit';
}
/**
* Form submit handler for block configuration form.
*
* @see node_form_block_admin_configure_alter()
*/
function node_block_admin_configure_submit($form, &$form_state) {
function node_form_block_admin_configure_submit($form, &$form_state) {
db_delete('block_node_type')
->condition('module', $form_state['values']['module'])
->condition('delta', $form_state['values']['delta'])
......@@ -2242,6 +2248,96 @@ function node_block_admin_configure_submit($form, &$form_state) {
$query->execute();
}
/**
* Implements hook_form_FORMID_alter().
*
* Adds node specific submit handler to delete custom block form.
*
* @see block_custom_block_delete()
*/
function node_form_block_custom_block_delete_alter(&$form, &$form_state) {
$form['#submit'][] = 'node_form_block_custom_block_delete_submit';
}
/**
* Form submit handler for custom block delete form.
*
* @see node_form_block_custom_block_delete_alter()
*/
function node_form_block_custom_block_delete_submit($form, &$form_state) {
db_delete('block_node_type')
->condition('module', 'block')
->condition('delta', $form_state['values']['bid'])
->execute();
}
/**
* Implements hook_modules_uninstalled().
*
* Cleanup {block_node_type} table from modules' blocks.
*/
function node_modules_uninstalled($modules) {
db_delete('block_node_type')
->condition('module', $modules, 'IN')
->execute();
}
/**
* Implements hook_block_info_alter().
*
* Check the content type specific visibilty settings.
* Remove the block if the visibility conditions are not met.
*/
function node_block_info_alter(&$blocks) {
global $theme_key;
// Build an array of node types for each block.
$block_node_types = array();
$result = db_query('SELECT module, delta, type FROM {block_node_type}');
foreach ($result as $record) {
$block_node_types[$record->module][$record->delta][$record->type] = TRUE;
}
$node = menu_get_object();
$node_types = node_type_get_types();
if (arg(0) == 'node' && arg(1) == 'add' && arg(2)) {
$node_add_arg = strtr(arg(2), '-', '_');
}
foreach ($blocks as $key => $block) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {
// This block was added by a contrib module, leave it in the list.
continue;
}
// If a block has no node types associated, it is displayed for every type.
// For blocks with node types associated, if the node type does not match
// the settings from this block, remove it from the block list.
if (isset($block_node_types[$block->module][$block->delta])) {
if (!empty($node)) {
// This is a node or node edit page.
if (!isset($block_node_types[$block->module][$block->delta][$node->type])) {
// This block should not be displayed for this node type.
unset($blocks[$key]);
continue;
}
}
elseif (isset($node_add_arg) && isset($node_types[$node_add_arg])) {
// This is a node creation page
if (!isset($block_node_types[$block->module][$block->delta][$node_add_arg])) {
// This block should not be displayed for this node type.
unset($blocks[$key]);
continue;
}
}
else {
// This is not a node page, remove the block.
unset($blocks[$key]);
continue;
}
}
}
}
/**
* A generic function for generating RSS feeds from a set of nodes.
*
......
......@@ -1289,7 +1289,7 @@ class NodeBlockFunctionalTest extends DrupalWebTestCase {
}
function setUp() {
parent::setUp('node');
parent::setUp('node', 'block');
// Create users and test node.
$this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'administer blocks'));
......@@ -1379,6 +1379,32 @@ class NodeBlockFunctionalTest extends DrupalWebTestCase {
$this->assertText($node2->title, t('Node found in block.'));
$this->assertText($node3->title, t('Node found in block.'));
$this->assertText($node4->title, t('Node found in block.'));
// Create the custom block.
$custom_block = array();
$custom_block['info'] = $this->randomName();
$custom_block['title'] = $this->randomName();
$custom_block['types[article]'] = TRUE;
$custom_block['body[value]'] = $this->randomName(32);
$custom_block['regions[garland]'] = 'content';
$custom_block['regions[seven]'] = 'content';
$this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
$bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
$this->assertTrue($bid, t('Custom block with visibility rule was created.'));
// Verify visibility rules.
$this->drupalGet('');
$this->assertNoText($custom_block['title'], t('Block was displayed on the front page.'));
$this->drupalGet('node/add/article');
$this->assertText($custom_block['title'], t('Block was displayed on the node/add/article page.'));
$this->drupalGet('node/' . $node1->nid);
$this->assertText($custom_block['title'], t('Block was displayed on the node/N.'));
// Delete the created custom block & verify that it's been deleted.
$this->drupalPost('admin/structure/block/manage/block/' . $bid . '/delete', array(), t('Delete'));
$bid = db_query("SELECT 1 FROM {block_node_type} WHERE module = 'block' AND delta = :delta", array(':delta' => $bid))->fetchField();
$this->assertFalse($bid, t('Custom block was deleted.'));
}
}
/**
......
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