? boost-453908.patch
Index: boost.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/boost/boost.admin.inc,v
retrieving revision 1.1.2.1.2.3.2.82
diff -u -p -r1.1.2.1.2.3.2.82 boost.admin.inc
--- boost.admin.inc	7 Oct 2009 19:12:13 -0000	1.1.2.1.2.3.2.82
+++ boost.admin.inc	9 Oct 2009 22:28:14 -0000
@@ -406,6 +406,12 @@ function boost_admin_boost_performance_p
     '#default_value' => BOOST_FLUSH_NODE_TERMS,
     '#description'   => t('Works with view\'s taxonomy/term/% path as well as core.'),
   );
+  $form['advanced']['boost_flush_views'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Clear all cached views pages associated with a node on insert/update/delete'),
+    '#default_value' => BOOST_FLUSH_VIEWS,
+    '#description'   => t(''),
+  );
   $form['advanced']['boost_clear_cache_offline'] = array(
     '#type'          => 'checkbox',
     '#title'         => t('Clear Boosts cache when site goes offline'),
Index: boost.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/boost/boost.install,v
retrieving revision 1.2.2.1.2.3.2.56
diff -u -p -r1.2.2.1.2.3.2.56 boost.install
--- boost.install	8 Oct 2009 19:03:45 -0000	1.2.2.1.2.3.2.56
+++ boost.install	9 Oct 2009 22:28:14 -0000
@@ -444,6 +444,68 @@ function boost_schema() {
       'hash' => array('hash'),
     ),
   );
