/[drupal]/contributions/modules/comment_cck/comment_cck.module
ViewVC logotype

Contents of /contributions/modules/comment_cck/comment_cck.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.14 - (show annotations) (download) (as text)
Wed Jul 22 13:21:53 2009 UTC (4 months ago) by acm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +22 -28 lines
File MIME type: text/x-php
refactor of hook_comment code as well as fixing #481070 and #527258
1 <?php
2 // $Id: comment_cck.module,v 1.13 2009/05/08 18:59:42 coreymitchell Exp $
3
4 /**
5 * Implementation of hook_perm().
6 */
7 function comment_cck_perm() {
8 return array('change cck fields through comments');
9 }
10
11 /**
12 * Implementation of hook_form_alter().
13 */
14 function comment_cck_form_alter(&$form, &$form_state, $form_id) {
15 if ($form_id == 'comment_form' && user_access('change cck fields through comments')) {
16 $node = node_load($form['nid']['#value']);
17 // Check if any fields in this node type are comment_cck enabled.
18 if ($fields = variable_get('comment_cck_fields_'. $node->type, array())) {
19 // Include the functions to load the full node form.
20 module_load_include('inc', 'content', 'includes/content.node_form');
21 // This is a dummy node form, in which to gather the original fields.
22 $node_form['type'] = array(
23 '#type' => 'value',
24 '#value' => $node->type,
25 );
26 $node_form['#node'] = $node;
27 // This form will contain only the comment_cck enabled fields.
28 $final_form = $node_form;
29 $node_form = content_form($node_form, $form_state);
30
31 foreach ($fields as $field) {
32 if (isset($node_form[$field])) {
33 // Only add fields that are comment_cck enabled.
34 $final_form[$field] = $node_form[$field];
35 $form['#field_info'][$field] = $node_form['#field_info'][$field];
36 }
37 }
38
39 // If the fieldgroup module is installed, put fields into groups.
40 if (function_exists('fieldgroup_form_alter')) {
41 // Call fieldgroup_form_alter() to group the fields.
42 $final_form_id = $node->type .'_node_form';
43 fieldgroup_form_alter($final_form, array(), $final_form_id);
44 }
45 // Leaving the node type in the form causes it to output, so remove.
46 unset($final_form['type']);
47
48 // Add the comment_cck fields to comment_filter in order to postion it
49 // within the comment form.
50 $form['comment_filter']['comment_cck'] = $final_form;
51 // Set the position of the comment_cck fields within the comment form.
52 $form['comment_filter']['comment_cck']['#weight'] = 50;
53 // Set the comment_cck fields to output in the correct format.
54 $form['comment_filter']['comment_cck']['#tree'] = TRUE;
55 }
56 return;
57 }
58 if ($form_id == 'content_field_edit_form' && !$form_state['change_basic']) {
59 // Enable comment_ck to alter this field within this content type.
60 $form['widget']['comment_cck_enabled'] = array(
61 '#type' => 'checkbox',
62 '#title' => t('Allow comments to alter this field'),
63 '#description' => t('If checked, comments can alter this CCK field.'),
64 '#default_value' => in_array($form['field_name']['#value'], variable_get('comment_cck_fields_'. $form['type_name']['#value'], array())),
65 );
66 $form['#submit'][] = '_comment_cck_field_edit_form_submit';
67 }
68 }
69
70 function _comment_cck_field_edit_form_submit($form, &$form_state) {
71 $type_name = $form_state['values']['type_name'];
72 $field_name = $form_state['values']['field_name'];
73 if ($form_state['values']['comment_cck_enabled'] == TRUE) {
74 $fields = variable_get('comment_cck_fields_'. $type_name, array());
75 // Merge this field with other fields for this content type.
76 $fields = array_merge(array($field_name => $field_name), $fields);
77 variable_set('comment_cck_fields_'. $type_name, $fields);
78 }
79 else {
80 // Get the list of comment_cck enabled fields for this content type.
81 $fields = variable_get('comment_cck_fields_'. $type_name, array());
82 // Unset this field from the list.
83 unset($fields[$field_name]);
84 // Set the list of comment_cck enabled fields again.
85 variable_set('comment_cck_fields_'. $type_name, $fields);
86 }
87 return;
88 }
89
90 /**
91 * Implementation of hook_comment().
92 */
93 function comment_cck_comment(&$comment, $op) {
94 // Ignore if a user without the correct permissions submitted this comment.
95 if (!user_access('change cck fields through comments') && $op != 'view') {
96 return;
97 }
98
99 switch ($op) {
100 case 'update': case 'insert':
101 $original_node = node_load($comment['nid']);
102 if ($fields = variable_get('comment_cck_fields_'. $original_node->type, array())) {
103 // Ungroup the fields in this comment, if necessary.
104 $comment_fields = _comment_cck_ungroup_fields($comment['comment_cck'], $fields, $original_node->type);
105 // Merge the updated fields in this comment with the original node.
106 $node = (object) array_merge((array) $original_node, $comment_fields);
107 if($op == 'update') {
108 // We don't want a node revision, since we're updating an old comment.
109 // @TODO: Do we?
110 $node->revision = 0;
111 $node->vid = db_result(db_query('SELECT vid FROM {comment_cck_revisions} WHERE cid = %d', $comment['cid']));
112 // Save the node with the updated field data.
113 node_save($node);
114 }
115 else {
116 $node->revision = 1;
117 // Save the node with the updated field data.
118 node_save($node);
119 // Record that this comment added a node revision.
120 db_query('INSERT INTO {comment_cck_revisions} (cid, vid, previous_vid) VALUES (%d, %d, %d)', $comment['cid'], $node->vid, $previous_vid);
121 // Update the comment revision id.
122 // @TODO: What is this needed for?
123 $comment['revision_id'] = $node->vid;
124 }
125 }
126 break;
127
128 case 'view':
129 $node = node_load($comment->nid);
130 if ($fields = variable_get('comment_cck_fields_'. $node->type, array())) {
131 // We'll prepend the updated fields to the comment, not append.
132 $comment_text = $comment->comment;
133 // Get the comment_cck revisions associated with this comment.
134 $comment_revision = db_fetch_object(db_query('SELECT * FROM {comment_cck_revisions} WHERE cid = %d', $comment->cid));
135 if (!is_object($comment_revision)) {
136 // @TODO: Get this to work on preview. For now, degrade gracefully.
137 break;
138 }
139 if ($comment->op == t('Preview')) {
140 // @TODO: Is this a better way to check for preview? Get working!
141 break;
142 }
143 $current_node = _comment_cck_build_node((int) $comment->nid, $comment_revision->vid);
144 $previous_node = _comment_cck_build_node((int) $comment->nid, $comment_revision->previous_vid);
145 $cck_fields = content_types($node->type);
146
147 $result = array();
148 foreach ($fields as $field) {
149 // Check if the field was changed with this comment.
150 if ($current_node->$field != $previous_node->$field) {
151 // Render the current field.
152 $current_field = _comment_cck_render_field($field, $cck_fields, $current_node);
153 // Render the previous field.
154 $previous_field = _comment_cck_render_field($field, $cck_fields, $previous_node);
155 // Iterate over the current field values.
156 foreach ($current_field as $delta => $item) {
157 // Make sure they're different.
158 if ($item != $previous_field[$delta]) {
159 // They're different. Add them.
160 _comment_cck_rendering(TRUE);
161 $result[] = array($cck_fields['fields'][$field]['widget']['label'] .':&nbsp', drupal_render($previous_field[$delta]), "&raquo;", drupal_render($item));
162 _comment_cck_rendering(FALSE);
163 }
164 }
165 }
166 }
167 // If this comment changed any fields, update the comment output.
168 if (!empty($result)) {
169 drupal_add_css(drupal_get_path('module', 'comment_cck') .'/comment_cck.css');
170 // @TODO: Create template and preprocessing function.
171 $comment->comment = theme('table', array(), $result, array('class' => 'comment_cck')) . $comment_text;
172 }
173 }
174 break;
175 }
176 return $comment;
177 }
178
179 /**
180 * Build a node and it's content.
181 */
182 function _comment_cck_build_node($criteria, $revision) {
183 $node = node_load($criteria, $revision);
184 $node = node_build_content($node);
185 return $node;
186 }
187
188 /**
189 * Render a field.
190 */
191 function _comment_cck_render_field($field_name, $cck_fields, $node) {
192 // Mostly taken from content.module.
193 $field_types = _content_field_types();
194 $field = $cck_fields['fields'][$field_name];
195 $node_field = isset($node->$field_name) ? $node->$field_name : array();
196 $cck_submodule = $field_types[$field['type']]['module'];
197 $function = $cck_submodule .'_field';
198 if (function_exists($function)) {
199 $result = $function('view', $node, $field, $node_field, NULL, NULL);
200 }
201 if (!isset($result)) {
202 $result = content_field('view', $node, $field, $node_field, NULL, NULL);
203 }
204 $return = array();
205 if (is_array($result)) {
206 $return = $result;
207 }
208 elseif (isset($result)) {
209 $return[] = $result;
210 }
211 return $return;
212 }
213
214 /**
215 * Implementation of hook_preprocess_content_field().
216 */
217 function comment_cck_preprocess_content_field(&$variables) {
218 if (_comment_cck_rendering()) {
219 // Hide the field labels as output by CCK.
220 $variables['label_display'] = 'hidden';
221 }
222 }
223
224 /**
225 * Flatten grouped fields.
226 */
227 function _comment_cck_ungroup_fields($comment_fields, $fields, $node_type) {
228 // @TODO: I'm sure this can be improved, but it works for now.
229 if (module_exists('fieldgroup')) {
230 $comment_fields_flat = array();
231 foreach ($fields as $key => $field) {
232 if ($group_name = fieldgroup_get_group($node_type, $field)) {
233 if ($comment_fields[$group_name][$field]) {
234 $comment_fields_flat[$key] = $comment_fields[$group_name][$field];
235 }
236 }
237 else {
238 $comment_fields_flat[$key] = $comment_fields[$field];
239 }
240 }
241 return $comment_fields_flat;
242 }
243
244 return $comment_fields;
245 }
246
247 /**
248 * Keep track if we're rendering a field for a comment rather than a node.
249 */
250 function _comment_cck_rendering($set = NULL) {
251 static $rendering;
252 if (!is_null($set)) {
253 $rendering = $set;
254 }
255 return $rendering;
256 }

  ViewVC Help
Powered by ViewVC 1.1.2