From 82cadd0f429d8a5bf0704d9d1945a8b9e653500f Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 10 Nov 2009 17:47:43 +0000
Subject: [PATCH 01/31] Initial commit of branch

---
 expire.info   |    6 +
 expire.module |  386 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 392 insertions(+), 0 deletions(-)
 create mode 100644 expire.info
 create mode 100644 expire.module

diff --git a/expire.info b/expire.info
new file mode 100644
index 0000000..5da4c5c
--- /dev/null
+++ b/expire.info
@@ -0,0 +1,6 @@
+; $Id$
+name = Cache Expiration
+description = Logic for expiring related caches
+recommends[] = nodereferrer
+package = Caching
+core = 6.x
diff --git a/expire.module b/expire.module
new file mode 100644
index 0000000..0074785
--- /dev/null
+++ b/expire.module
@@ -0,0 +1,386 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provides logic for page cache expiration
+ */
+
+define('EXPIRE_FLUSH_NODE_TERMS', TRUE);
+define('EXPIRE_FLUSH_MENU_ITEMS', 1);
+define('EXPIRE_FLUSH_CCK_REFERENCES', TRUE);
+
+
+/**
+ * Implementation of hook_comment(). Acts on comment modification.
+ */
+function expire_comment($comment, $op) {
+
+  switch ($op) {
+    case 'insert':
+    case 'update':
+      // Expire the relevant node page from the static page cache to prevent serving stale content:
+      if (!empty($comment['nid'])) {
+        $node = node_load($comment['nid']);
+        $node->nid = $comment['nid'];
+        expire_node($node);
+      }
+      break;
+    case 'publish':
+    case 'unpublish':
+    case 'delete':
+      if (!empty($comment->nid)) {
+        $node = node_load($comment->nid);
+        $node->nid = $comment->nid;
+        expire_node($node);
+      }
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_nodeapi(). Acts on nodes defined by other modules.
+ */
+function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
+
+  switch ($op) {
+    case 'insert':
+      expire_node($node);
+      break;
+    case 'update':
+      expire_node($node);
+      break;
+    case 'delete':
+      expire_node($node);
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_votingapi_insert().
+ *
+ * @param $votes
+ *  array of votes
+ */
+function expire_votingapi_insert($votes) {
+  if (!BOOST_ENABLED) return;
+
+  foreach ($votes as $vote) {
+    $node = node_load($vote['content_id']);
+    $node->nid = $vote['content_id'];
+    expire_node($node);
+  }
+}
+
+/**
+ * Implementation of hook_votingapi_delete().
+ *
+ * @param $votes
+ *  array of votes
+ */
+function expire_votingapi_delete($votes) {
+  if (!BOOST_ENABLED) return;
+
+  foreach ($votes as $vote) {
+    $node = node_load($vote['content_id']);
+    $node->nid = $vote['content_id'];
+    boost_expire_node($node);
+  }
+}
+
+/**
+ * Implementation of hook_user(). Acts on user account actions.
+ */
+function expire_user($op, &$edit, &$account, $category = NULL) {
+
+  global $user;
+  switch ($op) {
+    case 'delete':
+      // Expire the relevant user page from the static page cache to prevent serving stale content:
+      if (!empty($account->uid)) {
+        $paths[] = 'user/' . $account->uid;
+        $flushed = expire_cache_derivative($paths, TRUE, TRUE);
+        watchdog('boost', 'expire_user() <br />User !uid was deleted resulting in !flushed pages being expired from the cache',  array('!uid' => $account->uid, '!flushed' => $flushed));
+      }
+      break;
+  }
+}
+
+/**
+ * Expires a node from the cache; including related pages.
+ *
+ * Expires front page if promoted, taxonomy terms,
+ *
+ * @param $node
+ *  node object
+ * @param $nid
+ *  node id
+ */
+function expire_node($node) {
+  $data = array();
+  $paths = array();
+
+  // Check node object
+  if (empty($node->nid)) {
+    return FALSE;
+  }
+
+  // Expire this node
+  $paths['node'] = 'node/' . $node->nid;
+
+  // If promoted to front page, expire front page
+  if ($node->promote == 1) {
+    $paths['front'] = '<front>';
+  }
+
+  // Get taxonomy terms and flush
+  if (module_exists('taxonomy') && EXPIRE_FLUSH_NODE_TERMS) {
+    $tids = boost_taxonomy_node_get_tids($node->nid);
+    $filenames = array();
+    foreach ($tids as $tid) {
+      if (is_int($tid)) {
+        $paths['term' . $tid] = 'taxonomy/term/' . $tid;
+      }
+    }
+  }
+
+  // Get menu and flush related items in the menu.
+  if (EXPIRE_FLUSH_MENU_ITEMS !=0) {
+    if (!isset($node->menu['menu_name'])) {
+      menu_nodeapi($node, 'prepare');
+    }
+    $menu = menu_tree_all_data($node->menu['menu_name']);
+    if (EXPIRE_FLUSH_MENU_ITEMS == 1) {
+      $links = expire_get_menu_structure($menu, FALSE, 'node/' . $node->nid);
+    }
+    elseif (EXPIRE_FLUSH_MENU_ITEMS == 2) {
+      $links = expire_get_menu_structure($menu);
+    }
+    $paths = array_merge($links, $paths);
+  }
+
+  // Get CCK References and flush.
+  if (EXPIRE_FLUSH_CCK_REFERENCES && module_exists('nodereference')) {
+    $nids = array();
+    $type = content_types($node->type);
+    if ($type) {
+      foreach ($type['fields'] as $field) {
+        // Add referenced nodes to nids. This will clean up nodereferrer fields
+        // when the referencing node is updated.
+        if ($field['type'] == 'nodereference') {
+          $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
+          foreach ($node_field as $delta => $item) {
+            $nids[$item['nid']] = $item['nid'];
+          }
+        }
+      }
+      foreach ($nids as $nid) {
+        if (is_int($nid)) {
+          $paths['reference' . $nid] = 'node/' . $nid;
+        }
+      }
+    }
+
+    // Get CCK references pointing to this node and flush.
+    if (module_exists('nodereferrer')) {
+      $nids = nodereferrer_referrers($node->nid);
+      foreach ($nids as $nid) {
+        if (is_int($nid['nid'])) {
+          $paths['referrer' . $nid['nid']] = 'node/' . $nid['nid'];
+        }
+      }
+    }
+  }
+
+  // Flush array of paths
+  if (!empty($paths)) {
+    $flushed = expire_cache_derivative($paths, TRUE);
+    watchdog('expire', 'expire_node() <br />Node !nid was flushed resulting in !flushed pages being expired from the cache',  array('!nid' => $node->nid, '!flushed' => $flushed));
+  }
+}
+
+/**
+ * Finds parent, siblings and children of the menu item. UGLY CODE...
+ *
+ * @param array $menu
+ *  Output from menu_tree_all_data()
+ * @param bool $found
+ *  Signal for when the needle was found in the menu array.
+ *  Set TRUE to get entire menu
+ * @param string $needle
+ *  Name of menu link. Example 'node/21'
+ * @param bool $first
+ *  Keep track of the first call; this is a recursive function.
+ * @param bool &$found_global
+ *  Used to signal the parent item was found in one of it's children
+ * @param bool &$menu_out
+ *  Output array of parent, siblings and children menu links
+ *
+ * TODO: Use page_callback and page_arguments instead of link_path.
+ *  Can use boost_cache_expire_router() then.
+ */
+function expire_get_menu_structure($menu, $found = TRUE, $needle = '', $first = TRUE, &$found_global = FALSE, &$menu_out = array()) {
+  $found_global = FALSE;
+  // Get Siblings
+  foreach ($menu as $item) {
+    if ($item['link']['hidden'] == 0 && $item['link']['page_callback'] != '' && ($item['link']['link_path'] == $needle || $found)) {
+      $menu_out[] = $item['link']['link_path'];
+      $found = TRUE;
+    }
+  }
+  // Get Children
+  foreach ($menu as $item) {
+    if ($item['link']['hidden'] != 0) {
+      continue;
+    }
+    if ($item['link']['page_callback'] != '' && ($item['link']['link_path'] == $needle || $found)) {
+      $menu_out[] = $item['link']['link_path'];
+      $found = TRUE;
+    }
+    // Get Grandkids
+    if (!empty($item['below'])) {
+      $sub_menu = array();
+      foreach ($item['below'] as $below) {
+        if ($below['link']['hidden'] == 0) {
+          $sub_menu[] = $below;
+        }
+      }
+      expire_get_menu_structure($sub_menu, $needle, $found, FALSE, $found_global, $menu_out);
+      $structure[$item['link']['link_path']][] = $sub;
+      if ($item['link']['page_callback'] != '' && $found_global) {
+        // Get Parent of kid
+        $menu_out[] = $item['link']['link_path'];
+      }
+    }
+    else {
+      $structure[$item['link']['link_path']] = '';
+    }
+  }
+
+  // Clean up
+  if (is_array($structure)) {
+    $structure = array_unique($structure);
+  }
+  $found_global = $found;
+  if ($first) {
+    $menu_out = array_unique($menu_out);
+    sort($menu_out);
+    return $menu_out;
+  }
+  else {
+    return $structure;
+  }
+}
+
+/**
+ * Return taxonomy terms given a nid.
+ *
+ * Needed because of a weird bug with CCK & node_load()
+ *  http://drupal.org/node/545922
+ */
+function expire_taxonomy_node_get_tids($nid) {
+  $vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $nid));
+  $result = db_query(db_rewrite_sql('SELECT t.tid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $vid);
+  $tids = array();
+  while ($term = db_result($result)) {
+    $tids[] = $term;
+  }
+  return $tids;
+}
+
+/**
+ * Finds all possible paths/redirects/aliases given the root path.
+ *
+ * @param $paths
+ *   Array of current URLs
+ * @param $both
+ *   Expire database & file
+ * @param $force_flush
+ *   Override the settings and kill the file
+ */
+function expire_cache_derivative($paths, $both = FALSE, $force_flush = FALSE) {
+  global $base_path;
+  $expire = array();
+
+  if (empty($paths)) {
+    return FALSE;
+  }
+  foreach ($paths as $path) {
+    // Given path
+    $expire[] = $path;
+
+    // Special front page feed handling
+    if ($path == '' || $path == '<front>') {
+      $expire[] = 'rss.xml';
+    }
+
+    // Path alias
+    $path_alias = url($path, array('absolute' => FALSE));
+    if ($base_path != '/') {
+      $path_alias = implode('/', array_diff_assoc(array_filter(explode('/', $path_alias)), array_filter(explode('/', $base_path))));
+    }
+    $expire[] = $path_alias;
+
+    // Path redirects
+    if (module_exists('path_redirect')) {
+      $path_redirects = expire_path_redirect_load(array('redirect' => $path));
+      if (isset($path_redirects)) {
+        foreach ($path_redirects as $path_redirect) {
+          $expire[] = $path_redirect['path'];
+        }
+      }
+    }
+  }
+
+  // Expire cached files
+  $counter = 0;
+  if (empty($expire)) {
+    return FALSE;
+  }
+  $expire = array_unique($expire);
+  // Add on the url to these paths
+  $urls = array();
+  global $base_url;
+  foreach ($expire as $path) {
+    $urls[] = $base_url . '/' . $path;
+  }
+  watchdog('expire','<pre><tt>' .  print_r($urls, TRUE) . '</tt></pre>');
+  // hook_expire_cache
+  foreach (module_implements('expire_cache') as $module) {
+    module_invoke($module, 'expire_cache', $urls);
+  }
+  return count($urls);
+}
+
+/**
+ * Retrieve a specific URL redirect from the database.
+ * http://drupal.org/node/451790
+ *
+ * @param $where
+ *   Array containing 'redirect' => $path
+ */
+function expire_path_redirect_load($where = array(), $args = array(), $sort = array()) {
+  $redirects = array();
+  if (is_numeric($where)) {
+    $where = array('rid' => $where);
+  }
+
+  foreach ($where as $key => $value) {
+    if (is_string($key)) {
+      $args[] = $value;
+      $where[$key] = $key .' = '. (is_numeric($value) ? '%d' : "'%s'");
+    }
+  }
+
+  if ($where && $args) {
+    $sql = "SELECT * FROM {path_redirect} WHERE ". implode(' AND ', $where);
+    if ($sort) {
+      $sql .= ' ORDER BY '. implode(' ,', $sort);
+    }
+    $result = db_query($sql, $args);
+    while ($redirect = db_fetch_array($result)) {
+      $redirects[] = $redirect;
+    }
+    return $redirects;
+  }
+}
-- 
1.7.5.4


From 0f54f344fe0fbf8287e75f01a4e320edd076761a Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 10 Nov 2009 17:55:37 +0000
Subject: [PATCH 02/31] updated

---
 expire.module |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/expire.module b/expire.module
index 0074785..9d9654f 100644
--- a/expire.module
+++ b/expire.module
@@ -63,8 +63,6 @@ function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  *  array of votes
  */
 function expire_votingapi_insert($votes) {
-  if (!BOOST_ENABLED) return;
-
   foreach ($votes as $vote) {
     $node = node_load($vote['content_id']);
     $node->nid = $vote['content_id'];
@@ -79,12 +77,10 @@ function expire_votingapi_insert($votes) {
  *  array of votes
  */
 function expire_votingapi_delete($votes) {
-  if (!BOOST_ENABLED) return;
-
   foreach ($votes as $vote) {
     $node = node_load($vote['content_id']);
     $node->nid = $vote['content_id'];
-    boost_expire_node($node);
+    expire_node($node);
   }
 }
 
@@ -100,7 +96,7 @@ function expire_user($op, &$edit, &$account, $category = NULL) {
       if (!empty($account->uid)) {
         $paths[] = 'user/' . $account->uid;
         $flushed = expire_cache_derivative($paths, TRUE, TRUE);
-        watchdog('boost', 'expire_user() <br />User !uid was deleted resulting in !flushed pages being expired from the cache',  array('!uid' => $account->uid, '!flushed' => $flushed));
+        watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array('!uid' => $account->uid, '!flushed' => $flushed));
       }
       break;
   }
@@ -135,7 +131,7 @@ function expire_node($node) {
 
   // Get taxonomy terms and flush
   if (module_exists('taxonomy') && EXPIRE_FLUSH_NODE_TERMS) {
-    $tids = boost_taxonomy_node_get_tids($node->nid);
+    $tids = expire_taxonomy_node_get_tids($node->nid);
     $filenames = array();
     foreach ($tids as $tid) {
       if (is_int($tid)) {
-- 
1.7.5.4


From 6b6bd3a9a0ab86b44bc1447a6e9b06b53dcf59ba Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Wed, 26 May 2010 07:28:18 +0000
Subject: [PATCH 03/31] #809340: Update what in expire to the latest equivlent
 functions from boost.

---
 expire.info   |    4 +-
 expire.module |  177 +++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 143 insertions(+), 38 deletions(-)

diff --git a/expire.info b/expire.info
index 5da4c5c..68d9e26 100644
--- a/expire.info
+++ b/expire.info
@@ -1,6 +1,6 @@
 ; $Id$
 name = Cache Expiration
-description = Logic for expiring related caches
+description = Logic for expiring page caches
 recommends[] = nodereferrer
-package = Caching
+package = Performance and scalability
 core = 6.x
diff --git a/expire.module b/expire.module
index 9d9654f..31a5eab 100644
--- a/expire.module
+++ b/expire.module
@@ -6,16 +6,16 @@
  * Provides logic for page cache expiration
  */
 
+// Defaults used if variable_get is not set.
 define('EXPIRE_FLUSH_NODE_TERMS', TRUE);
 define('EXPIRE_FLUSH_MENU_ITEMS', 1);
 define('EXPIRE_FLUSH_CCK_REFERENCES', TRUE);
-
+define('EXPIRE_FLUSH_FRONT', TRUE);
 
 /**
  * Implementation of hook_comment(). Acts on comment modification.
  */
 function expire_comment($comment, $op) {
-
   switch ($op) {
     case 'insert':
     case 'update':
@@ -42,7 +42,6 @@ function expire_comment($comment, $op) {
  * Implementation of hook_nodeapi(). Acts on nodes defined by other modules.
  */
 function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
-
   switch ($op) {
     case 'insert':
       expire_node($node);
@@ -88,14 +87,12 @@ function expire_votingapi_delete($votes) {
  * Implementation of hook_user(). Acts on user account actions.
  */
 function expire_user($op, &$edit, &$account, $category = NULL) {
-
-  global $user;
   switch ($op) {
     case 'delete':
       // Expire the relevant user page from the static page cache to prevent serving stale content:
       if (!empty($account->uid)) {
         $paths[] = 'user/' . $account->uid;
-        $flushed = expire_cache_derivative($paths, TRUE, TRUE);
+        $flushed = expire_cache_derivative($account, $paths, TRUE, TRUE);
         watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array('!uid' => $account->uid, '!flushed' => $flushed));
       }
       break;
@@ -109,11 +106,8 @@ function expire_user($op, &$edit, &$account, $category = NULL) {
  *
  * @param $node
  *  node object
- * @param $nid
- *  node id
  */
 function expire_node($node) {
-  $data = array();
   $paths = array();
 
   // Check node object
@@ -125,13 +119,24 @@ function expire_node($node) {
   $paths['node'] = 'node/' . $node->nid;
 
   // If promoted to front page, expire front page
-  if ($node->promote == 1) {
+  if (variable_get('expire_flush_front', EXPIRE_FLUSH_FRONT) && $node->promote == 1) {
     $paths['front'] = '<front>';
   }
 
   // Get taxonomy terms and flush
-  if (module_exists('taxonomy') && EXPIRE_FLUSH_NODE_TERMS) {
+  if (module_exists('taxonomy') && variable_get('expire_flush_node_terms', EXPIRE_FLUSH_NODE_TERMS)) {
+    // Get old terms from DB
     $tids = expire_taxonomy_node_get_tids($node->nid);
+    // Get new terms from node object
+    if (!empty($node->taxonomy)) {
+      foreach ($node->taxonomy as $vocab) {
+        if (is_array($vocab)) {
+          foreach ($vocab as $term) {
+            $tids[$term] = $term;
+          }
+        }
+      }
+    }
     $filenames = array();
     foreach ($tids as $tid) {
       if (is_int($tid)) {
@@ -141,22 +146,26 @@ function expire_node($node) {
   }
 
   // Get menu and flush related items in the menu.
-  if (EXPIRE_FLUSH_MENU_ITEMS !=0) {
+  if (variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS) !=0) {
     if (!isset($node->menu['menu_name'])) {
       menu_nodeapi($node, 'prepare');
     }
     $menu = menu_tree_all_data($node->menu['menu_name']);
-    if (EXPIRE_FLUSH_MENU_ITEMS == 1) {
-      $links = expire_get_menu_structure($menu, FALSE, 'node/' . $node->nid);
+    $tempa = NULL;
+    $tempb = NULL;
+    if (variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS) == 1) {
+      $links = expire_get_menu_structure($menu, FALSE, 'node/' . $node->nid, NULL, $tempa, $tempb);
     }
-    elseif (EXPIRE_FLUSH_MENU_ITEMS == 2) {
-      $links = expire_get_menu_structure($menu);
+    elseif (variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS) == 2) {
+      $links = expire_get_menu_structure($menu, NULL, NULL, NULL, $tempa, $tempb);
     }
+    unset($tempa);
+    unset($tempb);
     $paths = array_merge($links, $paths);
   }
 
   // Get CCK References and flush.
-  if (EXPIRE_FLUSH_CCK_REFERENCES && module_exists('nodereference')) {
+  if (variable_get('expire_flush_cck_references', EXPIRE_FLUSH_CCK_REFERENCES) && module_exists('nodereference')) {
     $nids = array();
     $type = content_types($node->type);
     if ($type) {
@@ -166,15 +175,12 @@ function expire_node($node) {
         if ($field['type'] == 'nodereference') {
           $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
           foreach ($node_field as $delta => $item) {
-            $nids[$item['nid']] = $item['nid'];
+            if (is_int($item['nid'])) {
+              $paths['reference' . $nid] = 'node/' . $item['nid'];
+            }
           }
         }
       }
-      foreach ($nids as $nid) {
-        if (is_int($nid)) {
-          $paths['reference' . $nid] = 'node/' . $nid;
-        }
-      }
     }
 
     // Get CCK references pointing to this node and flush.
@@ -190,7 +196,7 @@ function expire_node($node) {
 
   // Flush array of paths
   if (!empty($paths)) {
-    $flushed = expire_cache_derivative($paths, TRUE);
+    $flushed = expire_cache_derivative($node, $paths, TRUE);
     watchdog('expire', 'expire_node() <br />Node !nid was flushed resulting in !flushed pages being expired from the cache',  array('!nid' => $node->nid, '!flushed' => $flushed));
   }
 }
@@ -211,12 +217,15 @@ function expire_node($node) {
  *  Used to signal the parent item was found in one of it's children
  * @param bool &$menu_out
  *  Output array of parent, siblings and children menu links
- *
- * TODO: Use page_callback and page_arguments instead of link_path.
- *  Can use boost_cache_expire_router() then.
  */
-function expire_get_menu_structure($menu, $found = TRUE, $needle = '', $first = TRUE, &$found_global = FALSE, &$menu_out = array()) {
+function expire_get_menu_structure($menu, $found, $needle, $first, &$found_global, &$menu_out) {
+  // Set Defaults
+  $found = !is_null($found) ? $found : TRUE;
+  $needle = !is_null($needle) ? $needle : '';
+  $first = !is_null($first) ? $first : TRUE;
   $found_global = FALSE;
+  $menu_out = !is_null($menu_out) ? $menu_out : array();
+
   // Get Siblings
   foreach ($menu as $item) {
     if ($item['link']['hidden'] == 0 && $item['link']['page_callback'] != '' && ($item['link']['link_path'] == $needle || $found)) {
@@ -254,14 +263,19 @@ function expire_get_menu_structure($menu, $found = TRUE, $needle = '', $first =
   }
 
   // Clean up
-  if (is_array($structure)) {
+  if (isset($structure) && is_array($structure)) {
     $structure = array_unique($structure);
   }
   $found_global = $found;
   if ($first) {
-    $menu_out = array_unique($menu_out);
-    sort($menu_out);
-    return $menu_out;
+    if (isset($menu_out) && is_array($menu_out)) {
+      $menu_out = array_unique($menu_out);
+      sort($menu_out);
+      return $menu_out;
+    }
+    else {
+      return array();
+    }
   }
   else {
     return $structure;
@@ -294,7 +308,7 @@ function expire_taxonomy_node_get_tids($nid) {
  * @param $force_flush
  *   Override the settings and kill the file
  */
-function expire_cache_derivative($paths, $both = FALSE, $force_flush = FALSE) {
+function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = FALSE) {
   global $base_path;
   $expire = array();
 
@@ -337,10 +351,14 @@ function expire_cache_derivative($paths, $both = FALSE, $force_flush = FALSE) {
   // Add on the url to these paths
   $urls = array();
   global $base_url;
-  foreach ($expire as $path) {
-    $urls[] = $base_url . '/' . $path;
+  foreach (expire_get_base_urls($node) as $domain_id) {
+    foreach ($domain_id as $base) {
+      foreach ($expire as $path) {
+        $urls[] = $base . $path;
+      }
+    }
   }
-  watchdog('expire','<pre><tt>' .  print_r($urls, TRUE) . '</tt></pre>');
+  watchdog('expire', 'input: !paths <br /> output: !urls', array('!paths' => expire_print_r($paths), '!urls' => expire_print_r($urls)));
   // hook_expire_cache
   foreach (module_implements('expire_cache') as $module) {
     module_invoke($module, 'expire_cache', $urls);
@@ -380,3 +398,90 @@ function expire_path_redirect_load($where = array(), $args = array(), $sort = ar
     return $redirects;
   }
 }
+
+/**
+ * Simple print_r to html function
+ *
+ * @param $data
+ *
+ * @return string
+ *   print_r contents in nicely formatted html
+ */
+function expire_print_r($data) {
+  return str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(htmlentities(print_r($data, TRUE))));
+}
+
+/**
+ * Get all base url's where this node can appear. Domain access support.
+ *
+ * @param $node
+ *   node object
+ * @return array
+ *   array(0 => array($base_url . '/'))
+ */
+function expire_get_base_urls(&$node) {
+  global $base_url, $base_path;
+
+  // Get list of URL's if using domain access
+  $base_urls = array();
+  $domains = array();
+  if (module_exists('domain') && isset($node->domains)) {
+    // Get domains from node/user object
+    foreach ($node->domains as $key => $domain_id) {
+      if ($key != $domain_id) {
+        continue;
+      }
+      $domains[$domain_id] = $domain_id;
+    }
+    // Get domains from database
+    foreach (expire_get_domains($node) as $domain_id) {
+      $domains[$domain_id] = $domain_id;
+    }
+    // Get aliases and set base url
+    foreach ($domains as $domain_id) {
+      $domain = domain_lookup($domain_id);
+      if ($domain['valid'] == 1) {
+        if (isset($domain['path'])) {
+          $base_urls[$domain_id][] = $domain['path'];
+        }
+        foreach ($domain['aliases'] as $alias) {
+          if ($alias['redirect'] != 1) {
+            $temp_domain = array('scheme' => $domain['scheme'], 'subdomain' => $alias['pattern']);
+            $base_urls[$domain_id][] = domain_get_path($temp_domain);
+          }
+        }
+      }
+    }
+  }
+  else {
+    $base_urls[0][] = $base_url . '/';
+  }
+  return $base_urls;
+}
+
+/**
+ * Get domains the node is currently published to
+ *
+ * @param $node
+ *   node object
+ * @return array
+ *   array('$gid' => $gid)
+ */
+function expire_get_domains(&$node) {
+  $domains = array();
+  if ($node->nid) {
+    $result = db_query("SELECT gid FROM {domain_access} WHERE nid = %d", $node->nid);
+    while ($row = db_fetch_array($result)) {
+      $gid = $row['gid'];
+      $domains[$gid] = $gid;
+    }
+  }
+  elseif ($node->mail && $node->name) {
+    $result = db_query("SELECT domain_id FROM {domain_editor} WHERE uid = %d", $node->uid);
+    while ($row = db_fetch_array($result)) {
+      $gid = $row['domain_id'];
+      $domains[$gid] = $gid;
+    }
+  }
+  return $domains;
+}
-- 
1.7.5.4


From 3e56351c0dcece0548196872a990b399ec2b05fd Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Wed, 26 May 2010 18:38:14 +0000
Subject: [PATCH 04/31] Cleaner watchdog code; output what modules are using
 the hook; Make  inclusion optional.

---
 expire.module |   34 +++++++++++++++++++++++++---------
 1 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/expire.module b/expire.module
index 31a5eab..b6f239f 100644
--- a/expire.module
+++ b/expire.module
@@ -11,6 +11,7 @@ define('EXPIRE_FLUSH_NODE_TERMS', TRUE);
 define('EXPIRE_FLUSH_MENU_ITEMS', 1);
 define('EXPIRE_FLUSH_CCK_REFERENCES', TRUE);
 define('EXPIRE_FLUSH_FRONT', TRUE);
+define('EXPIRE_INCLUDE_BASE_URL', TRUE);
 
 /**
  * Implementation of hook_comment(). Acts on comment modification.
@@ -93,7 +94,10 @@ function expire_user($op, &$edit, &$account, $category = NULL) {
       if (!empty($account->uid)) {
         $paths[] = 'user/' . $account->uid;
         $flushed = expire_cache_derivative($account, $paths, TRUE, TRUE);
-        watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array('!uid' => $account->uid, '!flushed' => $flushed));
+        watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
+          '!uid' => $account->uid,
+          '!flushed' => $flushed,
+        ));
       }
       break;
   }
@@ -197,7 +201,10 @@ function expire_node($node) {
   // Flush array of paths
   if (!empty($paths)) {
     $flushed = expire_cache_derivative($node, $paths, TRUE);
-    watchdog('expire', 'expire_node() <br />Node !nid was flushed resulting in !flushed pages being expired from the cache',  array('!nid' => $node->nid, '!flushed' => $flushed));
+    watchdog('expire', 'Node !nid was flushed resulting in !flushed pages being expired from the cache',  array(
+      '!nid' => $node->nid,
+      '!flushed' => $flushed,
+    ));
   }
 }
 
@@ -343,7 +350,6 @@ function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = F
   }
 
   // Expire cached files
-  $counter = 0;
   if (empty($expire)) {
     return FALSE;
   }
@@ -351,18 +357,28 @@ function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = F
   // Add on the url to these paths
   $urls = array();
   global $base_url;
-  foreach (expire_get_base_urls($node) as $domain_id) {
-    foreach ($domain_id as $base) {
-      foreach ($expire as $path) {
-        $urls[] = $base . $path;
+  if (variable_get('expire_include_base_url', EXPIRE_INCLUDE_BASE_URL)) {
+    foreach (expire_get_base_urls($node) as $domain_id) {
+      foreach ($domain_id as $base) {
+        foreach ($expire as $path) {
+          $urls[] = $base . $path;
+        }
       }
     }
   }
-  watchdog('expire', 'input: !paths <br /> output: !urls', array('!paths' => expire_print_r($paths), '!urls' => expire_print_r($urls)));
+  else {
+    $urls = $expire;
+  }
   // hook_expire_cache
-  foreach (module_implements('expire_cache') as $module) {
+  $modules = module_implements('expire_cache');
+  foreach ($modules as $module) {
     module_invoke($module, 'expire_cache', $urls);
   }
+  watchdog('expire', 'Input: !paths <br /> Output: !urls <br /> Modules Using hook_expire_cache(): !modules', array(
+    '!paths' => expire_print_r($paths),
+    '!urls' => expire_print_r($urls),
+    '!modules' => expire_print_r($modules),
+  ));
   return count($urls);
 }
 
-- 
1.7.5.4


From f6babf406b6b1eb0ee89f0e3227b6fc94567617f Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 20 Jul 2010 09:35:48 +0000
Subject: [PATCH 05/31] #829010 by carlos8f: fix double paths in cache
 clearing logic.

---
 expire.module |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/expire.module b/expire.module
index b6f239f..63ff2b6 100644
--- a/expire.module
+++ b/expire.module
@@ -333,10 +333,8 @@ function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = F
 
     // Path alias
     $path_alias = url($path, array('absolute' => FALSE));
-    if ($base_path != '/') {
-      $path_alias = implode('/', array_diff_assoc(array_filter(explode('/', $path_alias)), array_filter(explode('/', $base_path))));
-    }
-    $expire[] = $path_alias;
+    // Remove the base path
+    $expire[] = substr($path_alias, strlen($base_path));
 
     // Path redirects
     if (module_exists('path_redirect')) {
-- 
1.7.5.4


From 64d7b59ce7204e1ab2b594252346cc20f77b1e4a Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 20 Jul 2010 09:38:56 +0000
Subject: [PATCH 06/31] #790480 by AlexisWilke: fix for inconsistant array vs
 object in core.

---
 expire.module |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/expire.module b/expire.module
index 63ff2b6..e1c56d4 100644
--- a/expire.module
+++ b/expire.module
@@ -17,16 +17,15 @@ define('EXPIRE_INCLUDE_BASE_URL', TRUE);
  * Implementation of hook_comment(). Acts on comment modification.
  */
 function expire_comment($comment, $op) {
+  // Convert array to object
+  if (is_array($comment)) {
+    $comment = (object)$comment;
+  }
+
+  // Expire the relevant node page from the static page cache to prevent serving stale content:
   switch ($op) {
     case 'insert':
     case 'update':
-      // Expire the relevant node page from the static page cache to prevent serving stale content:
-      if (!empty($comment['nid'])) {
-        $node = node_load($comment['nid']);
-        $node->nid = $comment['nid'];
-        expire_node($node);
-      }
-      break;
     case 'publish':
     case 'unpublish':
     case 'delete':
-- 
1.7.5.4


From 22ec44c9810a8cd0dbb6191cff87403a05678584 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Wed, 11 Aug 2010 19:19:07 +0000
Subject: [PATCH 07/31] #879942 by jmkoenraadt: make sure aliases is an array.

---
 expire.module |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/expire.module b/expire.module
index e1c56d4..b34c61b 100644
--- a/expire.module
+++ b/expire.module
@@ -457,10 +457,12 @@ function expire_get_base_urls(&$node) {
         if (isset($domain['path'])) {
           $base_urls[$domain_id][] = $domain['path'];
         }
-        foreach ($domain['aliases'] as $alias) {
-          if ($alias['redirect'] != 1) {
-            $temp_domain = array('scheme' => $domain['scheme'], 'subdomain' => $alias['pattern']);
-            $base_urls[$domain_id][] = domain_get_path($temp_domain);
+        if (is_array($domain['aliases'])) {
+          foreach ($domain['aliases'] as $alias) {
+            if ($alias['redirect'] != 1) {
+              $temp_domain = array('scheme' => $domain['scheme'], 'subdomain' => $alias['pattern']);
+              $base_urls[$domain_id][] = domain_get_path($temp_domain);
+            }
           }
         }
       }
-- 
1.7.5.4


From 70c684ffd9daf254fa4eea7301484a5d92546931 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 14 Sep 2010 19:53:17 +0000
Subject: [PATCH 08/31] #911324 by dixon: use is_numeric not is_int.

---
 expire.module |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/expire.module b/expire.module
index b34c61b..a280092 100644
--- a/expire.module
+++ b/expire.module
@@ -142,7 +142,7 @@ function expire_node($node) {
     }
     $filenames = array();
     foreach ($tids as $tid) {
-      if (is_int($tid)) {
+      if (is_numeric($tid)) {
         $paths['term' . $tid] = 'taxonomy/term/' . $tid;
       }
     }
@@ -178,7 +178,7 @@ function expire_node($node) {
         if ($field['type'] == 'nodereference') {
           $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
           foreach ($node_field as $delta => $item) {
-            if (is_int($item['nid'])) {
+            if (is_numeric($item['nid'])) {
               $paths['reference' . $nid] = 'node/' . $item['nid'];
             }
           }
@@ -190,7 +190,7 @@ function expire_node($node) {
     if (module_exists('nodereferrer')) {
       $nids = nodereferrer_referrers($node->nid);
       foreach ($nids as $nid) {
-        if (is_int($nid['nid'])) {
+        if (is_numeric($nid['nid'])) {
           $paths['referrer' . $nid['nid']] = 'node/' . $nid['nid'];
         }
       }
-- 
1.7.5.4


From a141009e57d93dfeca6b90816144a4e45bebf8f0 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 14 Sep 2010 19:54:56 +0000
Subject: [PATCH 09/31] #911280 by dixon_: check if path is front page; if yes
 expire frontpage.

---
 expire.module |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/expire.module b/expire.module
index a280092..c32d401 100644
--- a/expire.module
+++ b/expire.module
@@ -325,6 +325,12 @@ function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = F
     // Given path
     $expire[] = $path;
 
+    // Add the empty front page path if this is the alias
+    if ($path == variable_get('site_frontpage', 'node')) {
+      $expire[] = '';
+      $expire[] = 'rss.xml';
+    }
+
     // Special front page feed handling
     if ($path == '' || $path == '<front>') {
       $expire[] = 'rss.xml';
-- 
1.7.5.4


From 07ac0071b74db9800621b711cb982174f5237e11 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Mon, 22 Nov 2010 04:14:01 +0000
Subject: [PATCH 10/31] #957016 by catch: Fix for votingapi so it works with
 comments.

---
 expire.module |   25 +++++++++++++++++--------
 1 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/expire.module b/expire.module
index c32d401..60328ed 100644
--- a/expire.module
+++ b/expire.module
@@ -62,11 +62,7 @@ function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  *  array of votes
  */
 function expire_votingapi_insert($votes) {
-  foreach ($votes as $vote) {
-    $node = node_load($vote['content_id']);
-    $node->nid = $vote['content_id'];
-    expire_node($node);
-  }
+  _expire_votingapi($votes);
 }
 
 /**
@@ -76,10 +72,23 @@ function expire_votingapi_insert($votes) {
  *  array of votes
  */
 function expire_votingapi_delete($votes) {
+  _expire_votingapi($votes);
+}
+
+/**
+ * Common expiry logic for votingapi.
+ */
+function _expire_votingapi($votes) {
   foreach ($votes as $vote) {
-    $node = node_load($vote['content_id']);
-    $node->nid = $vote['content_id'];
-    expire_node($node);
+    if ($vote['content_type'] == 'comment') {
+      $nid = db_result(db_query('SELECT nid FROM {comments} WHERE cid = %d', $vote['content_id']));
+      $node = node_load($nid);
+      expire_node($node);
+    }
+    if ($vote['content_type'] == 'node') {
+      $node = node_load($vote['content_id']);
+      expire_node($node);
+    }
   }
 }
 
-- 
1.7.5.4


From c5c6e964d3664a47b1867c2b8864b27dd9002b47 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 21 Dec 2010 10:21:26 +0000
Subject: [PATCH 11/31] #1002002 by fgm, mikeytown2: Allow other modules to
 modify the expire list.

---
 expire.module |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/expire.module b/expire.module
index 60328ed..2860dc8 100644
--- a/expire.module
+++ b/expire.module
@@ -101,7 +101,7 @@ function expire_user($op, &$edit, &$account, $category = NULL) {
       // Expire the relevant user page from the static page cache to prevent serving stale content:
       if (!empty($account->uid)) {
         $paths[] = 'user/' . $account->uid;
-        $flushed = expire_cache_derivative($account, $paths, TRUE, TRUE);
+        $flushed = expire_cache_derivative($account, $paths);
         watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
           '!uid' => $account->uid,
           '!flushed' => $flushed,
@@ -208,7 +208,7 @@ function expire_node($node) {
 
   // Flush array of paths
   if (!empty($paths)) {
-    $flushed = expire_cache_derivative($node, $paths, TRUE);
+    $flushed = expire_cache_derivative($node, $paths);
     watchdog('expire', 'Node !nid was flushed resulting in !flushed pages being expired from the cache',  array(
       '!nid' => $node->nid,
       '!flushed' => $flushed,
@@ -316,14 +316,12 @@ function expire_taxonomy_node_get_tids($nid) {
 /**
  * Finds all possible paths/redirects/aliases given the root path.
  *
+ * @param $node
+ *   node object
  * @param $paths
  *   Array of current URLs
- * @param $both
- *   Expire database & file
- * @param $force_flush
- *   Override the settings and kill the file
  */
-function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = FALSE) {
+function expire_cache_derivative(&$node, $paths) {
   global $base_path;
   $expire = array();
 
@@ -361,6 +359,9 @@ function expire_cache_derivative(&$node, $paths, $both = FALSE, $force_flush = F
     }
   }
 
+  // Allow other modules to modify the list prior to expiring
+  drupal_alter('expire_cache', $expire, $node, $paths);
+
   // Expire cached files
   if (empty($expire)) {
     return FALSE;
-- 
1.7.5.4


From 450eab9928aa2348b554df22af20545d8a11b472 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Thu, 23 Dec 2010 02:15:00 +0000
Subject: [PATCH 12/31] #1001308: use taxonomy_term_path for taxonomy paths.

---
 expire.module |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/expire.module b/expire.module
index 2860dc8..666ff40 100644
--- a/expire.module
+++ b/expire.module
@@ -139,6 +139,13 @@ function expire_node($node) {
   if (module_exists('taxonomy') && variable_get('expire_flush_node_terms', EXPIRE_FLUSH_NODE_TERMS)) {
     // Get old terms from DB
     $tids = expire_taxonomy_node_get_tids($node->nid);
+    // Get old terms from static variable
+    $terms = taxonomy_node_get_terms($node);
+    if (!empty($terms)) {
+      foreach ($terms as $term) {
+        $tids[$term->tid] = $term->tid;
+      }
+    }
     // Get new terms from node object
     if (!empty($node->taxonomy)) {
       foreach ($node->taxonomy as $vocab) {
@@ -152,7 +159,8 @@ function expire_node($node) {
     $filenames = array();
     foreach ($tids as $tid) {
       if (is_numeric($tid)) {
-        $paths['term' . $tid] = 'taxonomy/term/' . $tid;
+        $term = taxonomy_get_term($tid);
+        $paths['term' . $tid] = taxonomy_term_path($term);
       }
     }
   }
-- 
1.7.5.4


From 5a2c1066d6ef27479e22b1e9dff4087eb4c58596 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Thu, 23 Dec 2010 02:25:50 +0000
Subject: [PATCH 13/31] #998056 by fgm: add uninstall & admin page.

---
 expire.admin.inc |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 expire.info      |    6 ++--
 expire.install   |   25 +++++++++++++++++++++++
 expire.module    |   26 +++++++++++++++++++++++-
 4 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 expire.admin.inc
 create mode 100644 expire.install

diff --git a/expire.admin.inc b/expire.admin.inc
new file mode 100644
index 0000000..889a9c3
--- /dev/null
+++ b/expire.admin.inc
@@ -0,0 +1,58 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provides form for changing settings
+ */
+
+/**
+ * Implementation of the former hook_settings().
+ */
+function expire_admin_settings_form() {
+  drupal_set_title(t('Cache Expiration'));
+  $form['expire'] = array(
+    '#type'          => 'fieldset',
+    '#title'         => t('What to expire'),
+  );
+  $form['expire']['expire_flush_front'] = array(
+    '#type'        => 'checkbox',
+    '#title'       => t('Expire front page'),
+    '#default_value' => variable_get('expire_flush_front', EXPIRE_FLUSH_FRONT),
+    '#description'   => t('When expiring a node: if promoted to front page, expire front page.'),
+  );
+
+  $form['expire']['expire_flush_node_terms'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Expire node term pages'),
+    '#default_value' => variable_get('expire_flush_node_terms', EXPIRE_FLUSH_NODE_TERMS),
+    '#description'   => t('When expiring a node: expire taxonomy pages for its terms.'),
+  );
+
+  $form['expire']['expire_flush_menu_items'] = array(
+    '#type'          => 'radios',
+    '#title'         => t('Expire menus'),
+    '#options'       => array(0 => t('No'), EXPIRE_FLUSH_MENU_ITEMS => t('Family'), 2 => t('Entire menu')),
+    '#default_value' => variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS),
+    '#description'   => t('When expiring a node: expire related menu items or entire menu'),
+  );
+  $form['expire']['expire_flush_cck_references'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Expire CCK node references'),
+    '#default_value' => variable_get('expire_flush_cck_references', EXPIRE_FLUSH_CCK_REFERENCES),
+    '#description'   => t('When expiring a node: expire its node references and nodes containing it in their own ndoe references.'),
+  );
+
+  $form['format'] = array(
+    '#type'          => 'fieldset',
+    '#title'         => t('Expire protocol'),
+  );
+  $form['format']['expire_include_base_url'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Include base URL in expires'),
+    '#default_value' => variable_get('expire_include_base_url', EXPIRE_INCLUDE_BASE_URL),
+    '#description'   => t('Include the base URL in expire requests. Compatible with Domain Access'),
+  );
+
+  return system_settings_form($form);
+}
diff --git a/expire.info b/expire.info
index 68d9e26..524a5be 100644
--- a/expire.info
+++ b/expire.info
@@ -1,6 +1,6 @@
 ; $Id$
-name = Cache Expiration
-description = Logic for expiring page caches
+name = "Cache Expiration"
+description = "Logic for expiring page caches"
 recommends[] = nodereferrer
-package = Performance and scalability
+package = "Performance and scalability"
 core = 6.x
diff --git a/expire.install b/expire.install
new file mode 100644
index 0000000..7ec88d2
--- /dev/null
+++ b/expire.install
@@ -0,0 +1,25 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Install file for expire module
+ */
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function expire_uninstall() {
+  $vars = array(
+    'expire_flush_front',
+    'expire_flush_node_terms',
+    'expire_flush_menu_items',
+    'expire_flush_cck_references',
+    'expire_include_base_url',
+  );
+  foreach ($vars as $var) {
+    variable_del($var);
+  }
+  $t = get_t();
+  drupal_set_message($t('Removed Expire variables'));
+}
diff --git a/expire.module b/expire.module
index 666ff40..e718297 100644
--- a/expire.module
+++ b/expire.module
@@ -14,6 +14,29 @@ define('EXPIRE_FLUSH_FRONT', TRUE);
 define('EXPIRE_INCLUDE_BASE_URL', TRUE);
 
 /**
+ * Implementation of hook_menu().
+ */
+function expire_menu() {
+  $items = array();
+  $items['admin/settings/performance/default'] = array(
+    'title'             => 'Performance',
+    'type'              => MENU_DEFAULT_LOCAL_TASK,
+    'file path'         => drupal_get_path('module', 'system'),
+  );
+  $items['admin/settings/performance/expire'] = array(
+    'type'              => MENU_LOCAL_TASK,
+    'title'             => 'Cache Expiration',
+    'page callback'     => 'drupal_get_form',
+    'page arguments'    => array('expire_admin_settings_form'),
+    'access arguments'  => array('administer site configuration'),
+    'file path'         => drupal_get_path('module', 'boost'),
+    'file'              => 'expire.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
  * Implementation of hook_comment(). Acts on comment modification.
  */
 function expire_comment($comment, $op) {
@@ -119,7 +142,7 @@ function expire_user($op, &$edit, &$account, $category = NULL) {
  * @param $node
  *  node object
  */
-function expire_node($node) {
+function expire_node(&$node) {
   $paths = array();
 
   // Check node object
@@ -524,3 +547,4 @@ function expire_get_domains(&$node) {
   }
   return $domains;
 }
+
-- 
1.7.5.4


From fc5744d9db1f04b10829ecdee145ef85d87fa19c Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Thu, 23 Dec 2010 02:28:15 +0000
Subject: [PATCH 14/31] #968366: do not pass <front> in the output of the
 hook.

---
 expire.module |   15 +++++++--------
 1 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/expire.module b/expire.module
index e718297..a2ab8a2 100644
--- a/expire.module
+++ b/expire.module
@@ -359,19 +359,18 @@ function expire_cache_derivative(&$node, $paths) {
   if (empty($paths)) {
     return FALSE;
   }
+  $site_frontpage = variable_get('site_frontpage', 'node');
   foreach ($paths as $path) {
-    // Given path
-    $expire[] = $path;
-
-    // Add the empty front page path if this is the alias
-    if ($path == variable_get('site_frontpage', 'node')) {
+    // Special front page handling
+    if ($path == $site_frontpage || $path == '' || $path == '<front>') {
       $expire[] = '';
       $expire[] = 'rss.xml';
+      $expire[] = $site_frontpage;
     }
 
-    // Special front page feed handling
-    if ($path == '' || $path == '<front>') {
-      $expire[] = 'rss.xml';
+    // Add given path
+    if ($path != '<front>') {
+      $expire[] = $path;
     }
 
     // Path alias
-- 
1.7.5.4


From 9a8e2bcad254c943db5a857d00e56298d842eb5d Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Mon, 27 Dec 2010 19:46:12 +0000
Subject: [PATCH 15/31] #997806 by fgm, mikeytown2: give feedback on the
 status report of what modules are using expire.

---
 expire.install |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/expire.install b/expire.install
index 7ec88d2..44e0ea1 100644
--- a/expire.install
+++ b/expire.install
@@ -23,3 +23,47 @@ function expire_uninstall() {
   $t = get_t();
   drupal_set_message($t('Removed Expire variables'));
 }
+
+
+/**
+ * Implementation of hook_requirements().
+ *
+ * Make sure the module is not enabled and doing nothing useful.
+ */
+function expire_requirements($phase) {
+  if ($phase == 'install') {
+    return array();
+  }
+
+  $requirements = array();
+
+  // Check hook_expire_cache implementation.
+  $modules = module_implements('expire_cache');
+  if (empty($modules)) {
+    $requirements['hook status'] = array(
+      'value' => t('No expirable cache enabled'),
+      'description' => t('None of the enabled modules implements hook_expire_cache(). This means that expire.module will not be having any effect. You should enable a module implements this hook, like the <a href="http://drupal.org/project/varnish">Varnish</a> module.'),
+      'severity' => REQUIREMENT_WARNING,
+    );
+  }
+  else {
+    $requirements['hook status'] = array(
+      'value' => t('hook_expire_cache() implemented: @modules', array('@modules' => implode(', ', $modules))),
+      'severity' => REQUIREMENT_OK,
+    );
+    if (in_array('varnish', $modules)) {
+      if (variable_get('varnish_cache_clear', VARNISH_DEFAULT_CLEAR) == VARNISH_DEFAULT_CLEAR) {
+        $requirements['varnish status'] = array(
+          'value' => t('Varnish module is enabled, but configured to use default clearing: expire.module will be redundant with default clearing. Configure varnish.module to use selective clearing instead.'),
+          'severity' => REQUIREMENT_WARNING,
+        );
+      }
+    }
+  }
+
+ foreach ($requirements as $key => $value) {
+    $requirements[$key]['title'] = t('Cache Expiration - @key', array('@key' => $key));
+  }
+
+  return $requirements;
+}
-- 
1.7.5.4


From ba7f833b145442c2c11a8ceb47a12708513bdf16 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Mon, 27 Dec 2010 19:50:34 +0000
Subject: [PATCH 16/31] #997784 by fgm, mikeytown2: Add more cases to cache
 expiration.

---
 expire.module |  152 +++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 100 insertions(+), 52 deletions(-)

diff --git a/expire.module b/expire.module
index a2ab8a2..532f625 100644
--- a/expire.module
+++ b/expire.module
@@ -37,44 +37,91 @@ function expire_menu() {
 }
 
 /**
- * Implementation of hook_comment(). Acts on comment modification.
+ * Implementation of hook_comment().
+ *
+ * Acts on comment modification.
  */
 function expire_comment($comment, $op) {
   // Convert array to object
   if (is_array($comment)) {
-    $comment = (object)$comment;
-  }
-
-  // Expire the relevant node page from the static page cache to prevent serving stale content:
-  switch ($op) {
-    case 'insert':
-    case 'update':
-    case 'publish':
-    case 'unpublish':
-    case 'delete':
-      if (!empty($comment->nid)) {
-        $node = node_load($comment->nid);
-        $node->nid = $comment->nid;
-        expire_node($node);
-      }
-      break;
+    $comment = (object) $comment;
+  }
+
+  // Return if no node id is attached to the comment.
+  if (empty($comment->nid)) {
+    return;
+  }
+
+  // Select which comment opperations require a cache flush.
+  $cases = array(
+    'insert',
+    'update',
+    'publish',
+    'unpublish',
+    'delete',
+  );
+
+  // Expire the relevant node page from the static page cache to prevent serving stale content.
+  if (in_array($op, $cases)) {
+    $node = node_load($comment->nid);
+    if ($node) {
+      expire_node($node);
+    }
   }
 }
 
 /**
- * Implementation of hook_nodeapi(). Acts on nodes defined by other modules.
+ * Implementation of hook_nodeapi().
+ *
+ * Acts on nodes defined by other modules.
  */
 function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
-  switch ($op) {
-    case 'insert':
-      expire_node($node);
-      break;
-    case 'update':
-      expire_node($node);
-      break;
-    case 'delete':
-      expire_node($node);
-      break;
+  // Return if no node id is attached to the node object.
+  if (empty($node->nid)) {
+    return;
+  }
+
+  // Select which node opperations require a cache flush.
+  $cases = array(
+    'insert',
+    'update',
+    'delete',
+    'delete revision',
+  );
+
+  // Expire the relevant node page from the static page cache to prevent serving stale content.
+  if (in_array($op, $cases)) {
+    expire_node($node);
+  }
+}
+
+/**
+ * Implementation of hook_user().
+ *
+ * Acts on user account actions: expire the relevant user page from the static
+ * page cache to prevent serving stale content.
+ */
+function expire_user($op, &$edit, &$account, $category = NULL) {
+  // Return if no user id is attached to the user object.
+  if (empty($account->uid)) {
+    return;
+  }
+
+  // Select which user opperations require a cache flush.
+  $cases = array(
+    'insert',
+    'update',
+    'after update',
+  );
+
+  // Expire the relevant user page from the static page cache to prevent serving stale content.
+  if (in_array($op, $cases)) {
+    $paths[] = 'user/' . $account->uid;
+    $flushed = expire_cache_derivative($account, $paths, TRUE, TRUE);
+    watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
+      '!uid' => $account->uid,
+      '!flushed' => $flushed,
+    ));
   }
 }
 
@@ -104,33 +151,20 @@ function expire_votingapi_delete($votes) {
 function _expire_votingapi($votes) {
   foreach ($votes as $vote) {
     if ($vote['content_type'] == 'comment') {
-      $nid = db_result(db_query('SELECT nid FROM {comments} WHERE cid = %d', $vote['content_id']));
-      $node = node_load($nid);
-      expire_node($node);
+      $nid = db_result(db_query("SELECT nid FROM {comments} WHERE cid = %d", $vote['content_id']));
+      if (is_numeric($nid)) {
+        $node = node_load($nid);
+        if ($node) {
+          expire_node($node);
+        }
+      }
     }
     if ($vote['content_type'] == 'node') {
       $node = node_load($vote['content_id']);
-      expire_node($node);
-    }
-  }
-}
-
-/**
- * Implementation of hook_user(). Acts on user account actions.
- */
-function expire_user($op, &$edit, &$account, $category = NULL) {
-  switch ($op) {
-    case 'delete':
-      // Expire the relevant user page from the static page cache to prevent serving stale content:
-      if (!empty($account->uid)) {
-        $paths[] = 'user/' . $account->uid;
-        $flushed = expire_cache_derivative($account, $paths);
-        watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
-          '!uid' => $account->uid,
-          '!flushed' => $flushed,
-        ));
+      if ($node) {
+        expire_node($node);
       }
-      break;
+    }
   }
 }
 
@@ -219,7 +253,21 @@ function expire_node(&$node) {
           $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
           foreach ($node_field as $delta => $item) {
             if (is_numeric($item['nid'])) {
-              $paths['reference' . $nid] = 'node/' . $item['nid'];
+              $paths['reference' . $item['nid']] = 'node/'. $item['nid'];
+            }
+          }
+
+          // Look for node referers without using nodereferrer
+          $info = content_database_info($field);
+          $table = $info['table'];
+          $column = $info['columns']['nid']['column'];
+          $results = db_query("SELECT n.nid
+            FROM {%s} nr
+            INNER JOIN {node} n USING (vid)
+            WHERE nr.%s = %d", $table, $column, $node->nid);
+          while ($nid = db_result($results)) {
+            if (is_numeric($nid)) {
+              $paths['referenceparent' . $nid] = 'node/'. $nid;
             }
           }
         }
@@ -335,8 +383,8 @@ function expire_get_menu_structure($menu, $found, $needle, $first, &$found_globa
  *  http://drupal.org/node/545922
  */
 function expire_taxonomy_node_get_tids($nid) {
-  $vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $nid));
-  $result = db_query(db_rewrite_sql('SELECT t.tid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $vid);
+  $vid = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
+  $result = db_query(db_rewrite_sql("SELECT t.tid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name", 't', 'tid'), $vid);
   $tids = array();
   while ($term = db_result($result)) {
     $tids[] = $term;
-- 
1.7.5.4


From 06475fbe37d812bbc8d4862bd5356ddb44eee692 Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Fri, 4 Feb 2011 02:58:11 +0000
Subject: [PATCH 17/31] #1050308 by brianmercer: fix file path in hook menu.

---
 expire.module |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/expire.module b/expire.module
index 532f625..43667d7 100644
--- a/expire.module
+++ b/expire.module
@@ -29,7 +29,7 @@ function expire_menu() {
     'page callback'     => 'drupal_get_form',
     'page arguments'    => array('expire_admin_settings_form'),
     'access arguments'  => array('administer site configuration'),
-    'file path'         => drupal_get_path('module', 'boost'),
+    'file path'         => drupal_get_path('module', 'expire'),
     'file'              => 'expire.admin.inc',
   );
 
-- 
1.7.5.4


From a62315f12d4260f3c7d7d68b6b46cb8ec192feea Mon Sep 17 00:00:00 2001
From: Mike Carper <mikeytown2@282446.no-reply.drupal.org>
Date: Tue, 8 Feb 2011 08:44:25 +0000
Subject: [PATCH 18/31] #1054580: Add in rules support for expire.

---
 expire.module    |   18 ++++++--
 expire.rules.inc |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 126 insertions(+), 5 deletions(-)
 create mode 100644 expire.rules.inc

diff --git a/expire.module b/expire.module
index 43667d7..f1d4bb1 100644
--- a/expire.module
+++ b/expire.module
@@ -117,7 +117,7 @@ function expire_user($op, &$edit, &$account, $category = NULL) {
   // Expire the relevant user page from the static page cache to prevent serving stale content.
   if (in_array($op, $cases)) {
     $paths[] = 'user/' . $account->uid;
-    $flushed = expire_cache_derivative($account, $paths, TRUE, TRUE);
+    $flushed = expire_cache_derivative($paths, $account);
     watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
       '!uid' => $account->uid,
       '!flushed' => $flushed,
@@ -287,7 +287,7 @@ function expire_node(&$node) {
 
   // Flush array of paths
   if (!empty($paths)) {
-    $flushed = expire_cache_derivative($node, $paths);
+    $flushed = expire_cache_derivative($paths, $node);
     watchdog('expire', 'Node !nid was flushed resulting in !flushed pages being expired from the cache',  array(
       '!nid' => $node->nid,
       '!flushed' => $flushed,
@@ -395,12 +395,12 @@ function expire_taxonomy_node_get_tids($nid) {
 /**
  * Finds all possible paths/redirects/aliases given the root path.
  *
- * @param $node
- *   node object
  * @param $paths
  *   Array of current URLs
+ * @param $node
+ *   node object
  */
-function expire_cache_derivative(&$node, $paths) {
+function expire_cache_derivative($paths, &$node = NULL) {
   global $base_path;
   $expire = array();
 
@@ -595,3 +595,11 @@ function expire_get_domains(&$node) {
   return $domains;
 }
 
+function expire_normal_path_check($path) {
+  $original_map = arg(NULL, $path);
+  $parts = array_slice($original_map, 0, MENU_MAX_PARTS);
+  list($ancestors, $placeholders) = menu_get_ancestors($parts);
+
+  $router_item = db_fetch_array(db_query_range('SELECT path FROM {menu_router} WHERE path IN (' . implode(',', $placeholders) . ') ORDER BY fit DESC', $ancestors, 0, 1));
+  return $router_item;
+}
diff --git a/expire.rules.inc b/expire.rules.inc
new file mode 100644
index 0000000..a757f57
--- /dev/null
+++ b/expire.rules.inc
@@ -0,0 +1,113 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Integration with the rules module
+ */
+
+/**
+ * Implementation of hook_rules_action_info().
+ *
+ * @ingroup rules
+ */
+function expire_rules_action_info() {
+  return array(
+    'expire_rules_action_flush_url' => array(
+      'label' => t('Clear URL(s) from the page cache.'),
+      'arguments' => array(
+        'urls' => array('type' => 'string', 'label' => t('URL of page to clear')),
+      ),
+      'module' => 'Expire',
+    ),
+  );
+}
+
+/**
+ * Expire a URL from the page cache.
+ */
+function expire_rules_action_flush_url($urls, $settings) {
+  global $base_root, $base_path;
+  $urls = preg_replace("/\r\n/", "\n", $urls);
+  $urls = explode("\n", $urls);
+  $urls = array_map('trim', $urls);
+  $urls = array_filter($urls);
+  $urls_parsed = array_map('parse_url', $urls);
+
+  // Figure out what kind of URL's these are and act accordingly.
+  $full_urls = array();
+  $bad_paths = array();
+  $internal = array();
+  foreach ($urls_parsed as $key => $parts) {
+    if (!empty($parts['host'])) {
+      $full_urls[] = $urls[$key];
+    }
+    elseif (!empty($parts['path'])) {
+      // Strip base path from path.
+      $parts['path'] = preg_replace('/^' . preg_quote($base_path, '/') .'/i', '', $parts['path']);
+      if (empty($parts['path']) || $parts['path'] == '<front>') {
+        $internal[$key] = variable_get('site_frontpage', 'node');
+      }
+      else {
+        $normal = expire_normal_path_check($parts['path']);
+        if (is_array($normal)) {
+          $internal[$key] = $urls[$key];
+        }
+        else {
+          $normal = drupal_get_normal_path($parts['path']);
+          if ($normal == $parts['path']) {
+            // Bad path given
+            $bad_paths[$key] = $urls[$key];
+          }
+          else {
+            $internal[$key] = $normal;
+          }
+        }
+      }
+    }
+  }
+
+  if (!empty($bad_paths)){
+    watchdog('expire', 'Bad URL(s) given. !url do not match any given paths or aliases', array('!url' => expire_print_r($bad_paths)));
+  }
+
+  // Process internal paths
+  foreach ($internal as $key => $path) {
+    $arg = arg(NULL, $path);
+    if ($arg[0] == 'node' && !empty($arg[1]) && is_numeric($arg[1])) {
+      $node = node_load($arg[1]);
+      expire_node($node);
+      unset($internal[$key]);
+    }
+  }
+  if (!empty($internal)) {
+    $flushed = expire_cache_derivative($internal);
+  }
+
+  // Process Full URLs
+  // hook_expire_cache
+  $modules = module_implements('expire_cache');
+  foreach ($modules as $module) {
+    module_invoke($module, 'expire_cache', $full_urls);
+  }
+  watchdog('expire', 'Output: !urls <br /> Modules Using hook_expire_cache(): !modules', array(
+    '!urls' => expire_print_r($full_urls),
+    '!modules' => expire_print_r($modules),
+  ));
+
+}
+
+/**
+ * Action clear page from cache configuration form.
+ */
+function expire_rules_action_flush_url_form($settings, &$form) {
+  $settings += array('urls' => '');
+
+  $form['settings']['urls'] = array(
+    '#type' => 'textarea',
+    '#title' => t('URL(s)'),
+    '#default_value' => $settings['urls'],
+    '#description' => t('Full URL (including http://); node/8; taxonomy/term/3; user/5; path alias; & <front> will work. One Per line.'),
+  );
+
+}
-- 
1.7.5.4


From b8c7becf4fd53eb769ee0e27c24b4da95b8891a5 Mon Sep 17 00:00:00 2001
From: The Great Git Migration <tggm@no-reply.drupal.org>
Date: Fri, 25 Feb 2011 02:12:25 +0000
Subject: [PATCH 19/31] Stripping CVS keywords

---
 expire.admin.inc |    1 -
 expire.info      |    1 -
 expire.install   |    1 -
 expire.module    |    1 -
 expire.rules.inc |    1 -
 5 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/expire.admin.inc b/expire.admin.inc
index 889a9c3..588041e 100644
--- a/expire.admin.inc
+++ b/expire.admin.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * @file
diff --git a/expire.info b/expire.info
index 524a5be..16ce766 100644
--- a/expire.info
+++ b/expire.info
@@ -1,4 +1,3 @@
-; $Id$
 name = "Cache Expiration"
 description = "Logic for expiring page caches"
 recommends[] = nodereferrer
diff --git a/expire.install b/expire.install
index 44e0ea1..51101ae 100644
--- a/expire.install
+++ b/expire.install
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * @file
diff --git a/expire.module b/expire.module
index f1d4bb1..586816b 100644
--- a/expire.module
+++ b/expire.module
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * @file
diff --git a/expire.rules.inc b/expire.rules.inc
index a757f57..71229ef 100644
--- a/expire.rules.inc
+++ b/expire.rules.inc
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * @file
-- 
1.7.5.4


From 820241c9710be0838004b93651627cfc8ecdb9da Mon Sep 17 00:00:00 2001
From: mc <paul@krischer.nl>
Date: Sat, 5 Mar 2011 22:42:50 +0100
Subject: [PATCH 20/31] Issue #1054584 by SqyD: Drush integration.

---
 expire.drush.inc |  118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 118 insertions(+), 0 deletions(-)
 create mode 100644 expire.drush.inc

diff --git a/expire.drush.inc b/expire.drush.inc
new file mode 100644
index 0000000..2518124
--- /dev/null
+++ b/expire.drush.inc
@@ -0,0 +1,118 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * This is the drush integration for the expire module
+ */
+
+/**
+ * Implementation of hook_drush_command().
+ */
+function expire_drush_command() {
+  $items['expire-url'] = array(
+    'description' => "Expire fully qualified URLs.",
+    'arguments' => array(
+      'urls' => 'URLs to expire separated by spaces.',
+    ),
+    'examples' => array(
+      'drush expire-url http://example.com/testpage.html' => 'Expire a single URL.',
+      'drush xu http://example.com/ http://test.com/logo.jpg' => 'Expire multiple URLs.',
+    ),
+    'aliases' => array('xu'),
+    'drupal dependencies' => array('expire'),
+    'callback' => 'drush_expire_url'
+  );
+  $items['expire-path'] = array(
+    'description' => "Expire a drupal path.",
+    'arguments' => array(
+      'paths' => 'A list drupal paths to expire separated by spaces.',
+    ),
+    'examples' => array(
+      'drush expire-path node/123' => 'Expire a single drupal path.',
+      'drush expire-path FRONT' => 'Expire the front page.',
+      'drush xp FRONT node/234 contact' => 'Expire multiple drupal paths.',
+    ),
+    'aliases' => array('xp'),
+    'drupal dependencies' => array('expire'),
+    'callback' => 'drush_expire_path'
+  );
+  $items['expire-node'] = array(
+    'description' => "Expire a node by node-id.",
+    'arguments' => array(
+      'nids' => 'Numeric node-ids to expire separated by spaces.',
+    ),
+    'examples' => array(
+      'drush expire-node 2 24 612' => 'Expire drupal nodes by node id',
+    ),
+    'aliases' => array('xn'),
+    'drupal dependencies' => array('expire'),
+    'callback' => 'drush_expire_nid'
+  );
+  return $items;
+}
+
+/**
+ * Callback for expire-url drush command.
+ * @param string $urls a space separated list of paths.
+ */
+function drush_expire_url() {
+  $full_urls = array();
+  $full_urls = drush_get_arguments();
+  unset($full_urls[0]);
+  // Process Full URLs
+  // hook_expire_cache
+  $modules = module_implements('expire_cache');
+  foreach ($modules as $module) {
+    module_invoke($module, 'expire_cache', $full_urls);
+  }
+  watchdog('expire', 'Output: !urls <br /> Modules Using hook_expire_cache(): !modules', array(
+    '!urls' => expire_print_r($full_urls),
+    '!modules' => expire_print_r($modules),
+  ));
+}
+
+/**
+ * Callback for expire-path drush command.
+ * @param string $urls a space separated list of paths.
+ */
+function drush_expire_path() {
+  global $base_path;
+  $internal = array();
+  $paths = array();
+  $paths = drush_get_arguments();
+  unset($paths[0]);
+  foreach ($paths as $path) {
+    // Strip base path from path.
+    $path_nobase = preg_replace('/^' . preg_quote($base_path, '/') .'/i', '', $path);
+    if ($path == 'FRONT') {
+      $internal[] = variable_get('site_frontpage', 'node');
+    }
+    else {
+      $normal = expire_normal_path_check($path_nobase);
+      if (is_array($normal)) {
+        $internal[] = $path;
+      }
+      else {
+        $normal = drupal_get_normal_path($path_nobase);
+        $internal[] = $normal;
+      }
+    }
+  }
+  $flushed = expire_cache_derivative($internal);
+}
+
+/**
+ * Callback for expire-node drush command.
+ * @param string $nids a space separated list of paths.
+ */
+function drush_expire_nid() {
+  $nids = drush_get_arguments();
+  unset($nids[0]);
+  foreach ($nids as $nid) {
+    if (is_numeric($nid)) {
+      $node = node_load($nid);
+      expire_node($node);
+    }
+  }
+}
-- 
1.7.5.4


From f116451adf647da8a4711f45672399a4c2b2e7d0 Mon Sep 17 00:00:00 2001
From: Paul <paul@krischer.nl>
Date: Thu, 1 Sep 2011 20:03:02 +0200
Subject: [PATCH 21/31] Initial D7 port. Settings and drush xu seem to work
 now.

---
 expire.info   |    7 ++++++-
 expire.module |    5 +++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/expire.info b/expire.info
index 16ce766..7d72ec9 100644
--- a/expire.info
+++ b/expire.info
@@ -2,4 +2,9 @@ name = "Cache Expiration"
 description = "Logic for expiring page caches"
 recommends[] = nodereferrer
 package = "Performance and scalability"
-core = 6.x
+core = 7.x
+
+files[] = expire.module
+files[] = expire.admin.inc
+files[] = expire.drush.inc
+files[] = expire.rules.inc
diff --git a/expire.module b/expire.module
index 586816b..e3ca582 100644
--- a/expire.module
+++ b/expire.module
@@ -17,12 +17,13 @@ define('EXPIRE_INCLUDE_BASE_URL', TRUE);
  */
 function expire_menu() {
   $items = array();
-  $items['admin/settings/performance/default'] = array(
+  $items['admin/config/development/performance/default'] = array(
     'title'             => 'Performance',
     'type'              => MENU_DEFAULT_LOCAL_TASK,
     'file path'         => drupal_get_path('module', 'system'),
+    'weight'            => -5,
   );
-  $items['admin/settings/performance/expire'] = array(
+  $items['admin/config/development/performance/expire'] = array(
     'type'              => MENU_LOCAL_TASK,
     'title'             => 'Cache Expiration',
     'page callback'     => 'drupal_get_form',
-- 
1.7.5.4


From af56ec45cbce8f3352155abdea4abd5f32d1f4cd Mon Sep 17 00:00:00 2001
From: Paul <paul@krischer.nl>
Date: Fri, 2 Sep 2011 01:14:36 +0200
Subject: [PATCH 22/31] Started with changing out hook_comment and hook_node
 replacements.

---
 expire.info   |    1 +
 expire.module |  103 +++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 83 insertions(+), 21 deletions(-)

diff --git a/expire.info b/expire.info
index 7d72ec9..3423afd 100644
--- a/expire.info
+++ b/expire.info
@@ -8,3 +8,4 @@ files[] = expire.module
 files[] = expire.admin.inc
 files[] = expire.drush.inc
 files[] = expire.rules.inc
+configure = admin/config/development/performance/expire
diff --git a/expire.module b/expire.module
index e3ca582..f08934e 100644
--- a/expire.module
+++ b/expire.module
@@ -36,41 +36,88 @@ function expire_menu() {
   return $items;
 }
 
+
 /**
- * Implementation of hook_comment().
+ * Implements hook_comment_insert().
  *
- * Acts on comment modification.
+ * Acts on new comments.
  */
-function expire_comment($comment, $op) {
-  // Convert array to object
-  if (is_array($comment)) {
-    $comment = (object) $comment;
+function expire_comment_insert($comment) {
+  // Return if no node id is attached to the comment.
+  if (empty($comment->nid)) {
+    return;
   }
 
-  // Return if no node id is attached to the comment.
+  // Expire the relevant node page from the static page cache to prevent serving stale content.
+  $node = node_load($comment->nid);
+  if ($node) {
+    expire_node($node);
+  }
+}
+
+/**
+ * Implements hook_comment_update().
+ *
+ * Acts on comments updates.
+ */
+function expire_comment_update($comment) {
   if (empty($comment->nid)) {
     return;
   }
+  $node = node_load($comment->nid);
+  if ($node) {
+    expire_node($node);
+  }
+}
 
-  // Select which comment opperations require a cache flush.
-  $cases = array(
-    'insert',
-    'update',
-    'publish',
-    'unpublish',
-    'delete',
-  );
+/**
+ * Implements hook_comment_publish().
+ *
+ * Acts when publishing comments.
+ */
+function expire_comment_publish($comment) {
+  if (empty($comment->nid)) {
+    return;
+  }
+  $node = node_load($comment->nid);
+  if ($node) {
+    expire_node($node);
+  }
+}
 
-  // Expire the relevant node page from the static page cache to prevent serving stale content.
-  if (in_array($op, $cases)) {
-    $node = node_load($comment->nid);
-    if ($node) {
-      expire_node($node);
-    }
+/**
+ * Implements hook_comment_unpublish().
+ *
+ * Acts when unpublishing comments.
+ */
+function expire_comment_unpublish($comment) {
+  if (empty($comment->nid)) {
+    return;
+  }
+  $node = node_load($comment->nid);
+  if ($node) {
+    expire_node($node);
   }
 }
 
 /**
+/**
+ * Implements hook_comment_delete().
+ *
+ * Acts when deleting comments.
+ */
+function expire_comment_delete($comment) {
+  if (empty($comment->nid)) {
+    return;
+  }
+  $node = node_load($comment->nid);
+  if ($node) {
+    expire_node($node);
+  }
+}
+
+
+/**
  * Implementation of hook_nodeapi().
  *
  * Acts on nodes defined by other modules.
@@ -96,6 +143,20 @@ function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
 }
 
 /**
+ * Implements hook_node_insert().
+ * 
+ * Acts on new nodes.
+ */
+function expire_node_insert($node) {
+  if (empty($node->nid)) {
+    return;
+  }
+  else {
+    expire_node($node);
+  }
+}
+
+/**
  * Implementation of hook_user().
  *
  * Acts on user account actions: expire the relevant user page from the static
-- 
1.7.5.4


From d039f5034b453a26bfbb9eb2a1e8570b9d7aef23 Mon Sep 17 00:00:00 2001
From: Paul <paul@krischer.nl>
Date: Sat, 3 Sep 2011 00:21:18 +0200
Subject: [PATCH 23/31] Node api hooks replaced with D7 versions. Expire now
 works! (with taxonomy off.)

---
 expire.module |   52 +++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/expire.module b/expire.module
index f08934e..5d2ad67 100644
--- a/expire.module
+++ b/expire.module
@@ -118,36 +118,53 @@ function expire_comment_delete($comment) {
 
 
 /**
- * Implementation of hook_nodeapi().
- *
- * Acts on nodes defined by other modules.
+ * Implements hook_node_insert().
+ * 
+ * Acts on new nodes.
  */
-function expire_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
-  // Return if no node id is attached to the node object.
+function expire_node_insert($node) {
   if (empty($node->nid)) {
     return;
   }
+  else {
+    expire_node($node);
+  }
+}
 
-  // Select which node opperations require a cache flush.
-  $cases = array(
-    'insert',
-    'update',
-    'delete',
-    'delete revision',
-  );
+/**
+ * Implements hook_node_update().
+ * 
+ * Acts on node updates.
+ */
+function expire_node_update($node) {
+  if (empty($node->nid)) {
+    return;
+  }
+  else {
+    expire_node($node);
+  }
+}
 
-  // Expire the relevant node page from the static page cache to prevent serving stale content.
-  if (in_array($op, $cases)) {
+/**
+ * Implements hook_node_delete().
+ * 
+ * Acts on deletion of nodes.
+ */
+function expire_node_delete($node) {
+  if (empty($node->nid)) {
+    return;
+  }
+  else {
     expire_node($node);
   }
 }
 
 /**
- * Implements hook_node_insert().
+ * Implements hook_node_revision_delete().
  * 
- * Acts on new nodes.
+ * Acts on deletion of revisions.
  */
-function expire_node_insert($node) {
+function expire_node_revision_delete($node) {
   if (empty($node->nid)) {
     return;
   }
@@ -156,6 +173,7 @@ function expire_node_insert($node) {
   }
 }
 
+
 /**
  * Implementation of hook_user().
  *
-- 
1.7.5.4


From 1f2534b1c5140500621c973f0ede6684222b7ee8 Mon Sep 17 00:00:00 2001
From: Paul <paul@krischer.nl>
Date: Sat, 3 Sep 2011 10:44:47 +0200
Subject: [PATCH 24/31] Hooks for user events upgraded to d7 versions.

---
 expire.module |   64 +++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/expire.module b/expire.module
index 5d2ad67..cfb5893 100644
--- a/expire.module
+++ b/expire.module
@@ -175,35 +175,63 @@ function expire_node_revision_delete($node) {
 
 
 /**
- * Implementation of hook_user().
+ * Implements hook_user_insert
  *
- * Acts on user account actions: expire the relevant user page from the static
- * page cache to prevent serving stale content.
+ * Acts on user account creation
  */
-function expire_user($op, &$edit, &$account, $category = NULL) {
+function expire_user_insert(&$edit, $account, $category = NULL) {
   // Return if no user id is attached to the user object.
   if (empty($account->uid)) {
     return;
   }
+  // Expire the relevant user page from the static page cache to prevent serving stale content.
+  $paths[] = 'user/' . $account->uid;
+  $flushed = expire_cache_derivative($paths, $account);
+  watchdog('expire', 'User !uid was created resulting in !flushed pages being expired from the cache',  array(
+    '!uid' => $account->uid,
+    '!flushed' => $flushed,
+  ));
+}
 
-  // Select which user opperations require a cache flush.
-  $cases = array(
-    'insert',
-    'update',
-    'after update',
-  );
-
+/**
+ * Implements hook_user_delete
+ *
+ * Acts on user account deletion
+ */
+function expire_user_delete(&$edit, $account, $category = NULL) {
+  // Return if no user id is attached to the user object.
+  if (empty($account->uid)) {
+    return;
+  }
   // Expire the relevant user page from the static page cache to prevent serving stale content.
-  if (in_array($op, $cases)) {
-    $paths[] = 'user/' . $account->uid;
-    $flushed = expire_cache_derivative($paths, $account);
-    watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
-      '!uid' => $account->uid,
-      '!flushed' => $flushed,
-    ));
+  $paths[] = 'user/' . $account->uid;
+  $flushed = expire_cache_derivative($paths, $account);
+  watchdog('expire', 'User !uid was deleted resulting in !flushed pages being expired from the cache',  array(
+    '!uid' => $account->uid,
+    '!flushed' => $flushed,
+  ));
+}
+
+/**
+ * Implements hook_user_update
+ *
+ * Acts on user account updates
+ */
+function expire_user_update(&$edit, $account, $category = NULL) {
+  // Return if no user id is attached to the user object.
+  if (empty($account->uid)) {
+    return;
   }
+  // Expire the relevant user page from the static page cache to prevent serving stale content.
+  $paths[] = 'user/' . $account->uid;
+  $flushed = expire_cache_derivative($paths, $account);
+  watchdog('expire', 'User !uid was updated resulting in !flushed pages being expired from the cache',  array(
+    '!uid' => $account->uid,
+    '!flushed' => $flushed,
+  ));
 }
 
+
 /**
  * Implementation of hook_votingapi_insert().
  *
-- 
1.7.5.4


From 944516ed6a460df5dc29ed3ee038b412ee687d48 Mon Sep 17 00:00:00 2001
From: Mark Sonnabaum <mark@sonnabaum.com>
Date: Mon, 19 Dec 2011 10:24:08 -0600
Subject: [PATCH 25/31] Updated query in expire_normal_path_check to use DBTNG
 syntax.

---
 expire.module |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/expire.module b/expire.module
index cfb5893..e9c0057 100644
--- a/expire.module
+++ b/expire.module
@@ -707,6 +707,6 @@ function expire_normal_path_check($path) {
   $parts = array_slice($original_map, 0, MENU_MAX_PARTS);
   list($ancestors, $placeholders) = menu_get_ancestors($parts);
 
-  $router_item = db_fetch_array(db_query_range('SELECT path FROM {menu_router} WHERE path IN (' . implode(',', $placeholders) . ') ORDER BY fit DESC', $ancestors, 0, 1));
+  $router_item = db_query_range('SELECT path FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
   return $router_item;
 }
-- 
1.7.5.4


From 22a41183d9468fd73cb785b5aa8b6eaeae529227 Mon Sep 17 00:00:00 2001
From: Mark Sonnabaum <mark@sonnabaum.com>
Date: Wed, 28 Dec 2011 22:05:10 -0600
Subject: [PATCH 26/31] Issue #1373508: Update rules support for D7.

---
 expire.rules.inc |   28 +++++++++-------------------
 1 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/expire.rules.inc b/expire.rules.inc
index 71229ef..6f381a0 100644
--- a/expire.rules.inc
+++ b/expire.rules.inc
@@ -12,12 +12,17 @@
  */
 function expire_rules_action_info() {
   return array(
-    'expire_rules_action_flush_url' => array(
+    'expire_flush_url' => array(
+      'base' => 'expire_rules_action_flush_url',
       'label' => t('Clear URL(s) from the page cache.'),
-      'arguments' => array(
-        'urls' => array('type' => 'string', 'label' => t('URL of page to clear')),
+      'parameter' => array(
+        'urls' => array(
+          'type' => 'text',
+          'label' => t('URL of page to clear'),
+          'description' => t('Full URL (including http://); node/8; taxonomy/term/3; user/5; path alias; & <front> will work. One Per line.'),
+        ),
       ),
-      'module' => 'Expire',
+      'group' => 'Expire',
     ),
   );
 }
@@ -95,18 +100,3 @@ function expire_rules_action_flush_url($urls, $settings) {
   ));
 
 }
-
-/**
- * Action clear page from cache configuration form.
- */
-function expire_rules_action_flush_url_form($settings, &$form) {
-  $settings += array('urls' => '');
-
-  $form['settings']['urls'] = array(
-    '#type' => 'textarea',
-    '#title' => t('URL(s)'),
-    '#default_value' => $settings['urls'],
-    '#description' => t('Full URL (including http://); node/8; taxonomy/term/3; user/5; path alias; & <front> will work. One Per line.'),
-  );
-
-}
-- 
1.7.5.4


From c9db72c244cd5cf7d7b4a0e788b1918d0d2f48a7 Mon Sep 17 00:00:00 2001
From: Paul <paul@krischer.nl>
Date: Thu, 29 Dec 2011 16:51:01 +0100
Subject: [PATCH 27/31] Issue #1362078 by jaydub: Spelling correction

---
 expire.admin.inc |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/expire.admin.inc b/expire.admin.inc
index 588041e..a4c4468 100644
--- a/expire.admin.inc
+++ b/expire.admin.inc
@@ -39,7 +39,7 @@ function expire_admin_settings_form() {
     '#type'          => 'checkbox',
     '#title'         => t('Expire CCK node references'),
     '#default_value' => variable_get('expire_flush_cck_references', EXPIRE_FLUSH_CCK_REFERENCES),
-    '#description'   => t('When expiring a node: expire its node references and nodes containing it in their own ndoe references.'),
+    '#description'   => t('When expiring a node: expire its node references and nodes containing it in their own node references.'),
   );
 
   $form['format'] = array(
-- 
1.7.5.4


From 2ff9af26e0cdb9ad2e9a73e4d34ccf967a2437dc Mon Sep 17 00:00:00 2001
From: Paul <paul@krischer.nl>
Date: Thu, 29 Dec 2011 17:31:38 +0100
Subject: [PATCH 28/31] Issue #1299692 by djboddydrake, jaydub: Null path
 retrieved from path redirect, leading to global flush

---
 expire.module |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/expire.module b/expire.module
index e9c0057..fe6e09a 100644
--- a/expire.module
+++ b/expire.module
@@ -538,7 +538,9 @@ function expire_cache_derivative($paths, &$node = NULL) {
       $path_redirects = expire_path_redirect_load(array('redirect' => $path));
       if (isset($path_redirects)) {
         foreach ($path_redirects as $path_redirect) {
-          $expire[] = $path_redirect['path'];
+          if (!empty($path_redirect['redirect'])) {
+            $expire[] = $path_redirect['redirect'];
+          }
         }
       }
     }
-- 
1.7.5.4


From a22023ff46e79eed1744675e1e162dd0bfe61f3e Mon Sep 17 00:00:00 2001
From: Mark Sonnabaum <mark@sonnabaum.com>
Date: Mon, 2 Jan 2012 22:53:06 -0600
Subject: [PATCH 29/31] Issue #1363964 by nevets, beejeebus: Change
 menu_nodeapi to menu_node_prepare for D7.

---
 expire.module |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/expire.module b/expire.module
index fe6e09a..67d82a4 100644
--- a/expire.module
+++ b/expire.module
@@ -332,7 +332,7 @@ function expire_node(&$node) {
   // Get menu and flush related items in the menu.
   if (variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS) !=0) {
     if (!isset($node->menu['menu_name'])) {
-      menu_nodeapi($node, 'prepare');
+      menu_node_prepare($node);
     }
     $menu = menu_tree_all_data($node->menu['menu_name']);
     $tempa = NULL;
-- 
1.7.5.4


From 9dfd111cfca11379855c8c5a0f6c9b48b0611959 Mon Sep 17 00:00:00 2001
From: Elliot Pahl <elliot@catalyst.net.nz>
Date: Wed, 22 Feb 2012 03:17:30 +1300
Subject: [PATCH 30/31] Update for DBTNG, domain, node_reference,
 path_redirect->redirect, taxonomy, and votingapi
 updates.

---
 expire.admin.inc          |   47 ++++++----
 expire.domain.inc         |   29 ++++++
 expire.info               |    3 +
 expire.install            |    2 +-
 expire.module             |  224 +++++---------------------------------------
 expire.node_reference.inc |   35 +++++++
 expire.votingapi.inc      |   46 +++++++++
 7 files changed, 168 insertions(+), 218 deletions(-)
 create mode 100644 expire.domain.inc
 create mode 100644 expire.node_reference.inc
 create mode 100644 expire.votingapi.inc

diff --git a/expire.admin.inc b/expire.admin.inc
index a4c4468..b104251 100644
--- a/expire.admin.inc
+++ b/expire.admin.inc
@@ -14,6 +14,7 @@ function expire_admin_settings_form() {
     '#type'          => 'fieldset',
     '#title'         => t('What to expire'),
   );
+
   $form['expire']['expire_flush_front'] = array(
     '#type'        => 'checkbox',
     '#title'       => t('Expire front page'),
@@ -21,31 +22,39 @@ function expire_admin_settings_form() {
     '#description'   => t('When expiring a node: if promoted to front page, expire front page.'),
   );
 
-  $form['expire']['expire_flush_node_terms'] = array(
-    '#type'          => 'checkbox',
-    '#title'         => t('Expire node term pages'),
-    '#default_value' => variable_get('expire_flush_node_terms', EXPIRE_FLUSH_NODE_TERMS),
-    '#description'   => t('When expiring a node: expire taxonomy pages for its terms.'),
-  );
+  if (module_exists('taxonomy')) {
+    $form['expire']['expire_flush_node_terms'] = array(
+      '#type'          => 'checkbox',
+      '#title'         => t('Expire node term pages'),
+      '#default_value' => variable_get('expire_flush_node_terms', EXPIRE_FLUSH_NODE_TERMS),
+      '#description'   => t('When expiring a node: expire taxonomy pages for its terms.'),
+    );
+  }
 
-  $form['expire']['expire_flush_menu_items'] = array(
-    '#type'          => 'radios',
-    '#title'         => t('Expire menus'),
-    '#options'       => array(0 => t('No'), EXPIRE_FLUSH_MENU_ITEMS => t('Family'), 2 => t('Entire menu')),
-    '#default_value' => variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS),
-    '#description'   => t('When expiring a node: expire related menu items or entire menu'),
-  );
-  $form['expire']['expire_flush_cck_references'] = array(
-    '#type'          => 'checkbox',
-    '#title'         => t('Expire CCK node references'),
-    '#default_value' => variable_get('expire_flush_cck_references', EXPIRE_FLUSH_CCK_REFERENCES),
-    '#description'   => t('When expiring a node: expire its node references and nodes containing it in their own node references.'),
-  );
+  if (module_exists('menu')) {
+    $form['expire']['expire_flush_menu_items'] = array(
+      '#type'          => 'radios',
+      '#title'         => t('Expire menus'),
+      '#options'       => array(0 => t('No'), EXPIRE_FLUSH_MENU_ITEMS => t('Family'), 2 => t('Entire menu')),
+      '#default_value' => variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS),
+      '#description'   => t('When expiring a node: expire related menu items or entire menu'),
+    );
+  }
+
+  if (module_exists('node_reference')) {
+    $form['expire']['expire_flush_node_references'] = array(
+      '#type'          => 'checkbox',
+      '#title'         => t('Expire node references'),
+      '#default_value' => variable_get('expire_flush_node_references', EXPIRE_FLUSH_NODE_REFERENCES),
+      '#description'   => t('When expiring a node: expire its node references and nodes containing it in their own node references.'),
+    );
+  }
 
   $form['format'] = array(
     '#type'          => 'fieldset',
     '#title'         => t('Expire protocol'),
   );
+
   $form['format']['expire_include_base_url'] = array(
     '#type'          => 'checkbox',
     '#title'         => t('Include base URL in expires'),
diff --git a/expire.domain.inc b/expire.domain.inc
new file mode 100644
index 0000000..7bc221f
--- /dev/null
+++ b/expire.domain.inc
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * Get domains the node is currently published to
+ *
+ * @param $node
+ *   node object
+ * @return array
+ *   array('$gid' => $gid)
+ */
+function expire_get_domains(&$node) {
+  $domains = array();
+  if ($node->nid) {
+    $result = db_query("SELECT gid FROM {domain_access} WHERE nid = :nid", array(':nid' => $node->nid));
+    while ($row = db_fetch_array($result)) {
+      $gid = $row['gid'];
+      $domains[$gid] = $gid;
+    }
+  }
+  elseif ($node->mail && $node->name) {
+    $result = db_query("SELECT domain_id FROM {domain_editor} WHERE uid = :uid", array(':uid' => $node->uid));
+    while ($row = db_fetch_array($result)) {
+      $gid = $row['domain_id'];
+      $domains[$gid] = $gid;
+    }
+  }
+  return $domains;
+}
+
diff --git a/expire.info b/expire.info
index 3423afd..7f18e25 100644
--- a/expire.info
+++ b/expire.info
@@ -6,6 +6,9 @@ core = 7.x
 
 files[] = expire.module
 files[] = expire.admin.inc
+files[] = expire.domain.inc
 files[] = expire.drush.inc
+files[] = expire.node_reference.inc
 files[] = expire.rules.inc
+files[] = expire.votingapi.inc
 configure = admin/config/development/performance/expire
diff --git a/expire.install b/expire.install
index 51101ae..e425154 100644
--- a/expire.install
+++ b/expire.install
@@ -13,7 +13,7 @@ function expire_uninstall() {
     'expire_flush_front',
     'expire_flush_node_terms',
     'expire_flush_menu_items',
-    'expire_flush_cck_references',
+    'expire_flush_node_references',
     'expire_include_base_url',
   );
   foreach ($vars as $var) {
diff --git a/expire.module b/expire.module
index 67d82a4..476910c 100644
--- a/expire.module
+++ b/expire.module
@@ -8,7 +8,7 @@
 // Defaults used if variable_get is not set.
 define('EXPIRE_FLUSH_NODE_TERMS', TRUE);
 define('EXPIRE_FLUSH_MENU_ITEMS', 1);
-define('EXPIRE_FLUSH_CCK_REFERENCES', TRUE);
+define('EXPIRE_FLUSH_NODE_REFERENCES', TRUE);
 define('EXPIRE_FLUSH_FRONT', TRUE);
 define('EXPIRE_INCLUDE_BASE_URL', TRUE);
 
@@ -119,7 +119,7 @@ function expire_comment_delete($comment) {
 
 /**
  * Implements hook_node_insert().
- * 
+ *
  * Acts on new nodes.
  */
 function expire_node_insert($node) {
@@ -133,7 +133,7 @@ function expire_node_insert($node) {
 
 /**
  * Implements hook_node_update().
- * 
+ *
  * Acts on node updates.
  */
 function expire_node_update($node) {
@@ -147,7 +147,7 @@ function expire_node_update($node) {
 
 /**
  * Implements hook_node_delete().
- * 
+ *
  * Acts on deletion of nodes.
  */
 function expire_node_delete($node) {
@@ -161,7 +161,7 @@ function expire_node_delete($node) {
 
 /**
  * Implements hook_node_revision_delete().
- * 
+ *
  * Acts on deletion of revisions.
  */
 function expire_node_revision_delete($node) {
@@ -231,50 +231,6 @@ function expire_user_update(&$edit, $account, $category = NULL) {
   ));
 }
 
-
-/**
- * Implementation of hook_votingapi_insert().
- *
- * @param $votes
- *  array of votes
- */
-function expire_votingapi_insert($votes) {
-  _expire_votingapi($votes);
-}
-
-/**
- * Implementation of hook_votingapi_delete().
- *
- * @param $votes
- *  array of votes
- */
-function expire_votingapi_delete($votes) {
-  _expire_votingapi($votes);
-}
-
-/**
- * Common expiry logic for votingapi.
- */
-function _expire_votingapi($votes) {
-  foreach ($votes as $vote) {
-    if ($vote['content_type'] == 'comment') {
-      $nid = db_result(db_query("SELECT nid FROM {comments} WHERE cid = %d", $vote['content_id']));
-      if (is_numeric($nid)) {
-        $node = node_load($nid);
-        if ($node) {
-          expire_node($node);
-        }
-      }
-    }
-    if ($vote['content_type'] == 'node') {
-      $node = node_load($vote['content_id']);
-      if ($node) {
-        expire_node($node);
-      }
-    }
-  }
-}
-
 /**
  * Expires a node from the cache; including related pages.
  *
@@ -283,7 +239,7 @@ function _expire_votingapi($votes) {
  * @param $node
  *  node object
  */
-function expire_node(&$node) {
+function expire_node($node) {
   $paths = array();
 
   // Check node object
@@ -301,36 +257,22 @@ function expire_node(&$node) {
 
   // Get taxonomy terms and flush
   if (module_exists('taxonomy') && variable_get('expire_flush_node_terms', EXPIRE_FLUSH_NODE_TERMS)) {
-    // Get old terms from DB
-    $tids = expire_taxonomy_node_get_tids($node->nid);
-    // Get old terms from static variable
-    $terms = taxonomy_node_get_terms($node);
-    if (!empty($terms)) {
-      foreach ($terms as $term) {
-        $tids[$term->tid] = $term->tid;
-      }
-    }
-    // Get new terms from node object
-    if (!empty($node->taxonomy)) {
-      foreach ($node->taxonomy as $vocab) {
-        if (is_array($vocab)) {
-          foreach ($vocab as $term) {
-            $tids[$term] = $term;
-          }
-        }
+    $terms = array();
+    $info = field_info_fields();
+
+    foreach (field_info_instances('node', $node->type) as $name => $instance) {
+      if ($info[$name]['type'] == 'taxonomy_term_reference') {
+        $terms = array_merge($node->{$name}[$node->language], $node->original->{$name}[$node->language], $terms);
       }
     }
-    $filenames = array();
-    foreach ($tids as $tid) {
-      if (is_numeric($tid)) {
-        $term = taxonomy_get_term($tid);
-        $paths['term' . $tid] = taxonomy_term_path($term);
-      }
+
+    foreach ($terms as $term) {
+      $paths['term' . $term['tid']] = 'taxonomy/term/' . $term['tid'];
     }
   }
 
   // Get menu and flush related items in the menu.
-  if (variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS) !=0) {
+  if (module_exists('menu') && variable_get('expire_flush_menu_items', EXPIRE_FLUSH_MENU_ITEMS) != 0) {
     if (!isset($node->menu['menu_name'])) {
       menu_node_prepare($node);
     }
@@ -348,48 +290,10 @@ function expire_node(&$node) {
     $paths = array_merge($links, $paths);
   }
 
-  // Get CCK References and flush.
-  if (variable_get('expire_flush_cck_references', EXPIRE_FLUSH_CCK_REFERENCES) && module_exists('nodereference')) {
-    $nids = array();
-    $type = content_types($node->type);
-    if ($type) {
-      foreach ($type['fields'] as $field) {
-        // Add referenced nodes to nids. This will clean up nodereferrer fields
-        // when the referencing node is updated.
-        if ($field['type'] == 'nodereference') {
-          $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
-          foreach ($node_field as $delta => $item) {
-            if (is_numeric($item['nid'])) {
-              $paths['reference' . $item['nid']] = 'node/'. $item['nid'];
-            }
-          }
-
-          // Look for node referers without using nodereferrer
-          $info = content_database_info($field);
-          $table = $info['table'];
-          $column = $info['columns']['nid']['column'];
-          $results = db_query("SELECT n.nid
-            FROM {%s} nr
-            INNER JOIN {node} n USING (vid)
-            WHERE nr.%s = %d", $table, $column, $node->nid);
-          while ($nid = db_result($results)) {
-            if (is_numeric($nid)) {
-              $paths['referenceparent' . $nid] = 'node/'. $nid;
-            }
-          }
-        }
-      }
-    }
-
-    // Get CCK references pointing to this node and flush.
-    if (module_exists('nodereferrer')) {
-      $nids = nodereferrer_referrers($node->nid);
-      foreach ($nids as $nid) {
-        if (is_numeric($nid['nid'])) {
-          $paths['referrer' . $nid['nid']] = 'node/' . $nid['nid'];
-        }
-      }
-    }
+  // Get NODE References and flush.
+  if (variable_get('expire_flush_node_references', EXPIRE_FLUSH_NODE_REFERENCES) && module_exists('node_reference')) {
+    $node_references = expire_get_node_references($node);
+    $paths = array_merge($node_references, $paths);
   }
 
   // Flush array of paths
@@ -484,22 +388,6 @@ function expire_get_menu_structure($menu, $found, $needle, $first, &$found_globa
 }
 
 /**
- * Return taxonomy terms given a nid.
- *
- * Needed because of a weird bug with CCK & node_load()
- *  http://drupal.org/node/545922
- */
-function expire_taxonomy_node_get_tids($nid) {
-  $vid = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
-  $result = db_query(db_rewrite_sql("SELECT t.tid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name", 't', 'tid'), $vid);
-  $tids = array();
-  while ($term = db_result($result)) {
-    $tids[] = $term;
-  }
-  return $tids;
-}
-
-/**
  * Finds all possible paths/redirects/aliases given the root path.
  *
  * @param $paths
@@ -534,12 +422,12 @@ function expire_cache_derivative($paths, &$node = NULL) {
     $expire[] = substr($path_alias, strlen($base_path));
 
     // Path redirects
-    if (module_exists('path_redirect')) {
-      $path_redirects = expire_path_redirect_load(array('redirect' => $path));
-      if (isset($path_redirects)) {
-        foreach ($path_redirects as $path_redirect) {
-          if (!empty($path_redirect['redirect'])) {
-            $expire[] = $path_redirect['redirect'];
+    if (module_exists('redirect')) {
+      $redirects = redirect_load_multiple(array('redirect' => $path));
+      if (isset($redirects)) {
+        foreach ($redirects as $redirect) {
+          if (!empty($redirect['redirect'])) {
+            $expire[] = $redirect['redirect'];
           }
         }
       }
@@ -583,39 +471,6 @@ function expire_cache_derivative($paths, &$node = NULL) {
 }
 
 /**
- * Retrieve a specific URL redirect from the database.
- * http://drupal.org/node/451790
- *
- * @param $where
- *   Array containing 'redirect' => $path
- */
-function expire_path_redirect_load($where = array(), $args = array(), $sort = array()) {
-  $redirects = array();
-  if (is_numeric($where)) {
-    $where = array('rid' => $where);
-  }
-
-  foreach ($where as $key => $value) {
-    if (is_string($key)) {
-      $args[] = $value;
-      $where[$key] = $key .' = '. (is_numeric($value) ? '%d' : "'%s'");
-    }
-  }
-
-  if ($where && $args) {
-    $sql = "SELECT * FROM {path_redirect} WHERE ". implode(' AND ', $where);
-    if ($sort) {
-      $sql .= ' ORDER BY '. implode(' ,', $sort);
-    }
-    $result = db_query($sql, $args);
-    while ($redirect = db_fetch_array($result)) {
-      $redirects[] = $redirect;
-    }
-    return $redirects;
-  }
-}
-
-/**
  * Simple print_r to html function
  *
  * @param $data
@@ -677,33 +532,6 @@ function expire_get_base_urls(&$node) {
   return $base_urls;
 }
 
-/**
- * Get domains the node is currently published to
- *
- * @param $node
- *   node object
- * @return array
- *   array('$gid' => $gid)
- */
-function expire_get_domains(&$node) {
-  $domains = array();
-  if ($node->nid) {
-    $result = db_query("SELECT gid FROM {domain_access} WHERE nid = %d", $node->nid);
-    while ($row = db_fetch_array($result)) {
-      $gid = $row['gid'];
-      $domains[$gid] = $gid;
-    }
-  }
-  elseif ($node->mail && $node->name) {
-    $result = db_query("SELECT domain_id FROM {domain_editor} WHERE uid = %d", $node->uid);
-    while ($row = db_fetch_array($result)) {
-      $gid = $row['domain_id'];
-      $domains[$gid] = $gid;
-    }
-  }
-  return $domains;
-}
-
 function expire_normal_path_check($path) {
   $original_map = arg(NULL, $path);
   $parts = array_slice($original_map, 0, MENU_MAX_PARTS);
diff --git a/expire.node_reference.inc b/expire.node_reference.inc
new file mode 100644
index 0000000..3e0d6b4
--- /dev/null
+++ b/expire.node_reference.inc
@@ -0,0 +1,35 @@
+<?php
+
+function expire_get_node_references($node)  {
+  $nids = array();
+  $type = content_types($node->type);
+  if ($type) {
+    foreach ($type['fields'] as $field) {
+      // Add referenced nodes to nids. This will clean up nodereferrer fields
+      // when the referencing node is updated.
+      if ($field['type'] == 'nodereference') {
+        $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
+        foreach ($node_field as $delta => $item) {
+          if (is_numeric($item['nid'])) {
+            $paths['reference' . $item['nid']] = 'node/'. $item['nid'];
+          }
+        }
+
+        // Look for node referers without using nodereferrer
+        $info = content_database_info($field);
+        $table = $info['table'];
+        $column = $info['columns']['nid']['column'];
+        $results = db_query("SELECT n.nid
+          FROM {$table} nr
+          INNER JOIN {node} n USING (vid)
+          WHERE nr.$column = :nid", array(':nid' => $node->nid));
+        foreach ($results->fetchCol() as $nid) {
+          if (is_numeric($nid)) {
+            $paths['referenceparent' . $nid] = 'node/'. $nid;
+          }
+        }
+      }
+    }
+  }
+  return $paths;
+}
diff --git a/expire.votingapi.inc b/expire.votingapi.inc
new file mode 100644
index 0000000..bf9ba30
--- /dev/null
+++ b/expire.votingapi.inc
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * Implementation of hook_votingapi_insert().
+ *
+ * @param $votes
+ *  array of votes
+ */
+function expire_votingapi_insert($votes) {
+  _expire_votingapi($votes);
+}
+
+/**
+ * Implementation of hook_votingapi_delete().
+ *
+ * @param $votes
+ *  array of votes
+ */
+function expire_votingapi_delete($votes) {
+  _expire_votingapi($votes);
+}
+
+/**
+ * Common expiry logic for votingapi.
+ */
+function _expire_votingapi($votes) {
+  foreach ($votes as $vote) {
+    if ($vote['entity_type'] == 'comment') {
+      $nid = db_query("SELECT nid FROM {comments} WHERE cid = :cid", array(':cid' => $vote['entity_id']))->fetchField();
+      if (is_numeric($nid)) {
+        $node = node_load($nid);
+        if ($node) {
+          expire_node($node);
+        }
+      }
+    }
+    if ($vote['entity_type'] == 'node') {
+      $node = node_load($vote['entity_id']);
+      if ($node) {
+        expire_node($node);
+      }
+    }
+  }
+}
+
+
-- 
1.7.5.4


From ea774b58b0cb11d1d340bd5b6c8d8fefe9b98b25 Mon Sep 17 00:00:00 2001
From: Elliot Pahl <elliot@catalyst.net.nz>
Date: Thu, 1 Mar 2012 15:24:20 +1300
Subject: [PATCH 31/31] Temporary commit.

---
 expire.domain.inc         |   45 ++++++++++
 expire.module             |  204 +++++++++++++++++++++------------------------
 expire.node_reference.inc |   39 +++------
 3 files changed, 152 insertions(+), 136 deletions(-)

diff --git a/expire.domain.inc b/expire.domain.inc
index 7bc221f..f690131 100644
--- a/expire.domain.inc
+++ b/expire.domain.inc
@@ -27,3 +27,48 @@ function expire_get_domains(&$node) {
   return $domains;
 }
 
+/**
+ * Get all base url's where this node can appear.
+ *
+ * @param $node
+ *   node object
+ * @return array
+ *   array(0 => array($base_url . '/'))
+ */
+function expire_get_base_urls($node) {
+  global $base_url, $base_path;
+
+  // Get list of URL's if using domain access
+  $base_urls = array();
+  $domains = array();
+  // Get domains from node/user object
+  foreach ($node->domains as $key => $domain_id) {
+    if ($key != $domain_id) {
+      continue;
+    }
+    $domains[$domain_id] = $domain_id;
+  }
+  // Get domains from database
+  foreach (expire_get_domains($node) as $domain_id) {
+    $domains[$domain_id] = $domain_id;
+  }
+  // Get aliases and set base url
+  foreach ($domains as $domain_id) {
+    $domain = domain_lookup($domain_id);
+    if ($domain['valid'] == 1) {
+      if (isset($domain['path'])) {
+        $base_urls[$domain_id][] = $domain['path'];
+      }
+      if (is_array($domain['aliases'])) {
+        foreach ($domain['aliases'] as $alias) {
+          if ($alias['redirect'] != 1) {
+            $temp_domain = array('scheme' => $domain['scheme'], 'subdomain' => $alias['pattern']);
+            $base_urls[$domain_id][] = domain_get_path($temp_domain);
+          }
+        }
+      }
+    }
+  }
+  return $base_urls;
+}
+
diff --git a/expire.module b/expire.module
index 476910c..3026c3b 100644
--- a/expire.module
+++ b/expire.module
@@ -43,15 +43,11 @@ function expire_menu() {
  * Acts on new comments.
  */
 function expire_comment_insert($comment) {
-  // Return if no node id is attached to the comment.
-  if (empty($comment->nid)) {
-    return;
-  }
-
-  // Expire the relevant node page from the static page cache to prevent serving stale content.
-  $node = node_load($comment->nid);
-  if ($node) {
-    expire_node($node);
+  if (!empty($comment->nid)) {
+    $node = node_load($comment->nid);
+    if ($node) {
+      expire_node($node);
+    }
   }
 }
 
@@ -61,12 +57,11 @@ function expire_comment_insert($comment) {
  * Acts on comments updates.
  */
 function expire_comment_update($comment) {
-  if (empty($comment->nid)) {
-    return;
-  }
-  $node = node_load($comment->nid);
-  if ($node) {
-    expire_node($node);
+  if (!empty($comment->nid)) {
+    $node = node_load($comment->nid);
+    if ($node) {
+      expire_node($node);
+    }
   }
 }
 
@@ -76,12 +71,11 @@ function expire_comment_update($comment) {
  * Acts when publishing comments.
  */
 function expire_comment_publish($comment) {
-  if (empty($comment->nid)) {
-    return;
-  }
-  $node = node_load($comment->nid);
-  if ($node) {
-    expire_node($node);
+  if (!empty($comment->nid)) {
+    $node = node_load($comment->nid);
+    if ($node) {
+      expire_node($node);
+    }
   }
 }
 
@@ -91,12 +85,11 @@ function expire_comment_publish($comment) {
  * Acts when unpublishing comments.
  */
 function expire_comment_unpublish($comment) {
-  if (empty($comment->nid)) {
-    return;
-  }
-  $node = node_load($comment->nid);
-  if ($node) {
-    expire_node($node);
+  if (!empty($comment->nid)) {
+    $node = node_load($comment->nid);
+    if ($node) {
+      expire_node($node);
+    }
   }
 }
 
@@ -107,12 +100,11 @@ function expire_comment_unpublish($comment) {
  * Acts when deleting comments.
  */
 function expire_comment_delete($comment) {
-  if (empty($comment->nid)) {
-    return;
-  }
-  $node = node_load($comment->nid);
-  if ($node) {
-    expire_node($node);
+  if (!empty($comment->nid)) {
+    $node = node_load($comment->nid);
+    if ($node) {
+      expire_node($node);
+    }
   }
 }
 
@@ -123,10 +115,7 @@ function expire_comment_delete($comment) {
  * Acts on new nodes.
  */
 function expire_node_insert($node) {
-  if (empty($node->nid)) {
-    return;
-  }
-  else {
+  if (!empty($node->nid)) {
     expire_node($node);
   }
 }
@@ -137,10 +126,7 @@ function expire_node_insert($node) {
  * Acts on node updates.
  */
 function expire_node_update($node) {
-  if (empty($node->nid)) {
-    return;
-  }
-  else {
+  if (!empty($node->nid)) {
     expire_node($node);
   }
 }
@@ -151,10 +137,7 @@ function expire_node_update($node) {
  * Acts on deletion of nodes.
  */
 function expire_node_delete($node) {
-  if (empty($node->nid)) {
-    return;
-  }
-  else {
+  if (!empty($node->nid)) {
     expire_node($node);
   }
 }
@@ -165,10 +148,7 @@ function expire_node_delete($node) {
  * Acts on deletion of revisions.
  */
 function expire_node_revision_delete($node) {
-  if (empty($node->nid)) {
-    return;
-  }
-  else {
+  if (!empty($node->nid)) {
     expire_node($node);
   }
 }
@@ -262,7 +242,14 @@ function expire_node($node) {
 
     foreach (field_info_instances('node', $node->type) as $name => $instance) {
       if ($info[$name]['type'] == 'taxonomy_term_reference') {
-        $terms = array_merge($node->{$name}[$node->language], $node->original->{$name}[$node->language], $terms);
+        $new_terms = field_get_items('node', $node, $name);
+        if (is_array($new_terms)) {
+          $terms = array_merge($new_terms, $terms);
+        }
+        $old_terms = isset($node->original) && !empty($node->original) ? field_get_items('node', $node->original, $name) : array();
+        if (is_array($old_terms)) {
+          $terms = array_merge($old_terms, $terms);
+        }
       }
     }
 
@@ -290,8 +277,10 @@ function expire_node($node) {
     $paths = array_merge($links, $paths);
   }
 
-  // Get NODE References and flush.
-  if (variable_get('expire_flush_node_references', EXPIRE_FLUSH_NODE_REFERENCES) && module_exists('node_reference')) {
+  // Get Node References and flush.
+  if (variable_get('expire_flush_node_references', EXPIRE_FLUSH_NODE_REFERENCES)
+   && module_exists('node_reference')
+   && module_load_include('inc', 'expire', 'expire.node_reference') != FALSE) {
     $node_references = expire_get_node_references($node);
     $paths = array_merge($node_references, $paths);
   }
@@ -423,11 +412,11 @@ function expire_cache_derivative($paths, &$node = NULL) {
 
     // Path redirects
     if (module_exists('redirect')) {
-      $redirects = redirect_load_multiple(array('redirect' => $path));
-      if (isset($redirects)) {
+      $redirects = redirect_load_multiple(array(), array('redirect' => $path));
+      if (isset($redirects) && !empty($redirects)) {
         foreach ($redirects as $redirect) {
-          if (!empty($redirect['redirect'])) {
-            $expire[] = $redirect['redirect'];
+          if (!empty($redirect->source)) {
+            $expire[] = $redirect->source;
           }
         }
       }
@@ -446,11 +435,14 @@ function expire_cache_derivative($paths, &$node = NULL) {
   $urls = array();
   global $base_url;
   if (variable_get('expire_include_base_url', EXPIRE_INCLUDE_BASE_URL)) {
-    foreach (expire_get_base_urls($node) as $domain_id) {
-      foreach ($domain_id as $base) {
-        foreach ($expire as $path) {
-          $urls[] = $base . $path;
-        }
+    $base_urls[] = $base_url;
+    if (module_exists('domain')
+     && module_load_include('inc', 'expire', 'expire.domain') != FALSE) {
+      $base_urls = array_merge($base_urls, expire_get_base_urls($node));
+    }
+    foreach ($expire as $path) {
+      foreach ($base_urls as $base) {
+        $urls[] = $base . $path;
       }
     }
   }
@@ -482,61 +474,55 @@ function expire_print_r($data) {
   return str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(htmlentities(print_r($data, TRUE))));
 }
 
+function expire_normal_path_check($path) {
+  $original_map = arg(NULL, $path);
+  $parts = array_slice($original_map, 0, MENU_MAX_PARTS);
+  list($ancestors, $placeholders) = menu_get_ancestors($parts);
+
+  $router_item = db_query_range('SELECT path FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
+  return $router_item;
+}
+
 /**
- * Get all base url's where this node can appear. Domain access support.
+ * Implementation of hook_votingapi_insert().
  *
- * @param $node
- *   node object
- * @return array
- *   array(0 => array($base_url . '/'))
+ * @param $votes
+ *  array of votes
+ */
+function expire_votingapi_insert($votes) {
+  _expire_votingapi($votes);
+}
+
+/**
+ * Implementation of hook_votingapi_delete().
+ *
+ * @param $votes
+ *  array of votes
  */
-function expire_get_base_urls(&$node) {
-  global $base_url, $base_path;
-
-  // Get list of URL's if using domain access
-  $base_urls = array();
-  $domains = array();
-  if (module_exists('domain') && isset($node->domains)) {
-    // Get domains from node/user object
-    foreach ($node->domains as $key => $domain_id) {
-      if ($key != $domain_id) {
-        continue;
+function expire_votingapi_delete($votes) {
+  _expire_votingapi($votes);
+}
+
+/**
+ * Common expiry logic for votingapi.
+ */
+function _expire_votingapi($votes) {
+  foreach ($votes as $vote) {
+    if ($vote['entity_type'] == 'comment') {
+      $nid = db_query("SELECT nid FROM {comments} WHERE cid = :cid", array(':cid' => $vote['entity_id']))->fetchField();
+      if (is_numeric($nid)) {
+        $node = node_load($nid);
+        if ($node) {
+          expire_node($node);
+        }
       }
-      $domains[$domain_id] = $domain_id;
     }
-    // Get domains from database
-    foreach (expire_get_domains($node) as $domain_id) {
-      $domains[$domain_id] = $domain_id;
-    }
-    // Get aliases and set base url
-    foreach ($domains as $domain_id) {
-      $domain = domain_lookup($domain_id);
-      if ($domain['valid'] == 1) {
-        if (isset($domain['path'])) {
-          $base_urls[$domain_id][] = $domain['path'];
-        }
-        if (is_array($domain['aliases'])) {
-          foreach ($domain['aliases'] as $alias) {
-            if ($alias['redirect'] != 1) {
-              $temp_domain = array('scheme' => $domain['scheme'], 'subdomain' => $alias['pattern']);
-              $base_urls[$domain_id][] = domain_get_path($temp_domain);
-            }
-          }
-        }
+    if ($vote['entity_type'] == 'node') {
+      $node = node_load($vote['entity_id']);
+      if ($node) {
+        expire_node($node);
       }
     }
   }
-  else {
-    $base_urls[0][] = $base_url . '/';
-  }
-  return $base_urls;
 }
 
-function expire_normal_path_check($path) {
-  $original_map = arg(NULL, $path);
-  $parts = array_slice($original_map, 0, MENU_MAX_PARTS);
-  list($ancestors, $placeholders) = menu_get_ancestors($parts);
-
-  $router_item = db_query_range('SELECT path FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
-  return $router_item;
-}
diff --git a/expire.node_reference.inc b/expire.node_reference.inc
index 3e0d6b4..394d32a 100644
--- a/expire.node_reference.inc
+++ b/expire.node_reference.inc
@@ -1,34 +1,19 @@
 <?php
 
 function expire_get_node_references($node)  {
-  $nids = array();
-  $type = content_types($node->type);
-  if ($type) {
-    foreach ($type['fields'] as $field) {
-      // Add referenced nodes to nids. This will clean up nodereferrer fields
-      // when the referencing node is updated.
-      if ($field['type'] == 'nodereference') {
-        $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
-        foreach ($node_field as $delta => $item) {
-          if (is_numeric($item['nid'])) {
-            $paths['reference' . $item['nid']] = 'node/'. $item['nid'];
-          }
-        }
-
-        // Look for node referers without using nodereferrer
-        $info = content_database_info($field);
-        $table = $info['table'];
-        $column = $info['columns']['nid']['column'];
-        $results = db_query("SELECT n.nid
-          FROM {$table} nr
-          INNER JOIN {node} n USING (vid)
-          WHERE nr.$column = :nid", array(':nid' => $node->nid));
-        foreach ($results->fetchCol() as $nid) {
-          if (is_numeric($nid)) {
-            $paths['referenceparent' . $nid] = 'node/'. $nid;
-          }
-        }
+  $paths = array();
+  $fields= field_info_instances('node', $node->type);
+  $field_types = field_info_fields();
+  foreach ($fields as $field) {
+    // Add referenced node paths and expire referenced nodes
+    // when the referencing node is updated.
+    if ($field_types[$field['field_name']]['type'] == 'node_reference') {
+      $node_field = isset($node->$field['field_name']) && !empty($node->$field['field_name']) ? $node->$field['field_name'] : array();
+      foreach($node_field[LANGUAGE_NONE] as $reference) {
+        $paths['reference' . $reference['nid']] = 'node/'. $reference['nid'];
       }
+
+      $types = entity_load_multiple_by_name('node');
     }
   }
   return $paths;
-- 
1.7.5.4

