--- comment_cck/comment_cck.module	2009-05-08 22:32:08.000000000 +0200
+++ comment_cck.module	2009-07-28 11:05:40.000000000 +0200
@@ -9,10 +9,30 @@ function comment_cck_perm() {
 }
 
 /**
- * Implementation of hook_form_alter().
+ * Implementation of hook_nodeapi().
  */
-function comment_cck_form_alter(&$form, &$form_state, $form_id) {
-  if ($form_id == 'comment_form' && user_access('change cck fields through comments')) {
+function comment_cck_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
+  switch ($op) {
+    case 'delete':
+      cache_clear_all($node->nid . ':', 'cache_comment_cck', TRUE);
+      break;
+
+    case 'delete revision':
+      // @TODO check revision delete situation
+      cache_clear_all($node->nid . ':', 'cache_comment_cck', TRUE);
+      break;
+
+    case 'update':
+      cache_clear_all($node->nid . ':', 'cache_comment_cck', TRUE);    
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ */
+function comment_cck_form_comment_form_alter(&$form, &$form_state) {
+  if (user_access('change cck fields through comments')) {
     $node = node_load($form['nid']['#value']);
     // Check if any fields in this node type are comment_cck enabled.
     if ($fields = variable_get('comment_cck_fields_'. $node->type, array())) {
@@ -53,10 +73,15 @@ function comment_cck_form_alter(&$form, 
       // Set the comment_cck fields to output in the correct format.
       $form['comment_filter']['comment_cck']['#tree'] = TRUE;
     }
-    return;
   }
-  if ($form_id == 'content_field_edit_form' && !$form_state['change_basic']) {
-    // Enable comment_ck to alter this field within this content type.
+}
+
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ */
+function comment_cck_form_content_field_edit_form_alter(&$form, &$form_state) {
+  if (!$form_state['change_basic']) {
+    // Enable comment_cck to alter this field within this content type.
     $form['widget']['comment_cck_enabled'] = array(
       '#type' => 'checkbox',
       '#title' => t('Allow comments to alter this field'),
@@ -67,6 +92,9 @@ function comment_cck_form_alter(&$form, 
   }
 }
 
+/**
+ * Submit handler for form content_field_edit_form.
+ */
 function _comment_cck_field_edit_form_submit($form, &$form_state) {
   $type_name = $form_state['values']['type_name'];
   $field_name = $form_state['values']['field_name'];
@@ -109,6 +137,7 @@ function comment_cck_comment(&$comment, 
         $node->revision = 0;
         $node->vid = db_result(db_query('SELECT vid FROM {comment_cck_revisions} WHERE cid = %d', $comment['cid']));
         // Save the node with the updated field data.
+        // @TODO: wrong if we edit non-last comments!
         node_save($node);
       }
       break;
@@ -134,61 +163,83 @@ function comment_cck_comment(&$comment, 
       break;
 
     case 'view':
-      $node = node_load($comment->nid);
-      if ($fields = variable_get('comment_cck_fields_'. $node->type, array())) {
-        // We'll prepend the updated fields to the comment, not append.
-        $comment_text = $comment->comment;
-        // Get the comment_cck revisions associated with this comment.
-        $comment_revision = db_fetch_object(db_query('SELECT * FROM {comment_cck_revisions} WHERE cid = %d', $comment->cid));
-        if (!is_object($comment_revision)) {
-          // @TODO: Get this to work on preview. For now, degrade gracefully.
-          break;
-        }
-        if ($comment->op == t('Preview')) {
-          // @TODO: Is this a better way to check for preview? Get working!
-          break;
-        }
-        $current_node = _comment_cck_build_node((int) $comment->nid, $comment_revision->vid);
-        $previous_node = _comment_cck_build_node((int) $comment->nid, $comment_revision->previous_vid);
-        $cck_fields = content_types($node->type);
-
-        $result = array();
-        foreach ($fields as $field) {
-          // Check if the field was changed with this comment.
-          if ($current_node->$field != $previous_node->$field) {
-            // Render the current field.
-            $current_field = _comment_cck_render_field($field, $cck_fields, $current_node);
-            // Render the previous field.
-            $previous_field = _comment_cck_render_field($field, $cck_fields, $previous_node);
-            // Iterate over the current field values.
-            foreach ($current_field as $delta => $item) {
-              // Make sure they're different.
-              if ($item != $previous_field[$delta]) {
-                // They're different. Add them.
-                _comment_cck_rendering(TRUE);
-                $result[] = array($cck_fields['fields'][$field]['widget']['label'] .':&nbsp', drupal_render($previous_field[$delta]), "&raquo;", drupal_render($item));
-                _comment_cck_rendering(FALSE);
-              }
-            }
-          }
-        }
-        // If this comment changed any fields, update the comment output.
-        if (!empty($result)) {
-          drupal_add_css(drupal_get_path('module', 'comment_cck') .'/comment_cck.css');
-          // @TODO: Create template and preprocessing function.
-          $comment->comment = theme('table', array(), $result, array('class' => 'comment_cck')) . $comment_text;
-        }
+      // We'll prepend the updated fields to the comment, not append.
+      $comment_text = $comment->comment;
+      // Caching makes servers happy
+      $cid = $comment->nid.':'.$comment->cid;
+      $cache = cache_get($cid, 'cache_comment_cck');
+      if($cache) {
+        $result = $cache->data;
+      }
+      else {
+        // build missing cache item
+        $result = _comment_cck_build_diff($comment);
+        cache_set($cid, $result, 'cache_comment_cck');
+      }
+      // If this comment changed any fields, update the comment output.
+      if ($result) { // !empty && !NULL
+        drupal_add_css(drupal_get_path('module', 'comment_cck') .'/comment_cck.css');
+        // @TODO: Create template and preprocessing function.
+        $comment->comment = theme('table', array(), $result, array('class' => 'comment_cck')) . $comment_text;
       }
       break;
   }
   return $comment;
 }
 
+function _comment_cck_build_diff($comment) {
+  $node = node_load($comment->nid);
+  $fields = variable_get('comment_cck_fields_'. $node->type, array());
+  if ($fields) {
+    // We'll prepend the updated fields to the comment, not append.
+    $comment_text = $comment->comment;
+    // Get the comment_cck revisions associated with this comment.
+    $comment_revision = db_fetch_object(db_query('SELECT * FROM {comment_cck_revisions} WHERE cid = %d', $comment->cid));
+    if (!is_object($comment_revision)) {
+      // @TODO: Get this to work on preview. For now, degrade gracefully.
+      // triggered by save too
+      return NULL;
+    }
+    if ($comment->op == t('Preview')) {
+      // @TODO: Is this a better way to check for preview? Get working!
+      return NULL;
+    }
+    $current_node = _comment_cck_build_node((int) $comment->nid, $comment_revision->vid);
+    $previous_node = _comment_cck_build_node((int) $comment->nid, $comment_revision->previous_vid);
+    $cck_fields = content_types($node->type);
+
+    // diff output
+    $result = array();
+    foreach ($fields as $field) {
+      // Check if the field was changed with this comment.
+      if ($current_node->$field != $previous_node->$field) {
+        // Render the current field.
+        $current_field = _comment_cck_render_field($field, $cck_fields, $current_node);
+        // Render the previous field.
+        $previous_field = _comment_cck_render_field($field, $cck_fields, $previous_node);
+        // Iterate over the current field values.
+        foreach ($current_field as $delta => $item) {
+          // Make sure they're different.
+          if ($item != $previous_field[$delta]) {
+            // They're different. Add them.
+            // @TODO: theme item
+            _comment_cck_rendering(TRUE);
+            $result[] = array($cck_fields['fields'][$field]['widget']['label'] .':&nbsp', drupal_render($previous_field[$delta]), "&raquo;", drupal_render($item));
+            _comment_cck_rendering(FALSE);
+          }
+        }
+      }
+    }
+    return $result;
+  }
+  return NULL;
+}
+
 /**
  * Build a node and it's content.
  */
-function _comment_cck_build_node($criteria, $revision) {
-  $node = node_load($criteria, $revision);
+function _comment_cck_build_node($nid, $vid) {
+  $node = node_load($nid, $vid);
   $node = node_build_content($node);
   return $node;
 }
