? .buildpath
? .project
? .settings
? 235673-block-caching-fix-D7.patch
? 409598.patch
? pager_limits.patch
? sites/all/modules/admin_menu
? sites/all/modules/admin_menu.tar.gz
? sites/all/modules/devel
? sites/all/modules/devel.tar.gz
? sites/default/files
? sites/default/settings.php
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.35
diff -u -p -r1.35 block.admin.inc
--- modules/block/block.admin.inc	11 Feb 2009 03:38:46 -0000	1.35
+++ modules/block/block.admin.inc	4 Apr 2009 15:41:05 -0000
@@ -15,8 +15,10 @@ function block_admin_display($theme = NU
   // If non-default theme configuration has been selected, set the custom theme.
   $custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
 
+  init_theme();
+  
   // Fetch and sort blocks.
-  $blocks = _block_rehash();
+  $blocks = _block_rehash($custom_theme);
   usort($blocks, '_block_compare');
 
   return drupal_get_form('block_admin_display_form', $blocks, $theme);
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.324
diff -u -p -r1.324 block.module
--- modules/block/block.module	17 Mar 2009 03:42:30 -0000	1.324
+++ modules/block/block.module	4 Apr 2009 15:41:05 -0000
@@ -283,78 +283,101 @@ function block_get_blocks_by_region($reg
 /**
  * Update the 'block' DB table with the blocks currently exported by modules.
  *
+ * @param $only_theme
+ *   The name of the theme whose blocks should be updated.
+ *   If NULL, updates blocks for all enabled themes.
+ *
  * @return
  *   Blocks currently exported by modules.
+ *   An array of blocks for themes, keyed by theme names.
  */
-function _block_rehash() {
-  global $theme_key;
+function _block_rehash($only_theme = NULL) {
 
-  init_theme();
+  if (is_null($only_theme)) {
+    foreach(list_themes() as $theme) {
+      if ($theme->status || $theme->name == variable_get('admin_theme', '0')) {
+        $themes[] = $theme->name;
+      }
+    }
+    $result = db_query("SELECT * FROM {block}");
+  }
+  else {
+    $themes = array($only_theme);
+    $result = db_query("SELECT * FROM {block} WHERE theme = '%s'", $only_theme);
+  }
 
-  $result = db_query("SELECT * FROM {block} WHERE theme = '%s'", $theme_key);
   $old_blocks = array();
   while ($old_block = db_fetch_array($result)) {
-    $old_blocks[$old_block['module']][$old_block['delta']] = $old_block;
+    $old_blocks[$old_block['theme']][$old_block['module']][$old_block['delta']] = $old_block;
   }
 
   $blocks = array();
-  // Valid region names for the theme.
-  $regions = system_region_list($theme_key);
-
   foreach (module_implements('block_list') as $module) {
     $module_blocks = module_invoke($module, 'block_list');
     if ($module_blocks) {
-      foreach ($module_blocks as $delta => $block) {
-        if (empty($old_blocks[$module][$delta])) {
-          // If it's a new block, add identifiers.
-          $block['module'] = $module;
-          $block['delta']  = $delta;
-          $block['theme']  = $theme_key;
-          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']  = '';
-          }
-          // 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;
+      foreach($themes as $theme) {
+        // Valid region names for the theme.
+        $regions = system_region_list($theme);        
+        foreach ($module_blocks as $delta => $block) {
+          if (empty($old_blocks[$theme][$module][$delta])) {
+            // If it's a new block, add identifiers.
+            $block['module'] = $module;
+            $block['delta']  = $delta;
+            $block['theme']  = $theme;
+            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']  = '';
+            }
+            // 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[$theme][] = $block;   
           }
           else {
-            $old_blocks[$module][$delta]['region'] = $old_blocks[$module][$delta]['status'] ? $old_blocks[$module][$delta]['region'] : BLOCK_REGION_NONE;
+            $old_block = $old_blocks[$theme][$module][$delta];
+            // For existing block, database settings should overwrite the code,
+            // except for possible changes in the cache mode.
+            if ((!isset($block['cache']) && $old_block['cache'] != BLOCK_CACHE_PER_ROLE) || (isset($block['cache']) && $old_block['cache'] != $block['cache'])) {
+              $old_block['cache'] = isset($block['cache']) ? $block['cache'] : BLOCK_CACHE_PER_ROLE;
+              drupal_write_record('block', $old_block, array('module', 'delta', 'theme'));
+              cache_clear_all("$module:$delta:", 'cache_block', TRUE);
+            }
+            // 'info' is the only thing that's definable in code but not stored
+            // in the database.
+            $old_block['info'] = $block['info'];
+            // If the region name does not exist, disable the block and assign it to none.
+            if (!empty($old_block['region']) && !isset($regions[$old_block['region']])) {
+              drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $old_block['info'], '%region' => $old_block['region'])), 'warning');
+              $old_block['status'] = 0;
+              $old_block['region'] = BLOCK_REGION_NONE;
+            }
+            else {
+              $old_block['region'] = $old_block['status'] ? $old_block['region'] : BLOCK_REGION_NONE;
+            }
+            // Add this block to the list of blocks we return.
+            $blocks[$theme][] = $old_block;
+            // Remove this block from the list of blocks to be deleted.
+            unset($old_blocks[$theme][$module][$delta]);
           }
-          // 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]);
         }
       }
     }
   }
 
   // Remove blocks that are no longer defined by the code from the database.
-  foreach ($old_blocks as $module => $old_module_blocks) {
-    foreach ($old_module_blocks as $delta => $block) {
-      db_query("DELETE FROM {block} WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $module, $delta, $theme_key);
+  foreach ($old_blocks as $theme => $old_theme_blocks) {
+    foreach ($old_theme_blocks as $module => $old_module_blocks) {
+      foreach ($old_module_blocks as $delta => $block) {
+        db_query("DELETE FROM {block} WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $module, $delta, $theme);
+      }  
     }
   }
-  return $blocks;
+  
+  return is_null($only_theme) ? $blocks : $blocks[$only_theme];
 }
 
 function block_box_get($bid) {
Index: modules/block/block.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.test,v
retrieving revision 1.14
diff -u -p -r1.14 block.test
--- modules/block/block.test	31 Mar 2009 01:49:50 -0000	1.14
+++ modules/block/block.test	4 Apr 2009 15:41:05 -0000
@@ -43,7 +43,7 @@ class BlockTestCase extends DrupalWebTes
     $this->assertText(t('The block has been created.'), t('Box successfully created.'));
     $bid = db_result(db_query("SELECT bid FROM {box} WHERE info = '%s'", array($box['info'])));
 
-    // Check to see if the box was created by checking that it's in the database..
+    // Check to see if the box was created by checking that it's in the database.
     $this->assertNotNull($bid, t('Box found in database'));
 
     // Check if the block can be moved to all availble regions.
@@ -100,7 +100,7 @@ class BlockTestCase extends DrupalWebTes
     // Check to see if the block was created by checking that it's in the database.
     $this->assertNotNull($bid, t('Block found in database'));
 
-    // Check if the block can be moved to all availble regions.
+    // Check if the block can be moved to all available regions.
     foreach ($this->regions as $region) {
       $this->moveBlockToRegion($block, $region);
     }
@@ -151,6 +151,73 @@ class BlockTestCase extends DrupalWebTes
   }
 }
 
+class BlockCachingTestCase extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => t('Block caching'),
+      'description' => t('Test various aspects of the block caching system.'),
+      'group' => t('Block'),
+    );
+  }
+
+  function setUp() {
+    parent::setUp("block_test");
+
+    // Create and login user
+    $admin_user = $this->drupalCreateUser(array('administer blocks'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Validate the behavior of the block caching layer.
+   */
+  function testCaching() {
+    variable_set('block_cache', 1);
+    variable_set('block_test_content',  $this->randomName(20));
+
+    // Display the test block.
+    $edit = array();
+    $edit['block_test_test_block[region]'] = 'left';
+    $this->drupalPost('admin/build/block', $edit, t('Save blocks'));
+
+    // Confirm that the test block is displayed.
+    $this->assertText(variable_get('block_test_content', ''), t('(NO_CACHE) Test block successfully being displayed on the page.'));
+
+    // Try changing the test block contents.
+    variable_set('block_test_content', $this->randomName(20));
+    $this->drupalGet('');
+    $this->assertText(variable_get('block_test_content', ''), t('(NO_CACHE) Test block content successfully changed.'));
+
+    // Change the caching of the test block.
+    variable_set('block_test_caching', BLOCK_CACHE_GLOBAL);
+    $this->drupalPost('admin/build/block', array(), t('Save blocks'));
+
+    // Try changing the test block contents.
+    $this->drupalGet('');
+    $this->assertText(variable_get('block_test_content', ''), t('(CACHE_GLOBAL) Test block content is still there.'));
+    variable_set('block_test_content', $data = $this->randomName(20));
+    $this->drupalGet('');
+    $this->assertNoText(variable_get('block_test_content', ''), t('(CACHE_GLOBAL) Test block content has been cached.'));
+
+    // Empty caches.
+    cache_clear_all(NULL, 'cache_block');
+    $this->drupalGet('');
+    $this->assertText(variable_get('block_test_content', ''), t('(CACHE_GLOBAL) Test block content changed after cache_clear_all().'));
+
+    // Back to no caching.
+    variable_set('block_test_caching', BLOCK_NO_CACHE);
+    $this->drupalPost('admin/build/block', array(), t('Save blocks'));
+
+    // Try changing the test block contents.
+    $this->drupalGet('');
+    $this->assertText(variable_get('block_test_content', ''), t('(NO_CACHE) Test block content is still there.'));
+    variable_set('block_test_content', $this->randomName(20));
+    $this->drupalGet('');
+    $this->assertText(variable_get('block_test_content', ''), t('(NO_CACHE) Test block content successfully changed.'));
+  }
+}
+
 class NonDefaultBlockAdmin extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
Index: modules/simpletest/tests/block_test.info
===================================================================
RCS file: modules/simpletest/tests/block_test.info
diff -N modules/simpletest/tests/block_test.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/block_test.info	4 Apr 2009 15:41:07 -0000
@@ -0,0 +1,8 @@
+; $Id$
+name = "Block Test"
+description = "Support module for testing the Block module."
+package = Testing
+version = VERSION
+core = 7.x
+files[] = block_test.module
+hidden = TRUE
\ No newline at end of file
Index: modules/simpletest/tests/block_test.module
===================================================================
RCS file: modules/simpletest/tests/block_test.module
diff -N modules/simpletest/tests/block_test.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/block_test.module	4 Apr 2009 15:41:07 -0000
@@ -0,0 +1,33 @@
+<?php
+// $Id $
+
+/**
+ * @file
+ * Create various blocks for testing purpose.
+ */
+
+/**
+ * Implementation of hook_block_list().
+ */
+function block_test_block_list() {
+  $blocks = array();
+
+  $blocks['test_block'] = array(
+    'info' => t('Test block'),
+    'cache' => variable_get('block_test_caching', BLOCK_NO_CACHE),
+  );
+
+  return $blocks;
+}
+
+/**
+ * Implementation of hook_block_view().
+ */
+function block_test_block_view($delta = 0, $edit = array()) {
+  if ($delta == 'test_block') {
+    return array(
+      'subject' => t('Test block'),
+      'content' => variable_get('block_test_content', ''),
+    );
+  }
+}
