Index: modules/block/block.schema =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.schema,v retrieving revision 1.1 diff -u -r1.1 block.schema --- modules/block/block.schema 25 May 2007 12:46:43 -0000 1.1 +++ modules/block/block.schema 23 Jun 2007 00:35:07 -0000 @@ -44,6 +44,8 @@ 'primary key' => array('bid'), ); + $schema['cache_block'] = drupal_get_schema_unprocessed('system', 'cache'); + return $schema; } Index: modules/block/block.module =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.module,v retrieving revision 1.266 diff -u -r1.266 block.module --- modules/block/block.module 22 Jun 2007 08:32:26 -0000 1.266 +++ modules/block/block.module 23 Jun 2007 00:27:41 -0000 @@ -13,6 +13,19 @@ define('BLOCK_REGION_NONE', -1); /** + * Flags defining cache granularity for cached blocks. + * + * BLOCK_CACHE_CUSTOM lets modules define their own critrions + * using hook_block('cache_id'). + */ +define('BLOCK_NO_CACHE', -1); +define('BLOCK_CACHE_GLOBAL', 0x0001); +define('BLOCK_CACHE_PER_PAGE', 0x0002); +define('BLOCK_CACHE_PER_USER', 0x0004); +define('BLOCK_CACHE_PER_ROLE', 0x0008); +define('BLOCK_CACHE_CUSTOM', 0x0010); + +/** * Implementation of hook_help(). */ function block_help($section) { @@ -217,7 +230,7 @@ /** * Generate main block administration form. */ -function block_admin_display($theme = NULL) { +function block_admin_display(&$form_state, $theme = NULL) { global $theme_key, $custom_theme; // Add CSS @@ -379,7 +392,7 @@ /** * Menu callback; displays the block configuration form. */ -function block_admin_configure($module = NULL, $delta = 0) { +function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { $form['module'] = array('#type' => 'value', '#value' => $module); $form['delta'] = array('#type' => 'value', '#value' => $delta); @@ -524,8 +537,8 @@ /** * Menu callback: display the custom block addition form. */ -function block_add_block_form() { - return block_admin_configure('block', NULL); +function block_add_block_form(&$form_state) { + return block_admin_configure($form_state, 'block', NULL); } function block_add_block_form_validate($form, &$form_state) { @@ -728,7 +741,17 @@ // Check the current throttle status and see if block should be displayed // based on server load. if (!($block->throttle && (module_invoke('throttle', 'status') > 0))) { - $array = module_invoke($block->module, 'block', 'view', $block->delta); + // Try fetching block from cache. + if (($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) { + $array = unserialize($cache->data); + } + else { + $array = module_invoke($block->module, 'block', 'view', $block->delta); + if ($cid) { + cache_set($cid, $array, 'cache_block', variable_get('cache_lifetime', CACHE_TEMPORARY)); + } + } + if (isset($array) && is_array($array)) { foreach ($array as $k => $v) { $block->$k = $v; @@ -752,3 +775,42 @@ } return $blocks[$region]; } + +function _block_get_cache_id($block) { + global $theme, $base_root, $user; + + if (variable_get('block_cache', 0) && $block->cache_mode != BLOCK_NO_CACHE && $user->uid != 1) { + $base_cid = "$block->module:$block->delta:$theme"; + if (module_exists('locale')) { + global $language; + $base_cid .= ":$language->language"; + } + + // Use 'per role' as a default. + if (!isset($block->cache_mode)) { + $block->cache_mode = BLOCK_CACHE_PER_ROLE; + } + + $cid_parts = array(); + + // Let hook_block($op = 'cid') define specific granularity. + if ($block->cache_mode & BLOCK_CACHE_CUSTOM) { + $cid_parts[] = module_invoke($block->module, 'block', 'cache_id', $block->delta); + } + + // 'per role' and 'per user' are mutually exclusive : + // we favor the less expensive 'per role'. + if ($block->cache_mode & BLOCK_CACHE_PER_ROLE) { + $cid_parts[] = 'r_'. implode(',', array_keys($user->roles)); + } + elseif ($block->cache_mode & BLOCK_CACHE_PER_USER) { + $cid_parts[] = "u_$user->uid"; + } + + if ($block->cache_mode & BLOCK_CACHE_PER_PAGE) { + $cid_parts[] = $base_root . request_uri(); + } + + return "$base_cid:". implode(':', $cid_parts); + } +} \ No newline at end of file Index: modules/menu/menu.module =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v retrieving revision 1.117 diff -u -r1.117 menu.module --- modules/menu/menu.module 22 Jun 2007 08:32:27 -0000 1.117 +++ modules/menu/menu.module 23 Jun 2007 00:27:42 -0000 @@ -520,6 +520,8 @@ foreach ($custom_menus as $name => $title) { // Default "Navigation" block is handled by user.module. $blocks[$name]['info'] = check_plain($title); + // menu blocks might be different on every page + $blocks[$name]['cache_mode'] = BLOCK_NO_CACHE; } return $blocks; } Index: modules/search/search.module =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.module,v retrieving revision 1.226 diff -u -r1.226 search.module --- modules/search/search.module 22 Jun 2007 08:32:28 -0000 1.226 +++ modules/search/search.module 23 Jun 2007 00:27:44 -0000 @@ -144,6 +144,7 @@ function search_block($op = 'list', $delta = 0) { if ($op == 'list') { $blocks[0]['info'] = t('Search form'); + $blocks[0]['cache_mode'] = BLOCK_CACHE_GLOBAL; return $blocks; } else if ($op == 'view' && user_access('search content')) { Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.802 diff -u -r1.802 user.module --- modules/user/user.module 22 Jun 2007 08:46:16 -0000 1.802 +++ modules/user/user.module 23 Jun 2007 00:27:49 -0000 @@ -599,10 +599,14 @@ if ($op == 'list') { $blocks[0]['info'] = t('User login'); + // Contains a redirect url which changes each page view. + $blocks[0]['cache_mode'] = BLOCK_CACHE_PER_PAGE; $blocks[1]['info'] = t('Navigation'); + $blocks[1]['cache_mode'] = BLOCK_CACHE_PER_PAGE & BLOCK_CACHE_PER_USER; $blocks[2]['info'] = t('Who\'s new'); + // too dynamic to cache $blocks[3]['info'] = t('Who\'s online'); - + $blocks[3]['cache_mode'] = BLOCK_NO_CACHE; return $blocks; } else if ($op == 'configure' && $delta == 2) { Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.835 diff -u -r1.835 node.module --- modules/node/node.module 22 Jun 2007 08:32:27 -0000 1.835 +++ modules/node/node.module 23 Jun 2007 00:27:43 -0000 @@ -1896,6 +1896,7 @@ function node_block($op = 'list', $delta = 0) { if ($op == 'list') { $blocks[0]['info'] = t('Syndicate'); + $blocks[0]['cache_mode'] = BLOCK_CACHE_GLOBAL; return $blocks; } else if ($op == 'view') { Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.495 diff -u -r1.495 system.module --- modules/system/system.module 22 Jun 2007 08:32:28 -0000 1.495 +++ modules/system/system.module 23 Jun 2007 00:27:47 -0000 @@ -704,6 +704,22 @@ '#description' => t('On high-traffic sites it can become necessary to enforce a minimum cache lifetime. The minimum cache lifetime is the minimum amount of time that will go by before the cache is emptied and recreated. A larger minimum cache lifetime offers better performance, but users will not see new content for a longer period of time.') ); + $form['block_cache'] = array( + '#type' => 'fieldset', + '#title' => t('Block cache'), + // TODO + '#description' => t(''), + ); + + $form['block_cache']['block_cache'] = array( + '#type' => 'radios', + '#title' => t('Block cache'), + '#default_value' => variable_get('block_cache', CACHE_DISABLED), + '#options' => array(CACHE_DISABLED => t('Disabled'), CACHE_NORMAL => t('Enabled (recommended)')), + // TODO + '#description' => t(''), + ); + $form['bandwidth_optimizations'] = array( '#type' => 'fieldset', '#title' => t('Bandwidth optimizations'), Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.122 diff -u -r1.122 system.install --- modules/system/system.install 15 Jun 2007 18:40:14 -0000 1.122 +++ modules/system/system.install 23 Jun 2007 00:34:01 -0000 @@ -3362,6 +3362,28 @@ } /** + * Add cache_block table. + */ +function system_update_6025() { + $ret = array(); + $schema['cache_block'] = array( + 'fields' => array( + 'cid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'data' => array('type' => 'blob', 'not null' => FALSE, 'size' => 'big'), + 'expire' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + 'headers' => array('type' => 'text', 'not null' => FALSE), + 'serialized' => array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0) + ), + 'indexes' => array('expire' => array('expire')), + 'primary key' => array('cid'), + ); + _drupal_initialize_schema('block', $schema); + db_create_table($ret, $schema['cache_block']); + return $ret; +} + +/** * @} End of "defgroup updates-5.x-to-6.x" * The next series of updates should start at 7000. */