summaryrefslogtreecommitdiff
path: root/modules/block
diff options
context:
space:
mode:
Diffstat (limited to 'modules/block')
-rw-r--r--modules/block/block.api.php73
-rw-r--r--modules/block/block.js24
-rw-r--r--modules/block/block.module19
-rw-r--r--modules/block/block.test66
4 files changed, 120 insertions, 62 deletions
diff --git a/modules/block/block.api.php b/modules/block/block.api.php
index d33f59425..3cd52f8b7 100644
--- a/modules/block/block.api.php
+++ b/modules/block/block.api.php
@@ -20,11 +20,11 @@
* identifier referred to as "delta" (the array key in the return value). Delta
* values only need to be unique within your module, and they are used in the
* following ways:
- * - Passed into the other block hooks in your module as an argument to
- * identify the block being configured or viewed.
+ * - Passed into the other block hooks in your module as an argument to identify
+ * the block being configured or viewed.
* - Used to construct the default HTML ID of "block-MODULE-DELTA" applied to
- * each block when it is rendered (which can then be used for CSS styling or
- * JavaScript programming).
+ * each block when it is rendered. This ID may then be used for CSS styling or
+ * JavaScript programming.
* - Used to define a theming template suggestion of block__MODULE__DELTA, for
* advanced theming possibilities.
* - Used by other modules to identify your block in hook_block_info_alter() and
@@ -39,43 +39,43 @@
* An associative array whose keys define the delta for each block and whose
* values contain the block descriptions. Each block description is itself an
* associative array, with the following key-value pairs:
- * - 'info': (required) The human-readable administrative name of the block.
- * This is used to identify the block on administration screens, and
- * is not displayed to non-administrative users.
- * - 'cache': (optional) A bitmask describing what kind of caching is
+ * - info: (required) The human-readable administrative name of the block.
+ * This is used to identify the block on administration screens, and is not
+ * displayed to non-administrative users.
+ * - cache: (optional) A bitmask describing what kind of caching is
* appropriate for the block. Drupal provides the following bitmask
* constants for defining cache granularity:
* - DRUPAL_CACHE_PER_ROLE (default): The block can change depending on the
* roles the user viewing the page belongs to.
* - DRUPAL_CACHE_PER_USER: The block can change depending on the user
- * viewing the page. This setting can be resource-consuming for sites
- * with large number of users, and should only be used when
+ * viewing the page. This setting can be resource-consuming for sites with
+ * large number of users, and should only be used when
* DRUPAL_CACHE_PER_ROLE is not sufficient.
- * - DRUPAL_CACHE_PER_PAGE: The block can change depending on the page
- * being viewed.
- * - DRUPAL_CACHE_GLOBAL: The block is the same for every user on every
- * page where it is visible.
+ * - DRUPAL_CACHE_PER_PAGE: The block can change depending on the page being
+ * viewed.
+ * - DRUPAL_CACHE_GLOBAL: The block is the same for every user on every page
+ * where it is visible.
* - DRUPAL_NO_CACHE: The block should not get cached.
- * - 'properties': (optional) Array of additional metadata to add to the
- * block. Common properties include:
- * - 'administrative': Boolean which categorizes this block as usable in
- * an administrative context. This might include blocks which help an
- * administrator approve/deny comments, or view recently created
- * user accounts.
- * - 'weight': (optional) Initial value for the ordering weight of this block.
+ * - properties: (optional) Array of additional metadata to add to the block.
+ * Common properties include:
+ * - administrative: Boolean that categorizes this block as usable in an
+ * administrative context. This might include blocks that help an
+ * administrator approve/deny comments, or view recently created user
+ * accounts.
+ * - weight: (optional) Initial value for the ordering weight of this block.
* Most modules do not provide an initial value, and any value provided can
* be modified by a user on the block configuration screen.
- * - 'status': (optional) Initial value for block enabled status. (1 =
- * enabled, 0 = disabled). Most modules do not provide an initial value,
- * and any value provided can be modified by a user on the block
- * configuration screen.
- * - 'region': (optional) Initial value for theme region within which this
- * block is set. Most modules do not provide an initial value, and
- * any value provided can be modified by a user on the block configuration
- * screen. Note: If you set a region that isn't available in the currently
- * enabled theme, the block will be disabled.
- * - 'visibility': (optional) Initial value for the visibility flag, which
- * tells how to interpret the 'pages' value. Possible values are:
+ * - status: (optional) Initial value for block enabled status. (1 = enabled,
+ * 0 = disabled). Most modules do not provide an initial value, and any
+ * value provided can be modified by a user on the block configuration
+ * screen.
+ * - region: (optional) Initial value for theme region within which this
+ * block is set. Most modules do not provide an initial value, and any value
+ * provided can be modified by a user on the block configuration screen.
+ * Note: If you set a region that isn't available in the currently enabled
+ * theme, the block will be disabled.
+ * - visibility: (optional) Initial value for the visibility flag, which tells
+ * how to interpret the 'pages' value. Possible values are:
* - BLOCK_VISIBILITY_NOTLISTED: Show on all pages except listed pages.
* 'pages' lists the paths where the block should not be shown.
* - BLOCK_VISIBILITY_LISTED: Show only on listed pages. 'pages' lists the
@@ -85,7 +85,14 @@
* Most modules do not provide an initial value for 'visibility' or 'pages',
* and any value provided can be modified by a user on the block
* configuration screen.
- * - 'pages': (optional) See 'visibility' above.
+ * - pages: (optional) See 'visibility' above. A string that contains one or
+ * more page paths separated by '\n', '\r', or '\r\n' when 'visibility' is
+ * set to BLOCK_VISIBILITY_NOTLISTED or BLOCK_VISIBILITY_LISTED, or custom
+ * PHP code when 'visibility' is set to BLOCK_VISIBILITY_PHP. Paths may use
+ * '*' as a wildcard (matching any number of characters); '<front>'
+ * designates the site's front page. For BLOCK_VISIBILITY_PHP, the PHP
+ * code's return value should be TRUE if the block is to be made visible or
+ * FALSE if the block should not be visible.
*
* For a detailed usage example, see block_example.module.
*
diff --git a/modules/block/block.js b/modules/block/block.js
index ce4995dca..acd3f5ae2 100644
--- a/modules/block/block.js
+++ b/modules/block/block.js
@@ -113,28 +113,12 @@ Drupal.behaviors.blockDrag = {
$('select.block-region-select', context).once('block-region-select', function () {
$(this).change(function (event) {
// Make our new row and select field.
- var row = $(this).parents('tr:first');
+ var row = $(this).closest('tr');
var select = $(this);
tableDrag.rowObject = new tableDrag.row(row);
- // Find the correct region and insert the row as the first in the region.
- $('tr.region-message', table).each(function () {
- if ($(this).is('.region-' + select[0].value + '-message')) {
- // Add the new row and remove the old one.
- $(this).after(row);
- // Manually update weights and restripe.
- tableDrag.updateFields(row.get(0));
- tableDrag.rowObject.changed = true;
- if (tableDrag.oldRowElement) {
- $(tableDrag.oldRowElement).removeClass('drag-previous');
- }
- tableDrag.oldRowElement = row.get(0);
- tableDrag.restripeTable();
- tableDrag.rowObject.markChanged();
- tableDrag.oldRowElement = row;
- $(row).addClass('drag-previous');
- }
- });
+ // Find the correct region and insert the row as the last in the region.
+ table.find('.region-' + select[0].value + '-message').nextUntil('.region-message').last().before(row);
// Modify empty regions with added or removed fields.
checkEmptyRegions(table, row);
@@ -153,7 +137,7 @@ Drupal.behaviors.blockDrag = {
}
}
// This region has become empty.
- if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) {
+ if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').length == 0) {
$(this).removeClass('region-populated').addClass('region-empty');
}
// This region has become populated.
diff --git a/modules/block/block.module b/modules/block/block.module
index 24319089e..70f55e5ab 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -48,11 +48,11 @@ function block_help($path, $arg) {
case 'admin/help#block':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
- $output .= '<p>' . t('The Block module allows you to create boxes of content, which are rendered into an area, or region, of one or more pages of a website. The core Seven administration theme, for example, implements the regions "Content", "Help", "Dashboard main", and "Dashboard sidebar", and a block may appear in any one of these regions. The <a href="@blocks">Blocks administration page</a> provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. For more information, see the online handbook entry for <a href="@block">Block module</a>.', array('@block' => 'http://drupal.org/handbook/modules/block/', '@blocks' => url('admin/structure/block'))) . '</p>';
+ $output .= '<p>' . t('The Block module allows you to create boxes of content, which are rendered into an area, or region, of one or more pages of a website. The core Seven administration theme, for example, implements the regions "Content", "Help", "Dashboard main", and "Dashboard sidebar", and a block may appear in any one of these regions. The <a href="@blocks">Blocks administration page</a> provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. For more information, see the online handbook entry for <a href="@block">Block module</a>.', array('@block' => 'http://drupal.org/documentation/modules/block/', '@blocks' => url('admin/structure/block'))) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Positioning content') . '</dt>';
- $output .= '<dd>' . t('When working with blocks, remember that all themes do <em>not</em> implement the same regions, or display regions in the same way. Blocks are positioned on a per-theme basis. Users with the <em>Administer blocks</em> permission can disable blocks. Disabled blocks are listed on the <a href="@blocks">Blocks administration page</a>, but are not displayed in any region.', array('@block' => 'http://drupal.org/handbook/modules/block/', '@blocks' => url('admin/structure/block'))) . '</dd>';
+ $output .= '<dd>' . t('When working with blocks, remember that all themes do <em>not</em> implement the same regions, or display regions in the same way. Blocks are positioned on a per-theme basis. Users with the <em>Administer blocks</em> permission can disable blocks. Disabled blocks are listed on the <a href="@blocks">Blocks administration page</a>, but are not displayed in any region.', array('@block' => 'http://drupal.org/documentation/modules/block/', '@blocks' => url('admin/structure/block'))) . '</dd>';
$output .= '<dt>' . t('Controlling visibility') . '</dt>';
$output .= '<dd>' . t('Blocks can be configured to be visible only on certain pages, only to users of certain roles, or only on pages displaying certain <a href="@content-type">content types</a>. Administrators can also allow specific blocks to be enabled or disabled by users when they edit their <a href="@user">My account</a> page. Some dynamic blocks, such as those generated by modules, will be displayed only on certain pages.', array('@content-type' => url('admin/structure/types'), '@user' => url('user'))) . '</dd>';
$output .= '<dt>' . t('Creating custom blocks') . '</dt>';
@@ -432,10 +432,10 @@ function _block_rehash($theme = NULL) {
if (!isset($block['weight'])) {
$block['weight'] = 0;
}
- if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']])) {
+ 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 bock to another region.
+ // need to move the block to another region.
$block['status'] = 0;
}
// Set region to none if not enabled and make sure status is set.
@@ -836,17 +836,18 @@ function block_block_list_alter(&$blocks) {
* An array of visible blocks as expected by drupal_render().
*/
function _block_render_blocks($region_blocks) {
+ // Block caching is not compatible with node access modules. We also
+ // preserve the submission of forms in blocks, by fetching from cache only
+ // if the request method is 'GET' (or 'HEAD').
+ $cacheable = !count(module_implements('node_grants')) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
foreach ($region_blocks as $key => $block) {
// Render the block content if it has not been created already.
if (!isset($block->content)) {
// Erase the block from the static array - we'll put it back if it has
// content.
unset($region_blocks[$key]);
- // Try fetching the block from cache. Block caching is not compatible
- // with node_access modules. We also preserve the submission of forms in
- // blocks, by fetching from cache only if the request method is 'GET'
- // (or 'HEAD').
- if (!count(module_implements('node_grants')) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && ($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) {
+ // Try fetching the block from cache.
+ if ($cacheable && ($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) {
$array = $cache->data;
}
else {
diff --git a/modules/block/block.test b/modules/block/block.test
index 323034062..cdd0d4589 100644
--- a/modules/block/block.test
+++ b/modules/block/block.test
@@ -791,3 +791,69 @@ class BlockHiddenRegionTestCase extends DrupalWebTestCase {
$this->assertText('Search form', t('Block was displayed on the front page.'));
}
}
+
+/**
+ * Tests that a block assigned to an invalid region triggers the warning.
+ */
+class BlockInvalidRegionTestCase extends DrupalWebTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Blocks in invalid regions',
+ 'description' => 'Checks that an active block assigned to a non-existing region triggers the warning message and is disabled.',
+ 'group' => 'Block',
+ );
+ }
+
+ function setUp() {
+ parent::setUp(array('block', 'block_test'));
+ // Create an admin user.
+ $admin_user = $this->drupalCreateUser(array('administer site configuration', 'access administration pages'));
+ $this->drupalLogin($admin_user);
+ }
+
+ /**
+ * Tests that blocks assigned to invalid regions work correctly.
+ */
+ function testBlockInInvalidRegion() {
+ // Enable a test block in the default theme and place it in an invalid region.
+ db_merge('block')
+ ->key(array(
+ 'module' => 'block_test',
+ 'delta' => 'test_html_id',
+ 'theme' => variable_get('theme_default', 'stark'),
+ ))
+ ->fields(array(
+ 'status' => 1,
+ 'region' => 'invalid_region',
+ 'cache' => DRUPAL_NO_CACHE,
+ ))
+ ->execute();
+
+ $warning_message = t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => t('Test block html id'), '%region' => 'invalid_region'));
+
+ // Clearing the cache should disable the test block placed in the invalid region.
+ $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
+ $this->assertRaw($warning_message, 'Enabled block was in the invalid region and has been disabled.');
+
+ // Clear the cache to check if the warning message is not triggered.
+ $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
+ $this->assertNoRaw($warning_message, 'Disabled block in the invalid region will not trigger the warning.');
+
+ // Place disabled test block in the invalid region of the default theme.
+ db_merge('block')
+ ->key(array(
+ 'module' => 'block_test',
+ 'delta' => 'test_html_id',
+ 'theme' => variable_get('theme_default', 'stark'),
+ ))
+ ->fields(array(
+ 'region' => 'invalid_region',
+ 'cache' => DRUPAL_NO_CACHE,
+ ))
+ ->execute();
+
+ // Clear the cache to check if the warning message is not triggered.
+ $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
+ $this->assertNoRaw($warning_message, 'Disabled block in the invalid region will not trigger the warning.');
+ }
+}