? cache_negotiation.patch
? cache_node_load.patch
? cache_node_load_17.patch
? cache_node_load_18.patch
? cache_redirect_5.patch
? drupal7-sun.drupal-render-translatable_.patch
? hook_block_visibility.patch
? test_bot_on_plz.patch
? translatable_fields.patch
? translatable_fields_0.patch
? translatable_fields_3.patch
? translatable_fields_8.patch
? translation_rendering.patch
? modules/block/.block.module.swp
? modules/simpletest/tests/.bootstrap.test.swp
? sites/default/files
? sites/default/settings.php
Index: modules/block/block.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.api.php,v
retrieving revision 1.3
diff -u -p -r1.3 block.api.php
--- modules/block/block.api.php	26 Jan 2009 14:08:42 -0000	1.3
+++ modules/block/block.api.php	6 Feb 2009 18:22:29 -0000
@@ -172,5 +172,29 @@ function hook_block_view($delta = '') {
 }
 
 /**
+ * Remove blocks from the list to display if they do not meet certain
+ * conditions.
+ *
+ * @param $blocks
+ *   An array of $blocks, keyed by $module . $delta
+ */
+function hook_block_visibility(&$blocks) {
+  global $language;
+  $result = db_query('SELECT module, delta, language FROM {my_table}')->fetchAll();
+  $block_languages = array();
+  foreach ($result as $record) {
+    $block_languages[$record->module . $record->delta][] = $record->language;
+  }
+  // If a block has no language associations, we assume it's language neutral.
+  // So build an array only of blocks with such associations.
+  $blocks_by_language = array_keys(array_intersect_key($blocks, $block_languages));
+  foreach ($blocks_by_language as $block) {
+    if (!in_array($language->language, $block_languages[$block])) {
+      unset($blocks[$block]);
+    }
+  }
+}
+
+/**
  * @} End of "addtogroup hooks".
  */
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.321
diff -u -p -r1.321 block.module
--- modules/block/block.module	3 Feb 2009 12:30:14 -0000	1.321
+++ modules/block/block.module	6 Feb 2009 18:22:29 -0000
@@ -471,15 +471,55 @@ function block_list($region) {
  * Load blocks information from the database.
  */
 function _block_load_blocks() {
-  global $user, $theme_key;
+  global $theme_key;
+
+  $queried_blocks = array();
+  $result = db_query('SELECT * FROM {block} WHERE theme = :theme AND status = 1 ORDER BY region, weight, module', array(':theme' => $theme_key));
+  foreach ($result as $record) {
+    $queried_blocks[$record->module . $record->delta] = $record;
+  }
+
+  // Invoke hook_block_visibility() to filter out any blocks not matched by
+  // block visibility rules.
+  foreach (module_implements('block_visibility') as $module) {
+    $function = $module . '_block_visibility';
+    $function($queried_blocks);
+  }
 
   $blocks = array();
-  $rids = array_keys($user->roles);
-  $result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {block} b LEFT JOIN {block_role} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (" . db_placeholders($rids) . ") OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key), $rids));
-  while ($block = db_fetch_object($result)) {
-    if (!isset($blocks[$block->region])) {
-      $blocks[$block->region] = array();
+  foreach ($queried_blocks as $key => $block) {
+    $blocks[$block->region][$block->module . '_' . $block->delta] = $block;
+  }
+
+  return $blocks;
+}
+
+/**
+ * Implementation of hook_block_visibility().
+ */
+function block_block_visibility(&$blocks) {
+  global $user;
+
+  // Build an array of roles for each block.
+  $blocks_roles = array();
+  $result = db_query('SELECT module, delta, rid FROM {block_role}')->fetchAll();
+  foreach ($result as $record) {
+    $blocks_roles[$record->module . $record->delta][] = $record->rid;
+  }
+
+  // If a block has no roles associated, it is displayed for every role.
+  $blocks_by_role = array_keys(array_intersect_key($blocks, $blocks_roles));
+
+  // For blocks with roles associated, if none of the user's roles matches
+  // the settings from this block, remove it from the array.
+  foreach ($blocks_by_role as $block) {
+    if (!array_intersect($blocks_roles[$block], array_keys($user->roles))) {
+      unset($blocks[$block]);
     }
+  }
+
+  foreach ($blocks as $key => $block) {
+
     // Use the user's block visibility setting, if necessary.
     if ($block->custom != 0) {
       if ($user->uid && isset($user->block[$block->module][$block->delta])) {
@@ -492,6 +532,10 @@ function _block_load_blocks() {
     else {
       $enabled = TRUE;
     }
+    if (!$enabled) {
+      unset($blocks[$key]);
+      continue;
+    }
 
     // Match path if necessary.
     if ($block->pages) {
@@ -514,12 +558,11 @@ function _block_load_blocks() {
     else {
       $page_match = TRUE;
     }
-    $block->enabled = $enabled;
-    $block->page_match = $page_match;
-    $blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
-  }
 
-  return $blocks;
+    if (!$page_match) {
+      unset($blocks[$key]);
+    }
+  }
 }
 
 /**
@@ -537,36 +580,34 @@ function _block_render_blocks($region_bl
     if (!isset($block->content)) {
       // Erase the block from the static array - we'll put it back if it has content.
       unset($region_blocks[$key]);
-      if ($block->enabled && $block->page_match) {
-        // 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'))) {
-          $array = $cache->data;
-        }
-        else {
-          $array = module_invoke($block->module, 'block_view', $block->delta);
-          if (isset($cid)) {
-            cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);
-          }
+      // 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'))) {
+        $array = $cache->data;
+      }
+      else {
+        $array = module_invoke($block->module, 'block_view', $block->delta);
+        if (isset($cid)) {
+          cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);
         }
+      }
 
-        if (isset($array) && is_array($array)) {
-          foreach ($array as $k => $v) {
-            $block->$k = $v;
-          }
+      if (isset($array) && is_array($array)) {
+        foreach ($array as $k => $v) {
+          $block->$k = $v;
+        }
+      }
+      if (isset($block->content) && $block->content) {
+        // Override default block title if a custom display title is present.
+        if ($block->title) {
+          // Check plain here to allow module generated titles to keep any markup.
+          $block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
         }
-        if (isset($block->content) && $block->content) {
-          // Override default block title if a custom display title is present.
-          if ($block->title) {
-            // Check plain here to allow module generated titles to keep any markup.
-            $block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
-          }
-          if (!isset($block->subject)) {
-            $block->subject = '';
-          }
-          $region_blocks["{$block->module}_{$block->delta}"] = $block;
+        if (!isset($block->subject)) {
+          $block->subject = '';
         }
+        $region_blocks["{$block->module}_{$block->delta}"] = $block;
       }
     }
   }
