--- modules/node/node.module	2010-09-01 14:10:33.000000000 -0700
+++ modules/node/node_patched.module	2010-09-01 14:10:56.000000000 -0700
@@ -1,5 +1,5 @@
 <?php
-// $Id: node.module,v 1.947.2.19 2009/09/23 09:09:30 goba Exp $
+// $Id: node.module,v 1.947.2.26 2010/08/06 11:41:13 goba Exp $
 
 /**
  * @file
@@ -7,6 +7,12 @@
  * programmatically submit nodes using the usual form API pattern.
  */
 
+/**
+ * Nodes changed before this time are always marked as read.
+ *
+ * Nodes changed after this time may be marked new, updated, or read, depending
+ * on their state for the current user. Defaults to 30 days ago.
+ */
 define('NODE_NEW_LIMIT', time() - 30 * 24 * 60 * 60);
 
 define('NODE_BUILD_NORMAL', 0);
@@ -695,20 +701,30 @@ function node_invoke_nodeapi(&$node, $op
  *   A fully-populated node object.
  */
 function node_load($param = array(), $revision = NULL, $reset = NULL) {
+  global $user;
   static $nodes = array();
 
   if ($reset) {
     $nodes = array();
   }
 
-  $cachable = ($revision == NULL);
+  $cache_id = 0;
   $arguments = array();
   if (is_numeric($param)) {
-    if ($cachable) {
-      // Is the node statically cached?
+    if (module_exists('advcache')) {
+      $cache_id = ($revision == NULL) ? "node/{$param}" : 0;
+    }
+    if ($cache_id !== 0) {
       if (isset($nodes[$param])) {
         return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];
       }
+		 if ($user->uid != 1) {
+        $cache = cache_get($cache_id, 'cache_node');
+        if ($cache) {
+          $nodes[$param] = is_object($cache->data) ? drupal_clone($cache->data) : $cache->data;
+          return $nodes[$param];
+        }
+      }
     }
     $cond = 'n.nid = %d';
     $arguments[] = $param;
@@ -763,8 +779,13 @@ function node_load($param = array(), $re
         $node->$key = $value;
       }
     }
-    if ($cachable) {
+    if ($cache_id !== 0) {
       $nodes[$node->nid] = is_object($node) ? drupal_clone($node) : $node;
+			if ($user->uid != 1) {
+        if (!in_array($node->type, variable_get('advcache_node_exclude_types', array('poll')))) {
+          cache_set($cache_id, $nodes[$node->nid], 'cache_node');
+        }
+      }
     }
   }
 
@@ -832,7 +853,7 @@ function node_submit($node) {
     }
     else {
       $node->teaser = '';
-      $node->format = 0;
+			$node->format = 0;
     }
   }
 
@@ -859,13 +880,10 @@ function node_save(&$node) {
   node_invoke_nodeapi($node, 'presave');
   global $user;
 
-  $node->is_new = FALSE;
-
-  // Apply filters to some default node fields:
-  if (empty($node->nid)) {
-    // Insert a new node.
-    $node->is_new = TRUE;
+  // Insert a new node.
+  $node->is_new = empty($node->nid);
 
+  if ($node->is_new || !empty($node->revision)) {
     // When inserting a node, $node->log must be set because
     // {node_revisions}.log does not (and cannot) have a default
     // value.  If the user does not have permission to create
@@ -874,35 +892,35 @@ function node_save(&$node) {
     if (!isset($node->log)) {
       $node->log = '';
     }
+  }
+  elseif (empty($node->log)) {
+    // When updating a node, however, avoid clobbering an existing
+    // log entry with an empty one.
+    unset($node->log);
+  }
 
-    // For the same reasons, make sure we have $node->teaser and
-    // $node->body.  We should consider making these fields nullable
-    // in a future version since node types are not required to use them.
-    if (!isset($node->teaser)) {
-      $node->teaser = '';
-    }
-    if (!isset($node->body)) {
-      $node->body = '';
-    }
+  // For the same reasons, make sure we have $node->teaser and
+  // $node->body set.
+  if (!isset($node->teaser)) {
+    $node->teaser = '';
   }
-  elseif (!empty($node->revision)) {
-    $node->old_vid = $node->vid;
+  if (!isset($node->body)) {
+    $node->body = '';
   }
-  else {
-    // When updating a node, avoid clobberring an existing log entry with an empty one.
-    if (empty($node->log)) {
-      unset($node->log);
-    }
+
+  // Save the old revision if needed.
+  if (!$node->is_new && !empty($node->revision) && $node->vid) {
+    $node->old_vid = $node->vid;
   }
 
-  // Set some required fields:
+  $time = time();
   if (empty($node->created)) {
-    $node->created = time();
+    $node->created = $time;
   }
   // The changed timestamp is always updated for bookkeeping purposes (revisions, searching, ...)
-  $node->changed = time();
+  $node->changed = $time;
 
-  $node->timestamp = time();
+  $node->timestamp = $time;
   $node->format = isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT;
 
   // Generate the node table query and the node_revisions table query.
@@ -958,7 +976,9 @@ function _node_save_revision(&$node, $ui
  */
 function node_delete($nid) {
 
-  $node = node_load($nid);
+  // Clear the cache before the load, so if multiple nodes are deleted, the
+  // memory will not fill up with nodes (possibly) already removed.
+  $node = node_load($nid, NULL, TRUE);
 
   if (node_access('delete', $node)) {
     db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
@@ -1227,7 +1247,10 @@ function node_search($op = 'search', $ke
       }
       if ($weight = (int)variable_get('node_rank_recent', 5)) {
         // Exponential decay with half-life of 6 months, starting at last indexed node
-        $ranking[] = '%d * POW(2, (GREATEST(MAX(n.created), MAX(n.changed), MAX(c.last_comment_timestamp)) - %d) * 6.43e-8)';
+        // c.last_comment_timestamp may be NULL. Since both MAX(anynumber, NULL) and
+        // GREATEST(anynumber, NULL) return NULL, we OR MAX(c.last_comment_timestamp) with 1
+        // to prevent it from being NULL.
+        $ranking[] = '%d * POW(2, (GREATEST(MAX(n.created), MAX(n.changed), MAX(c.last_comment_timestamp) || 1) - %d) * 6.43e-8)';
         $arguments2[] = $weight;
         $arguments2[] = (int)variable_get('node_cron_last', 0);
         $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
@@ -1280,9 +1303,13 @@ function node_search($op = 'search', $ke
         $node->body = drupal_render($node->content);
 
         // Fetch comments for snippet.
-        $node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
+        if (module_exists('comment')) {
+          $node->body .= comment_nodeapi($node, 'update index');
+        }
         // Fetch terms for snippet.
-        $node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index');
+        if (module_exists('taxonomy')) {
+          $node->body .= taxonomy_nodeapi($node, 'update index');
+        }
 
         $extra = node_invoke_nodeapi($node, 'search result');
         $results[] = array(
@@ -1678,8 +1705,8 @@ function node_feed($nids = FALSE, $chann
 
       // Allow modules to change $node->content before the node is rendered.
       node_invoke_nodeapi($item, 'view', $teaser, FALSE);
-
-      // Set the proper node property, then unset unused $node property so that a
+			
+			// Set the proper node property, then unset unused $node property so that a
       // bad theme can not open a security hole.
       $content = drupal_render($item->content);
       if ($teaser) {
@@ -1692,7 +1719,7 @@ function node_feed($nids = FALSE, $chann
       }
     
       // Allow modules to modify the fully-built node.
-      node_invoke_nodeapi($item, 'alter', $teaser, FALSE);
+      node_invoke_nodeapi($item, 'alter', $teaser, FALSE);			
     }
 
     // Allow modules to add additional item fields and/or modify $item
@@ -1780,7 +1807,7 @@ function node_page_default() {
 /**
  * Menu callback; view a single node.
  */
-function node_page_view($node, $cid = NULL) {
+function node_page_view($node, $cid = 0) {
   drupal_set_title(check_plain($node->title));
   return node_show($node, $cid);
 }
@@ -2178,13 +2205,13 @@ function node_db_rewrite_sql($query, $pr
 }
 
 /**
- * This function will call module invoke to get a list of grants and then
- * write them to the database. It is called at node save, and should be
- * called by modules whenever something other than a node_save causes
- * the permissions on a node to change.
+ * Gets the list of node access grants and writes them to the database.
  *
- * This function is the only function that should write to the node_access
- * table.
+ * This function is called when a node is saved, and can also be called by
+ * modules if something other than a node save causes node access permissions
+ * to change. It collects all node access grants for the node from
+ * hook_node_access_records() implementations and saves the collected
+ * grants to the database.
  *
  * @param $node
  *   The $node to acquire grants for.
@@ -2208,12 +2235,12 @@ function node_access_acquire_grants($nod
 }
 
 /**
- * This function will write a list of grants to the database, deleting
- * any pre-existing grants. If a realm is provided, it will only
- * delete grants from that realm, but it will always delete a grant
- * from the 'all' realm. Modules which utilize node_access can
- * use this function when doing mass updates due to widespread permission
- * changes.
+ * Writes a list of grants to the database, deleting any previously saved ones.
+ *
+ * If a realm is provided, it will only delete grants from that realm, but it
+ * will always delete a grant from the 'all' realm. Modules that utilize
+ * node_access can use this function when doing mass updates due to widespread
+ * permission changes.
  *
  * @param $node
  *   The $node being written to. All that is necessary is that it contain a nid.
@@ -2307,7 +2334,7 @@ function node_access_rebuild($batch_mode
   db_query("DELETE FROM {node_access}");
   // Only recalculate if the site is using a node_access module.
   if (count(module_implements('node_grants'))) {
-    if (FALSE && $batch_mode) {
+    if ($batch_mode) {
       $batch = array(
         'title' => t('Rebuilding content access permissions'),
         'operations' => array(
@@ -2371,7 +2398,7 @@ function _node_access_rebuild_batch_oper
       node_access_acquire_grants($loaded_node);
     }
     $context['sandbox']['progress']++;
-    $context['sandbox']['current_node'] = $loaded_node->nid;
+    $context['sandbox']['current_node'] = $row['nid'];
   }
 
   // Multistep processing : report progress.