+  $schema['boost_cache_relationships'] = array(
+    'description' => t('Boost parent child relationships'),
+    'fields' => array(
+      'hash' => array(
+        'description' => 'MD5 hash of below items in the database',
+        'type' => 'varchar',
+        'length' => 32,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'base_dir' => array(
+        'description' => 'Path of the cache root dir relative to Drupal webroot.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'page_callback' => array(
+        'description' => 'The name of the parent function that renders the page.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'page_type' => array(
+        'description' => 'The name of the parent content type.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '0'
+      ),
+      'page_id' => array(
+        'description' => 'The ID of the parent page.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'child_page_callback' => array(
+        'description' => 'The name of the child function that renders the page.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'child_page_type' => array(
+        'description' => 'The name of the child content type.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '0'
+      ),
+      'child_page_id' => array(
+        'description' => 'The ID of the child page.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+    ),
+    'primary key' => array('hash'),
+  );
   return $schema;
 }
 
@@ -928,3 +990,76 @@ function boost_update_6118() {
   db_add_index($ret, 'boost_cache_settings', 'page_type', array('page_type'));
   return $ret;
 }
+
+
+/**
+ * Update 6119 - Create boost_cache_relationships table
+ */
+function boost_update_6119() {
+  $schema['boost_cache_relationships'] = array(
+    'description' => t('Boost parent child relationships'),
+    'fields' => array(
+      'hash' => array(
+        'description' => 'MD5 hash of the 7 these 7 items in the database',
+        'type' => 'varchar',
+        'length' => 32,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'base_dir' => array(
+        'description' => 'Path of the cache root dir relative to Drupal webroot.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'page_callback' => array(
+        'description' => 'The name of the parent function that renders the page.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'page_type' => array(
+        'description' => 'The name of the parent content type.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '0'
+      ),
+      'page_id' => array(
+        'description' => 'The ID of the parent page.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'child_page_callback' => array(
+        'description' => 'The name of the child function that renders the page.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'child_page_type' => array(
+        'description' => 'The name of the child content type.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '0'
+      ),
+      'child_page_id' => array(
+        'description' => 'The ID of the child page.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => ''
+      ),
+    ),
+    'primary key' => array('hash'),
+  );
+
+  $ret = array();
+  db_create_table($ret, 'boost_cache_relationships', $schema['boost_cache_relationships']);
+  return $ret;
+}
Index: boost.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/boost/boost.module,v
retrieving revision 1.3.2.2.2.5.2.173
diff -u -p -r1.3.2.2.2.5.2.173 boost.module
--- boost.module	8 Oct 2009 19:03:45 -0000	1.3.2.2.2.5.2.173
+++ boost.module	9 Oct 2009 22:28:15 -0000
@@ -69,6 +69,7 @@ define('BOOST_DISABLE_CLEAN_URL',    var
 define('BOOST_VERBOSE',              variable_get('boost_verbose', 5));
 define('BOOST_FLUSH_NODE_TERMS',     variable_get('boost_flush_node_terms', TRUE));
 define('BOOST_FLUSH_CCK_REFERENCES', variable_get('boost_flush_cck_references', TRUE));
+define('BOOST_FLUSH_VIEWS',          variable_get('boost_flush_views', FALSE));
 define('BOOST_MAX_TIMESTAMP',        variable_get('boost_max_timestamp', BOOST_TIME));
 
 // Crawler Settings
@@ -111,6 +112,7 @@ define('BOOST_MAX_THREAD_TIME',      max
 //$GLOBALS['_boost_output_buffering'] = '';
 //$GLOBALS['_boost_default_socket_timeout'] = '';
 //$GLOBALS['_boost_router_item'] = '';
+//$GLOBALS['_boost_relationships'] = '';
 
 //////////////////////////////////////////////////////////////////////////////
 // Core API hooks
@@ -133,9 +135,28 @@ function boost_help($path, $arg) {
 }
 
 /**
+ * Implementation of hook_views_pre_render().
+ *
+ * This is called right before the render process. Used to grab the NID's listed
+ * in this view, and set the view node relationship in the database.
+ *
+ * @param &$view
+ *  reference to the view being worked on
+ */
+function boost_views_pre_render(&$view) {
+  if (!is_null($view) && $GLOBALS['_boost_cache_this']) {
+    foreach ($view->result as $item) {
+      $node = node_load($item->nid);
+      $GLOBALS['_boost_relationships'][] = array('child_page_callback' => 'node', 'child_page_type' => $node->type, 'child_page_id' => $item->nid);
+    }
+  }
+}
+
+/**
  * Implementation of hook_init(). Performs page setup tasks if page not cached.
  */
 function boost_init() {
+
   // Disable all caches when nocache is set
   if (isset($_GET['nocache'])) {
     $GLOBALS['conf']['cache'] = CACHE_DISABLED;
@@ -145,7 +166,7 @@ function boost_init() {
 
   global $user, $base_path;
   //set variables
-  $GLOBALS['_boost_router_item'] = _boost_get_menu_router();
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
   $GLOBALS['_boost_path'] = $_REQUEST['q'];
   // Make the proper filename for our query
   $GLOBALS['_boost_query'] = BOOST_CHAR;
@@ -492,6 +513,15 @@ function boost_expire_node($node) {
       }
     }
   }
+
+  if (BOOST_FLUSH_VIEWS) {
+    $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+    $router_item = $GLOBALS['_boost_router_item'];
+    $data = array();
+    $data[] = array('base_dir' => BOOST_FILE_PATH, 'page_callback' => $router_item['page_callback'], 'page_type' => $router_item['page_type'], 'page_id' => $router_item['page_id']);
+    $relationships = boost_cache_get_node_relationships($data);
+    boost_cache_expire_router($relationships);
+  }
 }
 
 /**
@@ -675,7 +705,8 @@ function boost_block($op = 'list', $delt
 }
 
 function boost_block_flush_form() {
-  $router_item = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $router_item = $GLOBALS['_boost_router_item'];
   $form['boost_clear']['page_callback'] = array(
     '#type' => 'hidden',
     '#value' => $router_item['page_callback'],
@@ -708,7 +739,8 @@ function boost_block_db_settings_form() 
   $period[0] = '<' . t('none') . '>';
   $period[-1] = t('default');
   //$info = boost_get_db(boost_file_path($GLOBALS['_boost_path']));
-  $router_item = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $router_item = $GLOBALS['_boost_router_item'];
   $settings = boost_get_settings_db($router_item);
   $default = 0;
   foreach ($settings as $key => $value) {
@@ -817,7 +849,8 @@ function boost_block_db_settings_form_su
  * Sets page specific settings in the boost cache database.
  */
 function boost_block_db_rm_settings_form_submit(&$form_state, $form) {
-  $router_item = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $router_item = $GLOBALS['_boost_router_item'];
   $data = array();
   if (is_int($form['values']['id'])) {
     boost_remove_settings_db($form['values']['id_value']);
@@ -1518,6 +1551,7 @@ function boost_cache_set($path, $data, $
       boost_cache_write(str_replace(BOOST_FILE_PATH, BOOST_GZIP_FILE_PATH, $filename) . BOOST_GZIP_EXTENSION, gzencode($data, 9));
     }
     boost_db_prep($filename, $extension, BOOST_TIME + $expire);
+    boost_cache_set_node_relationships($GLOBALS['_boost_relationships']);
     return TRUE;
   }
   else {
@@ -1526,6 +1560,85 @@ function boost_cache_set($path, $data, $
 }
 
 /**
+ * Creates a parent child relationship for pages like views.
+ *
+ * @param $relationships
+ *   Array of $router_item array "objects"
+ *    Required
+ *     ['child_page_callback']
+ *     ['child_page_type']
+ *     ['child_page_id']
+ *    Optional
+ *     ['base_dir']
+ *     ['page_callback']
+ *     ['page_type']
+ *     ['page_id']
+ *
+ * If Optional is not set it will use values in $GLOBALS['_boost_router_item']
+ */
+function boost_cache_set_node_relationships($relationships) {
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $router_item = $GLOBALS['_boost_router_item'];
+  if (!is_array($relationships)) {
+    return FALSE;
+  }
+  foreach ($relationships as $data) {
+    // If one of the required items is not set, skip this entry
+    if (!isset($data['child_page_callback']) || !isset($data['child_page_type']) || !isset($data['child_page_id'])) {
+      continue;
+     }
+    // Set the optional parameters
+    $data['base_dir'] = isset($data['base_dir']) ? $data['base_dir'] : BOOST_FILE_PATH;
+    $data['page_callback'] = isset($data['page_callback']) ? $data['page_callback'] : $router_item['page_callback'];
+    $data['page_type'] = isset($data['page_type']) ? $data['page_type'] : $router_item['page_type'];
+    $data['page_id'] = isset($data['page_id']) ? $data['page_id'] : $router_item['page_id'];
+
+    // Create the primary key
+    $hash = md5($data['base_dir'] . $data['page_callback'] . $data['page_type'] . $data['page_id'] . $data['child_page_callback'] . $data['child_page_type'] . $data['child_page_id']);
+
+    // Insert data into database
+    db_query("UPDATE {boost_cache_relationships} SET base_dir = '%s', page_callback = '%s', page_type = '%s', page_id = '%s', child_page_callback = '%s', child_page_type = '%s', child_page_id = '%s' WHERE hash = '%s'", $data['base_dir'], $data['page_callback'], $data['page_type'], $data['page_id'], $data['child_page_callback'], $data['child_page_type'], $data['child_page_id'], $hash);
+    if (!db_affected_rows()) {
+      @db_query("INSERT INTO {boost_cache_relationships} (hash, base_dir, page_callback, page_type, page_id, child_page_callback, child_page_type, child_page_id) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", $hash, $data['base_dir'], $data['page_callback'], $data['page_type'], $data['page_id'], $data['child_page_callback'], $data['child_page_type'], $data['child_page_id']);
+    }
+  }
+  unset($GLOBALS['_boost_relationships']);
+  return TRUE;
+}
+
+/**
+ * Creates a parent child relationship for pages like views.
+ *
+ * @param $relationships
+ *   Array of $router_item array "objects"
+ *    Required
+ *     ['page_callback']
+ *     ['page_type']
+ *     ['page_id']
+ *    Optional
+ *     ['base_dir']
+ */
+function boost_cache_get_node_relationships($relationships) {
+  if (!is_array($relationships)) {
+    return FALSE;
+  }
+  $results = array();
+  foreach ($relationships as $data) {
+    // If one of the required items is not set, skip this entry
+    if (!isset($data['page_callback']) || !isset($data['page_type']) || !isset($data['page_id'])) {
+      continue;
+     }
+    $data['base_dir'] = isset($data['base_dir']) ? $data['base_dir'] : BOOST_FILE_PATH;
+    $result = db_query("SELECT page_callback, page_type, page_id FROM {boost_cache_relationships} WHERE child_page_id = '%s' AND child_page_type = '%s' AND child_page_callback = '%s' AND base_dir = '%s'", $data['page_id'], $data['page_type'], $data['page_callback'], $data['base_dir']);
+    while ($info = db_fetch_array($result)) {
+      $hash = $info['page_callback'] . '-' .  $info['page_type'] . '-' . $info['page_id'];
+      $results[$hash] = $info;
+    }
+  }
+  return $results;
+}
+
+/**
  * Figure out what is going in the database & put it in
  *
  * @param $filename
@@ -1536,7 +1649,8 @@ function boost_cache_set($path, $data, $
  *  Cache expiration time in seconds (UNIX time).
  */
 function boost_db_prep($filename, $extension, $expire) {
-  $router_item = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $router_item = $GLOBALS['_boost_router_item'];
   $timer = timer_read('page');
   $timer_average = $timer;
   $lifetime = -1;
@@ -1667,7 +1781,8 @@ function boost_remove_settings_db($csid)
  *   At what level does this effect cache expiration
  */
 function boost_set_db_page_settings($lifetime, $push, $scope) {
-  $router_item = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $GLOBALS['_boost_router_item'] = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router();
+  $router_item = $GLOBALS['_boost_router_item'];
   $filename = boost_file_path($GLOBALS['_boost_path']);
   $info = boost_get_db($filename);
   if (!$info) {
