--- comment_cck.module	2008-06-02 19:20:14.000000000 -0400
+++ comment_cck_gc_090526.module	2009-05-25 21:27:27.078125000 -0400
@@ -1,6 +1,9 @@
 <?php
 // $Id: comment_cck.module,v 1.1.2.4 2008/06/02 23:20:13 killes Exp $
 
+function comment_cck_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+}
+
 /**
  * Implementation of hook_perm().
  */
@@ -13,40 +16,86 @@ function comment_cck_perm() {
  * Implementation of hook_form_alter.
  */
 function comment_cck_form_alter($form_id, &$form) {
-  if ($form_id == 'comment_form' && user_access('allow fields to be changed')) {
+  
+  // a content type's field overview form
+  if ($form_id == 'content_admin_field_overview_form') {
+    $form['submit']['#weight'] = 30;
+    
+    $type = $form['type_name']['#value'];
+    
+    $form['comment_cck_settings'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Comment CCK'),
+      '#weight' => 29
+    );
+    
+    $form['comment_cck_settings']['comment_cck_teaser_settings'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use teaser display fields for comment cck display.'),
+      '#default_value' => variable_get('comment_cck_teaser_settings_'. $type, FALSE),
+    );
+    
+    $form['comment_cck_settings']['comment_cck_header_settings'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show a header on the comment changes table.'),
+      '#default_value' => variable_get('comment_cck_header_settings_'. $type, TRUE),
+    );
+    
+    $form['comment_cck_settings']['comment_cck_body_settings'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Comment body is required.'),
+      '#default_value' => variable_get('comment_cck_body_settings_'. $type, TRUE),
+    );
+    
+    $form['#submit'] += array('comment_cck_field_overview_submit' => array());
+  }
+  // a comment form
+  else if ($form_id == 'comment_form' && user_access('allow fields to be changed')) {
     $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
+      // Get the full form
       $content_form = content_form($node);
-      // This will hold the form with only the fields we need
-      $final_form = array();
-      $final_form['type']['#value'] = $node->type;
-
-      foreach ($fields as $field) {
-        if (isset($content_form[$field])) {
-          // Only add fields that are comment_cck enabled
-          $final_form[$field] = $content_form[$field];
+
+      foreach($content_form as $field_name => $field) {
+        if (substr($field_name, 0, 1) != '#' && !$fields[$field_name]) {
+          $content_form[$field_name]['#access'] = FALSE;
         }
       }
       // if we've got the fieldgroup module installed
       if (function_exists('fieldgroup_form_alter')) {
         // call fieldgroup_form_alter to add all the groupings.
-        fieldgroup_form_alter($node->type . "_node_form", $final_form);
+        $content_form['type']['#value'] = $node->type;
+        fieldgroup_form_alter($node->type . "_node_form", $content_form);
+        unset($content_form['type']);
+      }
+      
+      // gc: if the body isn't required, we'll shrink it too
+      if(!variable_get('comment_cck_body_settings_'. $node->type, TRUE)) {
+        $form['comment_filter']['comment']['#required'] = 0;
+        $form['comment_filter']['comment']['#rows'] = 7;
       }
-      // We don't need to know this, leaving it in just prints it in the form, so remove it.
-      unset($final_form['type']);
+
       // Add it to comment_filter so it maintains the correct postion in the form
-      $form['comment_filter']['comment_cck'] = $final_form;
+      $form['comment_filter']['comment_cck'] = $content_form;
       // Make it sink
       $form['comment_filter']['comment_cck']['#weight'] = 50;
       // It's tons easier like this
-      $form['comment_filter']['comment_cck']['#tree'] = TRUE;
+      // gc: removed this because of collisions w/ fieldgroups and drupal_execute
+      //$form['comment_filter']['comment_cck']['#tree'] = TRUE;
+      // gc: save ourselves as node_load later
+      $form['comment_filter']['comment_cck']['comment_cck_active'] = array(
+        '#type' => 'value',
+        '#value' => 1,
+      );
+      
     }
     return;
   }
+  // an individual field's edit form
   if ($form_id == '_content_admin_field') {
     $form['field']['allow_comment_altering'] = array(
       '#type' => 'checkbox',
@@ -58,6 +107,20 @@ function comment_cck_form_alter($form_id
   }
 }
 
+/*
+ * save the comment_cck options for this content type
+ * this function is injected into the content type's submission function array
+ *   in comment_cck_form_alter above
+ */    
+
+function comment_cck_field_overview_submit($form_id, $form_values) {
+  $type = $form_values['type_name'];
+  
+  variable_set('comment_cck_teaser_settings_'. $type, $form_values['comment_cck_teaser_settings']);
+  variable_set('comment_cck_header_settings_'. $type, $form_values['comment_cck_header_settings']);
+  variable_set('comment_cck_body_settings_'. $type, $form_values['comment_cck_body_settings']);
+}
+
 function _comment_cck_submit($form_id, $form_values) {
   if ($form_values['allow_comment_altering'] == TRUE) {
     // Allow it to alter comments on nodes with this type
@@ -85,97 +148,123 @@ function _comment_cck_submit($form_id, $
 
 /**
  * Implementation of hook_comment
+ *  
+ * gc: still having problems with cck fields of a non-standard structure that
+ * aren't editable by comments wiping out the values of those fields
+ * in the parent node. nodereference, userreference, and date X(
+ * i think drupal_execute is the answer but i haven't nailed it yet
  */
+        
 function comment_cck_comment(&$comment, $op) {
   switch ($op) {
+    case 'validate':
+      // TODO: run the values in the comment_cck through content_validate
+      break;
     case 'insert':
-    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']);
-        $previous_vid = $node->vid;
-        // We want a new revision
-        $node->revision = 1;
-        // Required to get the data in the right format
+    case 'update': 
+      if ($comment['comment_cck_active']) {
+    
+        $node = node_load($comment['nid']);
+        // gc: some of this is flailing to get drupal_execute working well
+        content_validate($node);
         content_submit($node);
+        
+        _content_widget_invoke('prepare form values', $node);
+        $editable_fields = variable_get('comment_cck_fields_'. $node->type, array());
+        $post = array();
+        
+        $type_name = $node->type;
+        $type = content_types($type_name);
+        $widget_types = _content_widget_types();
+        
+        if (count($type['fields'])) {
+          foreach ($type['fields'] as $field) {
+            // gc: building an array of POST values, essentially
+            if (isset($editable_fields[$field['field_name']])) {
+              $post[$field['field_name']] = $comment[$field['field_name']];            
+            }
+            // gc: big hunk of experimental code from content.module -> _content_widget invoke
+/*            else {
+              $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
+              $module = $widget_types[$field['widget']['type']]['module'];
+              $function = $module .'_widget';
+              if (function_exists($function)) {
+                $function('process form values', $node, $field, $node_field);
+                $function('submit', $node, $field, $node_field);
+                //$post[$field['field_name']] = $node_field;
+              }
+              // test for values in $node_field in case modules added items
+              if (is_object($node) && (isset($node->$field['field_name']) || count($node_field))) {
+                $node->$field['field_name'] = $node_field;
+              }
+            }*/
+          }
+        }
+        // We want a new revision 
+        $previous_vid = $node->vid;
+        $post['revision'] = 1;
+        $post['log'] = t('Updated by comment #!cid', array('!cid' => $comment['cid']));
         // Save the node
-        node_save($node);
+        
+        drupal_execute($node->type .'_node_form', $post, $node);
+        $new_vid = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $node->nid));
+        
         // Record that this comment added a revision
-        db_query('INSERT INTO {comment_cck_revisions} (cid, vid, nid, previous_vid) VALUES (%d, %d, %d, %d)', $comment['cid'], $node->vid, $node->nid, $previous_vid);
+        db_query('INSERT INTO {comment_cck_revisions} (cid, vid, nid, previous_vid) VALUES (%d, %d, %d, %d)', $comment['cid'], $new_vid, $node->nid, $previous_vid);
         // Update comment revision id
-        $comment['revision_id'] = $node->vid;
+        $comment['revision_id'] = $new_vid;
       }
       break;
     case 'view':
       $node = node_load($comment->nid);
-      if (variable_get('comment_cck_node_'. $node->type, FALSE) == TRUE) {
+      $type = $node->type;
+      
+      if (variable_get('comment_cck_node_'. $type, FALSE) == TRUE ) {
         // Get the fields
-        $fields = variable_get('comment_cck_fields_'. $node->type, array());
+        $fields = variable_get('comment_cck_fields_'. $type, array());
+        $teaser_settings = variable_get('comment_cck_teaser_settings_'. $type, FALSE);
+        $header_settings = variable_get('comment_cck_header_settings_'. $type, FALSE);
+        
         // We're gonna prepend to the comment, not append.
         $previous_text = $comment->comment;
         // Get the revisions associated with this comment.
         $comment_revision = db_fetch_object(db_query('SELECT * FROM {comment_cck_revisions} WHERE cid = %d', $comment->cid));
-        // The node that resulted from the update.
-        $current_node = node_load((int) $comment_revision->nid, $comment_revision->vid);
-        // The node, before the update.
-        $previous_node = node_load((int) $comment_revision->nid, $comment_revision->previous_vid);
-        // And our CCK fields (so we can get the labels and such).
-        $cck_fields = content_types($node->type);
-        
-        $result = array();
-        
-        foreach($fields as $field) {
-          // If the fields were changed.
-          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) {
-              // Make sure they're different.
-              if ($item != $previous[$delta]) {
-                // They're different.  Add them.
-                $result[] = array($cck_fields['fields'][$field]['widget']['label'] .':&nbsp', $previous[$delta]['view'], "&raquo;", $item['view']);
+        // gc: in these node_build_content calls, going to allow the use of teaser view.
+        // it should allow for the content type to hide unalterable fields on
+        // the teaser view, thus speeding load time, and presenting a presumably
+        // shorter value for the change summary table, since those are often used
+        // in teaser views.
+        if ($comment_revision) {
+          // The node that resulted from the update.
+          $current_node = node_build_content(node_load((int) $comment_revision->nid, $comment_revision->vid), $teaser_settings);
+          // The node, before the update.
+          $previous_node = node_build_content(node_load((int) $comment_revision->nid, $comment_revision->previous_vid), $teaser_settings);
+          // And our CCK fields (so we can get the labels and such).
+          $cck_fields = content_types($type);
+          
+          $result = array();
+          
+          foreach($fields as $field) {
+            // If the fields were changed.
+            if ($current_node->$field != $previous_node->$field) {
+              // Iterate over the current values.
+              foreach ($current_node->{$field} as $delta => $item) {
+                // Make sure they're different and we have something to view.
+                if ($item['view'] && $item != $previous_node->{$field}[$delta]) {
+                  // They're different.  Add them.
+                  $result[] = array($cck_fields['fields'][$field]['widget']['label'] .':&nbsp', $previous_node->{$field}[$delta]['view'], "&raquo;", $item['view']);
+                }
               }
             }
           }
-        }
-        // Make sure we have changes.
-        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;
+          // Make sure we have changes.
+          if (!empty($result)) {
+            drupal_add_css(drupal_get_path('module', 'comment_cck') .'/comment_cck.css');
+            $header = ($header_settings ? array(t('Updates'), t('Original'), '', t('Changed')) : array());
+            $comment->comment = theme('table', $header, $result, array('class' => 'comment_cck')) . $previous_text;
+          }
         }
       }
       break;
   }
-  return $comment;
-}
-
-/**
- * Render a field
- */
-function _comment_cck_render_field($field_name, $cck_fields, $node) {
-  // Mostly taken from content.module.
-  
-  $final = array();
-  $field = $cck_fields['fields'][$field_name];
-  $node_field = isset($node->$field_name) ? $node->$field_name : array();
-  $formatter = isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default';
-  $value = '';
-  if (content_handle('field', 'view', $field) == CONTENT_CALLBACK_CUSTOM) {
-    $module = $field_types[$field['type']]['module'];
-    $function = $module .'_field';
-    if (function_exists($function)) {
-      // TODO: I'm not sure what this should be.
-      $value = $function('view', $node, $field, $node_field, $teaser, $page);
-    }
-  }
-  else {
-    foreach ($node_field as $delta => $item) {
-      $final[$delta] = $item;
-    }
-  }
-  return $final;
-}
+}
\ No newline at end of file
