? comment_cck-big.patch
Index: comment_cck.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/comment_cck/comment_cck.install,v
retrieving revision 1.2
diff -u -p -r1.2 comment_cck.install
--- comment_cck.install	14 Jul 2008 20:30:44 -0000	1.2
+++ comment_cck.install	1 Apr 2009 01:12:56 -0000
@@ -14,6 +14,11 @@ function comment_cck_install() {
 function comment_cck_uninstall() {
   drupal_uninstall_schema('comment_cck');
   variable_del('comment_cck_block_author_fields');
+  variable_del('comment_cck_fields_');
+  foreach (node_get_types('names') as $type_name) {
+    variable_del('comment_cck_node_'. $type_name);
+    variable_del('comment_cck_fields_'. $type_name);
+  }
 }
 
 /**
@@ -26,21 +31,21 @@ function comment_cck_schema() {
     'description' => t('This table keeps track of which comments are responsible for which node revisions.'),
     'fields' => array(
       'cid' => array(
-        'description' => t('The cid of the comment that corresponds to the version specified by vid.'),
+        'description' => t('The cid of the comment that corresponds to the revision specified by vid.'),
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
       ),
       'vid' => array(
-        'description' => t('The vid of the version that corresponds to the comment specified by cid.'),
+        'description' => t('The vid of the revision that corresponds to the comment specified by cid.'),
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
       ),
      'previous_vid' => array(
-        'description' => t('The vid of the version that corresponds to the comment specified by cid.'),
+        'description' => t('The vid of the revision that corresponds to the comment specified by cid.'),
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
@@ -57,8 +62,7 @@ function comment_cck_schema() {
 }
 
 /**
- * Update function: change the primary key from vid to cid, since we always
- * select by cid.
+ * Change the primary key from vid to cid, since we always select by cid.
  */
 function comment_cck_update_6000() {
   $ret = array();
@@ -69,10 +73,24 @@ function comment_cck_update_6000() {
 }
 
 /**
- * Update function: the nid field is completely unnecessary and redundant.
+ * The nid field is unnecessary.
  */
 function comment_cck_update_6001() {
   $ret = array();
   db_drop_field($ret, 'comment_cck_revisions', 'nid');
   return $ret;
-}
\ No newline at end of file
+}
+
+/**
+ * Cleanup the database of old variables.
+ */
+function comment_cck_update_6002() {
+  $ret = array();
+  // Remove old per-node-type variables.
+  foreach (node_get_types('names') as $type_name) {
+    variable_del('comment_cck_node_'. $type_name);
+  }
+  // Remove phantom variable.
+  variable_del('comment_cck_fields_');
+  return $ret;
+}
Index: comment_cck.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/comment_cck/comment_cck.module,v
retrieving revision 1.12
diff -u -p -r1.12 comment_cck.module
--- comment_cck.module	8 Sep 2008 21:35:39 -0000	1.12
+++ comment_cck.module	1 Apr 2009 01:12:56 -0000
@@ -14,172 +14,169 @@ function comment_cck_perm() {
 function comment_cck_form_alter(&$form, &$form_state, $form_id) {
   if ($form_id == 'comment_form' && user_access('change cck fields through comments')) {
     $node = node_load($form['nid']['#value']);
-    // Check if fields for this type are enabled
-    if (variable_get('comment_cck_node_'. $node->type, FALSE) == TRUE) {
-      // If so, get the fields
-      $fields = variable_get('comment_cck_fields_'. $node->type, array());
-      // Get the full form as well
+    // Check if any fields in this node type are comment_cck enabled.
+    if ($fields = variable_get('comment_cck_fields_'. $node->type, array())) {
+      // Include the functions to load the full node form.
       module_load_include('inc', 'content', 'includes/content.node_form');
-      $form['type'] = array(
+      // This is a dummy node form, in which to gather the original fields.
+      $node_form['type'] = array(
         '#type' => 'value',
         '#value' => $node->type,
       );
-      $form['#node'] = $node;
-      $copy = $form;
-      $content_form = content_form($copy, $form_state);
-      // This will hold the form with only the fields we need
-      $final_form = array();
-      $final_form['type']['#value'] = $node->type;
+      $node_form['#node'] = $node;
+      // This form will contain only the comment_cck enabled fields.
+      $final_form = $node_form;
+      $node_form = content_form($node_form, $form_state);
 
       foreach ($fields as $field) {
-        if (isset($content_form[$field])) {
-          // Only add fields that are comment_cck enabled
-          $final_form[$field] = $content_form[$field];
-          $form['#field_info'][$field] = $content_form['#field_info'][$field];
+        if (isset($node_form[$field])) {
+          // Only add fields that are comment_cck enabled.
+          $final_form[$field] = $node_form[$field];
+          $form['#field_info'][$field] = $node_form['#field_info'][$field];
         }
       }
-      // if we've got the fieldgroup module installed
+
+      // If the fieldgroup module is installed, put fields into groups.
       if (function_exists('fieldgroup_form_alter')) {
-        // call fieldgroup_form_alter to add all the groupings.
-        $arg = $node->type . '_node_form';
-        fieldgroup_form_alter($final_form, array(), $arg);
+        // Call fieldgroup_form_alter() to group the fields.
+        $final_form_id = $node->type .'_node_form';
+        fieldgroup_form_alter($final_form, array(), $final_form_id);
       }
-      // We don't need to know this, leaving it in just prints it in the form, so remove it.
+      // Leaving the node type in the form causes it to output, so remove.
       unset($final_form['type']);
-      // Add it to comment_filter so it maintains the correct postion in the form
+
+      // Add the comment_cck fields to comment_filter in order to postion it
+      // within the comment form.
       $form['comment_filter']['comment_cck'] = $final_form;
-      // Make it sink
+      // Set the position of the comment_cck fields within the comment form.
       $form['comment_filter']['comment_cck']['#weight'] = 50;
-      // It's tons easier like this
+      // Set the comment_cck fields to output in the correct format.
       $form['comment_filter']['comment_cck']['#tree'] = TRUE;
     }
     return;
   }
-  if ($form_id == '_content_admin_field') {
-    $form['field']['comment_cck_node'] = array(
-      '#type' => 'value',
-      '#value' => $form['type_name']['#value'],
-      );
-    $form['field']['comment_cck_field'] = array(
-      '#type' => 'value',
-      '#value' => $form['field_name']['#value'],
-      );
-    $form['field']['comment_cck_node_'. $form['field_name']['#value']] = array(
+  if ($form_id == 'content_field_edit_form' && !$form_state['change_basic']) {
+    // Enable comment_ck to alter this field within this content type.
+    $form['widget']['comment_cck_enabled'] = array(
       '#type' => 'checkbox',
       '#title' => t('Allow comments to alter this field'),
       '#description' => t('If checked, comments can alter this CCK field.'),
       '#default_value' => in_array($form['field_name']['#value'], variable_get('comment_cck_fields_'. $form['type_name']['#value'], array())),
     );
-    $form['#submit'][] = '_comment_cck_submit';
+    $form['#submit'][] = '_comment_cck_field_edit_form_submit';
   }
 }
 
-function _comment_cck_submit($form, &$form_state) {
-  if ($form_state['values']['comment_cck_node_'. $form_state['values']['comment_cck_field']] == TRUE) {
-    // Allow it to alter comments on nodes with this type
-    variable_set('comment_cck_node_'. $form_state['values']['comment_cck_node'], TRUE);
-    // Merge other fields for this node type with the one currently being added.
-    // $form_state['field_name'] is the key for two reasons: first of all,
-    // it's much easier to remove fields, second it prevents duplicates
-    variable_set('comment_cck_fields_'. $form_state['values']['comment_cck_node'], array_merge(array($form_state['values']['comment_cck_field'] => $form_state['values']['comment_cck_field']), variable_get('comment_cck_fields_'. $form_state['values']['comment_cck_node'], array())));
+function _comment_cck_field_edit_form_submit($form, &$form_state) {
+  $type_name = $form_state['values']['type_name'];
+  $field_name = $form_state['values']['field_name'];
+  if ($form_state['values']['comment_cck_enabled'] == TRUE) {
+    $fields = variable_get('comment_cck_fields_'. $type_name, array());
+    // Merge this field with other fields for this content type.
+    $fields = array_merge(array($field_name => $field_name), $fields);
+    variable_set('comment_cck_fields_'. $type_name, $fields);
   }
   else {
-    // Get the fields
-    $fields = variable_get('comment_cck_fields_'. $form_state['values']['comment_cck_node'], array());
-    // Unset the field
-    unset($fields[$form_state['field_name']]);
-    // And set it back again
-    variable_set('comment_cck_fields_'. $form_state['type_name'], $fields);
-    // Check if there are any fields left
-    if (empty($fields)) {
-      // Make this false so that it doesn't try to add a form
-      variable_set('comment_cck_node_'. $form_state['type_name'], FALSE);
-    }
+    // Get the list of comment_cck enabled fields for this content type.
+    $fields = variable_get('comment_cck_fields_'. $type_name, array());
+    // Unset this field from the list.
+    unset($fields[$field_name]);
+    // Set the list of comment_cck enabled fields again.
+    variable_set('comment_cck_fields_'. $type_name, $fields);
   }
   return;
 }
 
 /**
- * Implementation of hook_comment
+ * Implementation of hook_comment().
  */
 function comment_cck_comment(&$comment, $op) {
-  // It is possible that a user without permissions submitted a comment, in which case, ignore.
+  // Ignore if a user without the correct permissions submitted this comment.
   if (!user_access('change cck fields through comments') && $op != 'view') {
     return;
   }
+
   switch ($op) {
     case 'update':
-      $node = node_load($comment['nid']);
-      if (variable_get('comment_cck_node_'. $node->type, FALSE) == TRUE) {
-        // Merge the new array with the old node.
-        $node = (object) array_merge((array) node_load($comment['nid']), $comment['comment_cck']);
-        // We do not want a new revision.
+      $original_node = node_load($comment['nid']);
+      if ($fields = variable_get('comment_cck_fields_'. $original_node->type, array())) {
+        // Ungroup the fields in this comment, if necessary.
+        $comment_fields = _comment_cck_ungroup_fields($comment['comment_cck'], $fields, $original_node->type);
+        // Merge the updated fields in this comment with the original node.
+        $node = (object) array_merge((array) $original_node, $comment_fields);
+        // We don't want a node revision, since we're updating an old comment.
+        // @TODO: Do we?
         $node->revision = 0;
         $node->vid = db_result(db_query('SELECT vid FROM {comment_cck_revisions} WHERE cid = %d', $comment['cid']));
-        // Save the node.
+        // Save the node with the updated field data.
         node_save($node);
       }
       break;
 
     case 'insert':
       $original_node = node_load($comment['nid']);
-      if (variable_get('comment_cck_node_'. $original_node->type, FALSE) == TRUE) {
-        // Merge the new array with the old node.
-        $node = (object) array_merge((array) $original_node, $comment['comment_cck']);
+      if ($fields = variable_get('comment_cck_fields_'. $original_node->type, array())) {
+        // Ungroup the fields in this comment, if necessary.
+        $comment_fields = _comment_cck_ungroup_fields($comment['comment_cck'], $fields, $original_node->type);
+        // Merge the updated fields in this comment with the original node.
+        $node = (object) array_merge((array) $original_node, $comment_fields);
         $previous_vid = $node->vid;
-        // We want a new revision.
+        // We do want a node revision, since this is a new comment.
         $node->revision = 1;
-        // Save the node.
+        // Save the node with the updated field data.
         node_save($node);
-        // Record that this comment added a revision.
+        // Record that this comment added a node revision.
         db_query('INSERT INTO {comment_cck_revisions} (cid, vid, previous_vid) VALUES (%d, %d, %d)', $comment['cid'], $node->vid, $previous_vid);
-        // Update comment revision id.
+        // Update the comment revision id.
+        // @TODO: What is this needed for?
         $comment['revision_id'] = $node->vid;
       }
       break;
 
     case 'view':
       $node = node_load($comment->nid);
-      if (variable_get('comment_cck_node_'. $node->type, FALSE) == TRUE) {
-        // Get the fields
-        $fields = variable_get('comment_cck_fields_'. $node->type, array());
-        // We're gonna prepend to the comment, not append.
-        $previous_text = $comment->comment;
-        // Get the revisions associated with this comment.
+      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) {
-          // If the fields were changed.
+        foreach ($fields as $field) {
+          // Check if the field was changed with this comment.
           if ($current_node->$field != $previous_node->$field) {
-            // Current field.
-            $current = _comment_cck_render_field($field, $cck_fields, $current_node);
-            // Previous field.
-            $previous = _comment_cck_render_field($field, $cck_fields, $previous_node);
-            // Iterate over the current values.
-            foreach ($current as $delta => $item) {
+            // 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[$delta]) {
+              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[$delta]), "&raquo;", drupal_render($item));
+                $result[] = array($cck_fields['fields'][$field]['widget']['label'] .':&nbsp', drupal_render($previous_field[$delta]), "&raquo;", drupal_render($item));
                 _comment_cck_rendering(FALSE);
               }
             }
           }
         }
-        // Make sure we have changes.
+        // 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');
-          $comment->comment = theme('table', array(), $result, array('class' => 'comment_cck')) . $previous_text;
+          // @TODO: Create template and preprocessing function.
+          $comment->comment = theme('table', array(), $result, array('class' => 'comment_cck')) . $comment_text;
         }
       }
       break;
@@ -188,26 +185,24 @@ function comment_cck_comment(&$comment, 
 }
 
 /**
- * Build a node and it's content
+ * Build a node and it's content.
  */
-function _comment_cck_build_node($criteria, $rev) {
-  $node = node_load($criteria, $rev);
-  $node = node_build_content($node, FALSE, FALSE);
-  
+function _comment_cck_build_node($criteria, $revision) {
+  $node = node_load($criteria, $revision);
+  $node = node_build_content($node);
   return $node;
 }
 
 /**
- * Render a field
+ * Render a field.
  */
 function _comment_cck_render_field($field_name, $cck_fields, $node) {
   // Mostly taken from content.module.
   $field_types = _content_field_types();
-  $context = 'full';
   $field = $cck_fields['fields'][$field_name];
   $node_field = isset($node->$field_name) ? $node->$field_name : array();
-  $module = $field_types[$field['type']]['module'];
-  $function = $module .'_field';
+  $cck_submodule = $field_types[$field['type']]['module'];
+  $function = $cck_submodule .'_field';
   if (function_exists($function)) {
     $result = $function('view', $node, $field, $node_field, NULL, NULL);
   }
@@ -216,7 +211,7 @@ function _comment_cck_render_field($fiel
   }
   $return = array();
   if (is_array($result)) {
-    $return = array_merge($return, $result);
+    $return = $result;
   }
   elseif (isset($result)) {
     $return[] = $result;
@@ -229,13 +224,34 @@ function _comment_cck_render_field($fiel
  */
 function comment_cck_preprocess_content_field(&$variables) {
   if (_comment_cck_rendering()) {
-    $variables['label_display'] = 'none';
+    // Hide the field labels as output by CCK.
+    $variables['label_display'] = 'hidden';
   }
 }
 
 /**
- * Helper function: get/set if we're rendering a cck field for a comment rather
- * than a node.
+ * Flatten grouped fields.
+ */
+function _comment_cck_ungroup_fields($comment_fields, $fields, $node_type) {
+  // @TODO: I'm sure this can be improved, but it works for now.
+  if (module_exists('fieldgroup')) {
+    $comment_fields_flat = array();
+    foreach ($fields as $key => $field) {
+      if ($group_name = fieldgroup_get_group($node_type, $field)) {
+        if ($comment_fields[$group_name][$field]) {
+          $comment_fields_flat[$key] = $comment_fields[$group_name][$field];
+        }
+      }
+      else {
+        $comment_fields_flat[$key] = $comment_fields[$field];
+      }
+    }
+    return $comment_fields_flat;
+  }
+}
+
+/**
+ * Keep track if we're rendering a field for a comment rather than a node.
  */
 function _comment_cck_rendering($set = NULL) {
   static $rendering;
@@ -243,4 +259,4 @@ function _comment_cck_rendering($set = N
     $rendering = $set;
   }
   return $rendering;
-}
\ No newline at end of file
+}
