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

Contents of /contributions/modules/comment_mover/comment_mover.module

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


Revision 1.22 - (show annotations) (download) (as text)
Sun Dec 17 20:53:51 2006 UTC (2 years, 11 months ago) by heine
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-5
Changes since 1.21: +105 -34 lines
File MIME type: text/x-php
Update to Drupal-5 compatability
1 <?php
2 // $Id: comment_mover.module,v 1.21 2006/12/08 21:37:04 heine Exp $
3
4 define ('COMMENT_MOVER_NODE_TO_COMMENT', 1);
5 define ('COMMENT_MOVER_COMMENT_TO_NODE', 2);
6 define ('COMMENT_MOVER_COMMENT_TO_COMMENT', 3);
7 define ('COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD', 4);
8
9 /**
10 * Implementation of hook_help
11 */
12 function comment_mover_help($section) {
13 switch ($section) {
14 case 'admin/help#comment_mover':
15 $output = '<p>'. t('Comment mover enables you to move comments and nodes around by pruning and grafting. Pruning and grafting are similar to cut and paste but operate on branches, not on single comments. If you prune and graft a comment thread, the entire thread will be moved, not just the pruned comment.') .'</p>';
16 $output .= '<p>'. t('Basic use is simple; it starts by pruning a node or comment via the link prune. The pruned node/comment now appears in the Graft block. The graft block shows the title and author of the pruned content and always allows you to cancel the action. You can now navigate through your site and choose one of two options: grafting or conversion.') .'</p>';
17 $output .= '<p>'. t('Grafting is a simple matter: simply click the graft link on the content (comment or node) you want the pruned object to reside under. All childcomments will be moved together with the pruned node or comment') .'</p>';
18
19 $output .= '<p>'. t('If you just pruned a comment and enabled story and page under "Enable promotion to the following node types" on the <a href="@url">comment mover settings page</a>, the graft block also shows you story and page in the selection of node types to which the
20 comment can be converted. When you then, for example, select story and click convert, a story submission form will appear with prefilled fields. Edit if necessary, then click submit. A new story node will be created. All children of the original comment will be moved to the new node.', array('@url' => url('admin/settings/comment_mover'))) .'</p>';
21 $output .= '<p>'. t('When you move a comment to another node or convert it to a node, the original comment will contain a link pointing to the comments new location. When you move a node to become a comment on another node, the original node will contain a redirect to the new location.') .'</p>';
22 return $output;
23 }
24 }
25
26 /**
27 * Implementation of hook_menu
28 */
29 function comment_mover_menu($may_cache) {
30 $items = array();
31
32 $access = user_access('administer comments');
33 if ($may_cache) {
34 $items[] = array('path' => 'comment/cancel', 'title' => t('cancel pruning'),
35 'access' => $access,
36 'callback' => 'comment_mover_cancel',
37 'type' => MENU_CALLBACK);
38 $items[] = array('path' => 'admin/settings/comment_mover',
39 'title' => t('Comment mover'),
40 'description' => t('Configure comment mover to operate on specific content types.'),
41 'callback' => 'drupal_get_form',
42 'callback arguments' => 'comment_mover_settings',
43 'access' => user_access('administer site configuration'),
44 );
45 }
46 else {
47 $items[] = array('path' => 'comment/promote', 'title' => t('Promote comment'),
48 'callback' => 'comment_mover_promote', 'access' => $access,
49 'type' => MENU_CALLBACK);
50
51 $items[] = array('path' => 'comment/graft', 'title' => t('Prune comment'),
52 'callback' => 'comment_mover_graft', 'access' => $access,
53 'callback arguments' => array(arg(2), arg(3)),
54 'type' => MENU_CALLBACK);
55
56 $items[] = array('path' => 'comment/prune', 'title' => t('Prune comment'),
57 'callback' => 'comment_mover_prune', 'access' => $access,
58 'callback arguments' => array(arg(2), arg(3)),
59 'type' => MENU_CALLBACK);
60 }
61
62 return $items;
63 }
64
65 /**
66 * Implementation of hook_link
67 */
68 function comment_mover_link($type, $object = 0, $teaser = FALSE) {
69 $links = array();
70
71 if ($type == 'comment' && user_access('administer comments')) {
72 $prune = comment_mover_pruning();
73 if ($prune) {
74 // Display graft link when
75 if (comment_mover_allows_grafting('comment', $object) && // grafting is allowed on the node type
76 $prune->cid != $object->cid && // comment is not the pruned comment
77 !($prune->nid == $object->nid && $prune->cid == 0) && // comment is not a child of the pruned node
78 !in_array($object->cid, comment_mover_get_children($prune->cid))) { // comment is not a child of the pruned comment
79
80 $links['comment_mover_comment_graft'] = array(
81 'title' => t('graft'),
82 'href' => "comment/graft/{$object->nid}/{$object->cid}",
83 );
84 }
85 }
86 else if (comment_mover_allows_pruning('comment', $object)) {
87 $links['comment_mover_comment_prune'] = array(
88 'title' => t('prune'),
89 'href' => "comment/prune/{$object->nid}/{$object->cid}",
90 );
91 }
92 }
93 else if ($type == 'node' && !$teaser && user_access('administer comments')) {
94 $prune = comment_mover_pruning();
95 if ($prune) {
96 // Display graft link when
97 if (comment_mover_allows_grafting('node', $object) && // grafting on node_type is set
98 !($prune->nid == $object->nid && $prune->cid == 0) && // node is not the pruned node
99 !($prune->nid == $object->nid && $prune->pid == 0)) { // node is not the direct parent of pruned comment
100 $links['comment_mover_node_graft'] = array(
101 'title' => t('Graft'),
102 'href' => "comment/graft/{$object->nid}",
103 );
104 }
105 }
106 else if (node_access('update', $object) && user_access('administer comments') && comment_mover_allows_pruning('node', $object)) {
107 $links['comment_mover_node_prune'] = array(
108 'title' => t('Prune'),
109 'href' => "comment/prune/{$object->nid}",
110 'query' => drupal_get_destination(),
111 );
112 }
113 }
114 return $links;
115 }
116
117
118 /**
119 * Displays node type select in block
120 *
121 */
122 function comment_mover_promote_form() {
123 $form = array();
124 $options = array();
125 foreach (node_get_types() as $node_type) {
126 $type = $node_type->type;
127 $name = $node_type->name;
128 if (node_access('create', $type) && variable_get("commentmover_promotion_$type", FALSE)) {
129 $options[$type] = $name;
130 }
131 }
132 if (!empty($options)) {
133 $form['type'] = array(
134 '#type' => 'select',
135 '#title' => t('Convert to'),
136 '#default_value' => 'forum',
137 '#options' => $options,
138 );
139 $form['submit'] = array('#type' => 'submit', '#value' => t('Convert'));
140 }
141 return $form;
142 }
143
144 function comment_mover_promote_form_submit($form_id, $form_values) {
145 return "comment/promote/{$form_values['type']}" ;
146 }
147
148
149 /**
150 * Menu callback, directs to a node submission form of $type.
151 */
152 function comment_mover_promote($type) {
153 global $user;
154 if (array_key_exists($type, node_get_types()) && node_access('create', $type) && variable_get("commentmover_promotion_$type", FALSE)) {
155 $prune = comment_mover_pruning();
156 if ($prune->nid && $prune->cid && user_access('administer comments') && comment_mover_allows_pruning('comment', $prune)) {
157 $comment = db_fetch_object(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.picture, u.data, n.title AS node_title FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid INNER JOIN {node} n ON c.nid = n.nid WHERE c.cid = %d AND c.status = 0', $prune->cid));
158 $comment = drupal_unpack($comment);
159 $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
160 $node = array(
161 'uid' => $comment->uid,
162 'name' => $comment->uid ? $comment->name : '',
163 'type' => $type,
164 'body' => $comment->comment,
165 'title' => $comment->subject,
166 'created' => $comment->timestamp,
167 'comment_mover' => TRUE,
168 );
169
170 // Set name & warn the user when converting an anonymous comment to a blog post.
171 if ($type == 'blog' && $comment->uid == 0) {
172 $node['name'] = $user->name;
173 drupal_set_message(t('Author has been set to %username.', array('%username' => theme('username', $user))));
174 }
175
176 //$output = node_form($node);
177 $output = drupal_get_form($type .'_node_form', $node);
178 drupal_set_title(t('Submit %name', array('%name' => node_get_types('name', $node))));
179 return $output;
180 }
181 }
182 }
183
184 /**
185 * Modify the node submission form to enable comment mover to do it's job in hook_nodeapi.
186 */
187 function comment_mover_form_alter($form_id, &$form) {
188 if ($form['#id'] == 'node-form' && isset($form['#node']->comment_mover)) {
189 $form['comment_mover'] = array('#type' =>'value', '#value' => TRUE);
190 // Correct the data field; node_form_array only sets the date if the node already has a nid.
191 if (user_access('administer nodes')) {
192 $form['author']['date']['#default_value'] = $form['#node']->date;
193 }
194 }
195 }
196
197 function comment_mover_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
198 if ($op == 'insert' && $node->comment_mover == TRUE) {
199 $prune = comment_mover_pruning();
200 $comment = db_fetch_array(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.picture, u.data, n.title AS node_title FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid INNER JOIN {node} n ON c.nid = n.nid WHERE c.cid = %d AND c.status = 0', $prune->cid));
201 $comment['comment_mover'] = COMMENT_MOVER_COMMENT_TO_NODE;
202 $comment['new_nid'] = $node->nid;
203 comment_mover_move($comment);
204 comment_mover_unset();
205 }
206 }
207
208 /**
209 * Post the comments, children and updates the statistcis of both nodes.
210 *
211 */
212 function comment_mover_comment_post($edit) {
213 global $user;
214
215 if (user_access('administer comments') && node_comment_mode($edit['nid']) == 2) {
216 if ($edit['cid'] && !$edit['comment_mover_multiple']) {
217 $thread = comment_mover_build_thread($edit);
218
219 db_query("UPDATE {comments} SET subject = '%s', comment = '%s', pid = %d, format = '%s', thread = '%s' WHERE cid = %d", $edit['subject'], $edit['comment'], $edit['pid'], $edit['format'], $thread, $edit['cid']);
220
221 _comment_update_node_statistics($edit['nid']);
222
223 // Allow modules to respond to the updating of a comment.
224 module_invoke_all('comment', 'update', $edit);
225
226 // Add an entry to the watchdog log.
227 watchdog('content', t('Comment: updated %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
228 }
229 else if ($edit['cid'] && $edit['comment_mover_multiple']) {
230 $thread = comment_mover_build_thread($edit);
231
232 db_query("UPDATE {comments} SET pid = %d, nid = %d, thread = '%s' WHERE cid = %d", $edit['pid'], $edit['nid'], $thread, $edit['cid']);
233
234 _comment_update_node_statistics($edit['nid']);
235 _comment_update_node_statistics($edit['old_nid']);
236 watchdog('content', t('Comment: moved %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
237 }
238 else {
239 // Add the comment to database.
240 $status = 0;
241 $roles = variable_get('comment_roles', array());
242 $score = 0;
243
244 foreach (array_intersect(array_keys($roles), array_keys($user->roles)) as $rid) {
245 $score = max($roles[$rid], $score);
246 }
247
248 $users = serialize(array(0 => $score));
249
250 $edit['cid'] = db_next_id('{comments}_cid');
251 $edit['timestamp'] = isset($edit['timestamp']) ? $edit['timestamp'] : time();
252
253 if ($edit['uid'] == $user->uid) {
254 $edit['name'] = $user->name;
255 }
256 else {
257 $account = user_load(array('uid' => $edit['uid']));
258 $edit['name'] = $account->name;
259 }
260
261 $thread = comment_mover_build_thread($edit);
262
263 db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, format, hostname, timestamp, status, score, users, thread, name, mail, homepage) VALUES (%d, %d, %d, %d, '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s')", $edit['cid'], $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], $_SERVER['REMOTE_ADDR'], $edit['timestamp'], $status, $score, $users, $thread, $edit['name'], $edit['mail'], $edit['homepage']);
264
265 _comment_update_node_statistics($edit['nid']);
266
267 // Tell the other modules a new comment has been submitted.
268 module_invoke_all('comment', 'insert', $edit);
269
270 // Add an entry to the watchdog log.
271 watchdog('content', t('Comment: added %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
272 }
273
274 // Clear the cache so an anonymous user can see his comment being added.
275 cache_clear_all();
276
277 return $edit;
278 }
279 }
280
281
282 /**
283 * Returns a flat array of child cids
284 *
285 * @param array $cid
286 * @return bool
287 *
288 */
289 function comment_mover_get_children($cid) {
290 static $childlist;
291 if (!isset($childlist)) {
292 $childlist = array();
293 $comment = comment_mover_load_comment($cid);
294 $thread = comment_mover_get_thread((array)$comment);
295 foreach ($thread as $depth => $children) {
296 foreach ($children as $child) {
297 $childlist[] = $child['cid'];
298 }
299 }
300 }
301 return $childlist;
302 }
303
304 /**
305 * Determines whether $cid is among comments in $thread
306 */
307 function comment_mover_target_is_child($cid, $thread) {
308 if ($cid) {
309 // Check whether the intended target is a child of the object
310 foreach ($thread as $depth => $children) {
311 foreach ($children as $child) {
312 if ($child['cid'] == $cid) {
313 return TRUE;
314 }
315 }
316 }
317 }
318 return FALSE;
319 }
320
321 /**
322 * Make a copy of a comment or node and save node/ comment with new body.
323 * Move children of node or comment along.
324 *
325 * $object (array) the comment or node
326 * $pid (integer) parent id, default 0
327 * $nid (integer) node id, needed in case pid = 0
328 */
329 function comment_mover_move($object, $pid = 0, $nid = 0) {
330
331 switch ($object['comment_mover']) {
332 case COMMENT_MOVER_COMMENT_TO_COMMENT:
333 case COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD:
334 $comment = $object;
335 $comment['pid'] = $pid;
336 if ($object['comment_mover'] == COMMENT_MOVER_COMMENT_TO_COMMENT) {
337 unset($comment['cid']);
338 }
339 break;
340 case COMMENT_MOVER_COMMENT_TO_NODE:
341 $new_nid = $object['new_nid'];
342 $comment = $object;
343 $comment['comment'] = t('This comment has been moved <a href="@url">here</a>.', array('@url' => url('node/'. $new_nid, NULL, NULL, TRUE)));
344 break;
345 case COMMENT_MOVER_NODE_TO_COMMENT:
346 $comment = $object;
347 $comment['comment'] = $object['body'];
348 $comment['subject'] = $object['title'];
349 $comment['status'] = 0;
350 break;
351 }
352
353 $comment['nid'] = $nid ? $nid : $object['nid'];
354
355 $thread = comment_mover_get_thread($object);
356
357 if ($comment['comment_mover'] == COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD && comment_mover_target_is_child($pid, $thread)) {
358 drupal_set_message(t('comment cannot be grafted on one of its children'));
359 return 0;
360 }
361
362 $new_comment = comment_mover_comment_post($comment);
363 foreach ($thread as $depth => $comments) {
364 foreach ($comments as $c) {
365 $c['old_nid'] = $c['nid'];
366 $c['nid'] = isset($new_nid) ? $new_nid : $new_comment['nid'];
367 $c['pid'] = ($depth == 1) ? (isset($new_nid) ? 0 : $new_comment['cid']) : $c['pid'];
368 $c['comment_mover_multiple'] = 1;
369 comment_mover_comment_post($c);
370 }
371 }
372
373 switch ($object['comment_mover']) {
374 case COMMENT_MOVER_COMMENT_TO_COMMENT:
375 // If we moved the comment to another node, add a redirector.
376 $object['comment'] = t('This comment has been moved <a href="%url">here</a>.', array('%url' => url('node/'. $nid, NULL, 'comment-'. $new_comment['cid'], TRUE)));
377 comment_mover_comment_post($object);
378 break;
379 case COMMENT_MOVER_NODE_TO_COMMENT:
380 $object['format'] = 2;
381 $object['body'] = "<?php\ndrupal_goto('node/". $comment['nid'] ."', NULL, 'comment-". $new_comment['cid'] ."')\n?>";
382 // for some reason this is needed.
383 unset($object['0']);
384 $object = (object) $object;
385 node_save($object);
386 }
387 if (module_exists('oglist')) {
388 switch ($object['comment_mover']) {
389 case COMMENT_MOVER_NODE_TO_COMMENT:
390 db_query('UPDATE {og2list_msgid} SET nid = %d, cid = %d WHERE nid = %d AND cid = 0', $new_comment['nid'], $new_comment['cid'], $object['nid']);
391 break;
392 case COMMENT_MOVER_COMMENT_TO_NODE:
393 db_query('UPDATE {og2list_msgid} SET nid = %d, cid = 0 WHERE nid = %d AND cid = %d', $nid, $object['new_nid'], $object['cid']);
394 break;
395 case COMMENT_MOVER_COMMENT_TO_COMMENT:
396 db_query('UPDATE {og2list_msgid} SET nid = %d, cid = %d WHERE nid = %d AND cid = %d', $new_comment['nid'], $new_comment['cid'], $object['nid'], $object['cid']);
397 break;
398 case COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD:
399 // Nothing to do
400 break;
401 }
402 }
403
404 return $new_nid ? $new_nid : $new_comment['cid'];
405 }
406
407 /**
408 * Buids a thread for comments
409 *
410 * @TODO change for 4.7
411 */
412 function comment_mover_build_thread($edit) {
413 // Here we are building the thread field. See the comment
414 // in comment_render().
415 if ($edit['pid'] == 0) {
416 // This is a comment with no parent comment (depth 0): we start
417 // by retrieving the maximum thread level.
418 $max = db_result(db_query('SELECT MAX(thread) FROM {comments} WHERE nid = %d', $edit['nid']));
419
420 // Strip the "/" from the end of the thread.
421 $max = rtrim($max, '/');
422
423 if(!$max) {
424 $thread = int2vancode(0) . '/';
425 } else {
426 $thread = int2vancode(vancode2int($max)+1) . '/';
427 }
428 }
429 else {
430 // This is comment with a parent comment: we increase
431 // the part of the thread value at the proper depth.
432
433 // Get the parent comment:
434 $parent = db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $edit['pid']));
435
436 // Strip the "/" from the end of the parent thread.
437 $parent->thread = (string) rtrim((string) $parent->thread, '/');
438
439 // Get the max value in _this_ thread.
440 $max = db_result(db_query("SELECT MAX(thread) FROM {comments} WHERE thread LIKE '%s.%%' AND nid = %d", $parent->thread, $edit['nid']));
441
442 if ($max == '') {
443 // First child of this parent.
444 $thread = $parent->thread .'.00/';
445 }
446 else {
447 // Strip the "/" at the end of the thread.
448 $max = rtrim($max, '/');
449
450 // We need to get the value at the correct depth.
451 $parts = explode('.', $max);
452 $parent_depth = count(explode('.', $parent->thread));
453 $last = $parts[$parent_depth];
454
455 $thread = $parent->thread .'.'. int2vancode(vancode2int($last) + 1) .'/';
456 }
457 }
458
459 return $thread;
460 }
461
462 /**
463 * Get a all children of a given comment (recursivly)
464 * or all comments if a node
465 */
466 function comment_mover_get_thread($parent) {
467 if (isset($parent['cid'])) {
468 $query = "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name , c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users, c.thread FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d AND SUBSTRING(c.thread, 1, LENGTH('%s')) = '%s' AND c.cid != %d AND c.status = 0 ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))";
469
470 $depth = substr_count($parent['thread'], '.');
471 $thread = substr($parent['thread'], 0, strlen($parent['thread']) - 1);
472 $result = db_query($query, $parent['nid'], $thread, $thread, $parent['cid']);
473 }
474 else {
475 $query = "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name , c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users, c.thread FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))";
476 $result = db_query($query, $parent['nid']);
477 $depth = - 1;
478 }
479
480 $thread = array();
481 while ($comment = db_fetch_array($result)) {
482 $child_depth = substr_count($comment['thread'], '.') - $depth;
483 $thread[$child_depth][] = $comment;
484 }
485
486 return $thread;
487 }
488
489 /**
490 * Setup the session variable to hold the nid or cid to be pruned
491 *
492 * @param $nid
493 * The node id
494 * @param $cid
495 * The comment id, if empty nid is the nid to be pruned
496 *
497 */
498 function comment_mover_prune($nid, $cid = 0) {
499 if (comment_mover_pruning()) {
500 // Already in pruning a post.
501 drupal_goto();
502 }
503 if (is_numeric($cid) && is_numeric($nid)) {
504 // Pruning a comment.
505 $comment = comment_mover_load_comment($cid);
506 if (comment_mover_allows_pruning('comment', $comment)) {
507 $_SESSION['comment_mover']['cid'] = $cid;
508 $_SESSION['comment_mover']['nid'] = $comment->nid;
509 $_SESSION['comment_mover']['pid'] = $comment->pid;
510 drupal_goto('node/'. $nid);
511 }
512 }
513 else if (is_numeric($nid)) {
514 // Pruning a node.
515 $node = node_load($nid);
516 if (comment_mover_allows_pruning('node', $node)) {
517 $_SESSION['comment_mover']['cid'] = 0;
518 $_SESSION['comment_mover']['nid'] = $nid;
519 $_SESSION['comment_mover']['pid'] = 0;
520 drupal_goto('node/'. $nid);
521 }
522 }
523 else {
524 drupal_set_message(t('Unable to prune the post'));
525 drupal_goto();
526 }
527 }
528
529 function comment_mover_graft($nid, $cid = 0) {
530 return drupal_get_form('confirm_comment_mover_graft', $nid, $cid);
531 }
532
533
534 function confirm_comment_mover_graft($nid, $cid) {
535 $form['nid'] = array('#type' => 'value', '#value' => $nid);
536 $form['cid'] = array('#type' => 'value', '#value' => $cid);
537 return confirm_form($form, t('Are you sure you want to move this post here?'), 'node/'. $nid);
538 }
539
540
541 /*
542 * The grafting part, wrapper for comment_mover_move
543 *
544 * @param $nid
545 * The nid where the comment should go
546 * @param $cid
547 * The cid that shoud become the parent of the pruned comment (in $_SESSION)
548 * If 0, the $nid should be the direct parent
549 */
550 function confirm_comment_mover_graft_submit($form_id, $form_values) {
551 $nid = $form_values['nid'];
552 $cid = $form_values['cid'];
553 $prune = comment_mover_pruning();
554
555 // Load node to check whether the target node allows grafting.
556 if (is_numeric($nid)) {
557 $target_node = node_load($nid);
558 }
559
560 if (isset($target_node) && comment_mover_allows_grafting('node', $target_node)) {
561 if ($prune->cid && user_access('administer comments') && comment_mover_allows_pruning('comment', $prune)) {
562 // We're moving a comment
563 $comment = db_fetch_array(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.picture, u.data, n.title AS node_title FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid INNER JOIN {node} n ON c.nid = n.nid WHERE c.cid = %d AND c.status = 0', $prune->cid));
564 if ($prune->nid == $nid) {
565 // Moving to the same thread
566 $comment['comment_mover'] = COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD;
567 $new_cid = comment_mover_move($comment, $cid, $nid);
568 if ($new_cid) {
569 comment_mover_unset();
570 drupal_goto('node/'. $nid);
571 }
572 drupal_goto('node/'. $nid, NULL, 'comment-'. $new_cid);
573 }
574 else {
575 // Moving to another node
576 // First step (move to node)
577 $comment['comment_mover'] = COMMENT_MOVER_COMMENT_TO_COMMENT;
578 $new_cid = comment_mover_move($comment, 0, $nid);
579 // Second step (move to position) if indeed a cid was given
580 if ($cid) {
581 $comment = db_fetch_array(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.picture, u.data, n.title AS node_title FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid INNER JOIN {node} n ON c.nid = n.nid WHERE c.cid = %d AND c.status = 0', $new_cid));
582 $comment['comment_mover'] = COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD;
583 $new_cid = comment_mover_move($comment, $cid, $nid);
584 }
585 comment_mover_unset();
586 drupal_goto('node/'. $nid, NULL, 'comment-'. $new_cid);
587 }
588 }
589 else if ($prune->nid && user_access('administer comments')) {
590 // We're moving a node here
591 // First step - move to node as comment
592 $old_node = node_load($prune->nid);
593 if (node_access('update', $old_node) && comment_mover_allows_pruning('node', $old_node)) {
594 $old_node->comment_mover = COMMENT_MOVER_NODE_TO_COMMENT;
595 $new_cid = comment_mover_move((array) $old_node, 0, $nid);
596 // Second step - move to position - if indeed a cid was given
597 if ($cid) {
598 $comment = db_fetch_array(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.picture, u.data, n.title AS node_title FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid INNER JOIN {node} n ON c.nid = n.nid WHERE c.cid = %d AND c.status = 0', $new_cid));
599 $comment['comment_mover'] = COMMENT_MOVER_COMMENT_TO_COMMENT_SAME_THREAD;
600 $new_cid = comment_mover_move($comment, $cid, $nid);
601 }
602 }
603 comment_mover_unset();
604 drupal_goto('node/'. $nid, NULL, 'comment-'. $new_cid);
605 }
606 }
607
608 drupal_set_message(t('Unable to move the post'));
609 drupal_goto();
610 }
611
612
613 function comment_mover_load_comment($cid) {
614 $comment = db_fetch_object(db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.cid = %d', $cid));
615 $comment = drupal_unpack($comment);
616 $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
617 return $comment;
618 }
619
620 function comment_mover_cancel() {
621 comment_mover_unset();
622 drupal_goto();
623 }
624
625 function comment_mover_unset() {
626 unset($_SESSION['comment_mover']['cid']);
627 unset($_SESSION['comment_mover']['nid']);
628 unset($_SESSION['comment_mover']['pid']);
629 unset($_SESSION['comment_mover']);
630 }
631
632 /**
633 * Returns false when not in 'pruning' mode or an object with cid, pid and nid when pruning
634 *
635 * obj->nid the nid
636 * obj->cid the comment being moved, if 0, obj->nid is moved
637 * obj->pid the comment 'level, used in hook_link
638 */
639 function comment_mover_pruning() {
640 if (isset($_SESSION['comment_mover'])) {
641 $obj = '';
642 $obj->cid = isset($_SESSION['comment_mover']['cid']) ? $_SESSION['comment_mover']['cid'] : FALSE;
643 $obj->nid = isset($_SESSION['comment_mover']['nid']) ? $_SESSION['comment_mover']['nid'] : FALSE;
644 $obj->pid = isset($_SESSION['comment_mover']['pid']) ? $_SESSION['comment_mover']['pid'] : FALSE;
645 return $obj;
646 }
647 return FALSE;
648 }
649
650 /**
651 * Implementation of hook_block; the clipboard
652 *
653 */
654 function comment_mover_block($op = 'list', $delta = 0, $edit = array()) {
655 $block = array();
656 switch ($op) {
657
658 case 'list':
659 $blocks = array();
660 $block[0]= array('info' => t('Comment mover clipboard'));
661 break;
662
663 case 'view':
664 if ($delta == 0) {
665 $block['subject'] = t('Graft');
666 $block['content'] = '';
667 $prune = comment_mover_pruning();
668 if ($prune) {
669 if ($prune->cid) {
670 $comment = comment_mover_load_comment($prune->cid);
671 $block['content'] = theme('comment_mover_block', 'comment', $comment);
672 }
673 else {
674 $node = node_load($prune->nid);
675 $block['content'] = theme('comment_mover_block', 'node', $node);
676 }
677 }
678 }
679 break;
680 }
681 return $block;
682 }
683
684 /**
685 * Theme comment mover block
686 *
687 * @param $op
688 * indicates the type of $object. Possible values, comment, node.
689 * @param $object
690 * the node or comment object
691 *
692 * @return the content of the block
693 */
694 function theme_comment_mover_block($op, $object) {
695 $content = '';
696 if ($op == 'comment') {
697 $content = '<h3>'. check_plain($object->subject) .'</h3>';
698 $content .= t('By !author @date', array('!author' => theme('username', $object), '@date' => format_date($object->timestamp, 'small')));
699 $items[] = l(t('cancel'), 'comment/cancel', NULL, drupal_get_destination());
700 $content .= drupal_get_form('comment_mover_promote_form');
701 $content .= theme('item_list', $items);
702 }
703 else {
704 $content = '<h3>'. check_plain($object->title) .'</h3>';
705 $content .= t('By !author @date', array('!author' => theme('username', $object), '@date' => format_date($object->created, 'small')));
706 $items[] = l(t('cancel'), 'comment/cancel', NULL, drupal_get_destination());
707 $content .= theme('item_list', $items);
708 }
709 return $content;
710 }
711
712 /**
713 * Checks the settings whether the particular node type allows pruning of the node / or comments of the node
714 *
715 * @param $op
716 * determines the type of $object [node, comment]
717 * @param $object
718 * the node / nid or comment object
719 */
720 function comment_mover_allows_pruning($op, $object) {
721 if ($op == 'node') {
722 return variable_get("commentmover_node_{$object->type}", FALSE);
723 }
724 else if ($op == 'comment') {
725 $node = node_load($object->nid);
726 return (variable_get("commentmover_prune_{$node->type}", FALSE) && $node->comment == 2);
727 }
728 }
729
730 /**
731 * Checks the settings whether the node / comment allows grafting (depends on the type of the node/parent node)
732 *
733 * @param $op
734 * determines the type of $object [node, comment]
735 * @param $object
736 * the node or comment object
737 */
738 function comment_mover_allows_grafting($op, $object) {
739 if ($op == 'node') {
740 return variable_get("commentmover_graft_{$object->type}", FALSE);
741 }
742 else if ($op == 'comment') {
743 $node = node_load($object->nid);
744 return (variable_get("commentmover_graft_{$node->type}", FALSE) && $node->comment == 2);
745 }
746 }
747
748
749 //TODO: Rework hook_settings to the new Drupal 5 settings and 'admin/settings' hook_menu entry.
750 /**
751 * Implements hook settings
752 *
753 * - What node types can be pruned
754 * - What node types allow pruning (note: this refers to comments on the node)
755 * - What node types allow grafting
756 */
757 function comment_mover_settings() {
758
759 $form = array();
760
761 // Create the fieldsets holding the checkboxes
762 $form['allow_node_pruning'] = array(
763 '#type' => 'fieldset',
764 '#title' => t('Enable pruning of the following node types'),
765 '#weight' => -8,
766 '#collapsible' => TRUE,
767 '#collapsed' => TRUE,
768 '#description' => t("Define the node types that can be pruned. Note that pruning doesn't make sense for certain node types (poll, for example)."),
769 );
770
771 $form['allow_pruning'] = array(
772 '#type' => 'fieldset',
773 '#title' => t('Enable pruning of comments on the following node types'),
774 '#weight' => -5,
775 '#collapsible' => TRUE,
776 '#collapsed' => TRUE,
777 '#description' => t('Allow comments on these node types to be pruned and moved to other nodes or be promoted to a node.'),
778 );
779
780 $form['allow_grafting'] = array(
781 '#type' => 'fieldset',
782 '#title' => t('Enable grafting on the following node types'),
783 '#weight' => -2,
784 '#collapsible' => TRUE,
785 '#collapsed' => TRUE,
786 '#description' => t('These node types allow grafting of pruned nodes and comments.'),
787 );
788
789 $form['allow_promotion'] = array(
790 '#type' => 'fieldset',
791 '#title' => t('Enable promotion to the following node types'),
792 '#weight' => -2,
793 '#collapsible' => TRUE,
794 '#collapsed' => TRUE,
795 '#description' => t("Comments can be promoted to these nodetypes. Note that this doesn't make sense for certain node types (poll, for example)."),
796 );
797
798 // Generate the node type specific checkboxes per fieldset
799 foreach (node_get_types('types') as $node_type) {
800 $name = $node_type->name;
801 $type = $node_type->type;
802 $form['allow_node_pruning']["commentmover_node_$type"] = array(
803 '#type' => 'checkbox',
804 '#title' => check_plain($name),
805 '#default_value' => variable_get("commentmover_node_$type", FALSE),
806 );
807 $form['allow_pruning']["commentmover_prune_$type"] = array(
808 '#type' => 'checkbox',
809 '#title' => check_plain($name),
810 '#default_value' => variable_get("commentmover_prune_$type", FALSE),
811 );
812 $form['allow_grafting']["commentmover_graft_$type"] = array(
813 '#type' => 'checkbox',
814 '#title' => check_plain($name),
815 '#default_value' => variable_get("commentmover_graft_$type", FALSE),
816 );
817 $form['allow_promotion']["commentmover_promotion_$type"] = array(
818 '#type' => 'checkbox',
819 '#title' => check_plain($name),
820 '#default_value' => variable_get("commentmover_promotion_$type", FALSE),
821 );
822 }
823
824 return system_settings_form($form);
825 }
826
827 /**
828 * Respond to node type changes by updating associated settings.
829 */
830 function comment_mover_node_type($op, $info) {
831 switch ($op){
832 case 'delete':
833 variable_del('commentmover_promotion_'. $info->type);
834 variable_del('commentmover_graft_'. $info->type);
835 variable_del('commentmover_prune_'. $info->type);
836 variable_del('commentmover_node_'. $info->type);
837 break;
838 case 'update':
839 if (!empty($info->old_type) && $info->old_type != $info->type) {
840 variable_set('commentmover_promotion_'. $info->type, variable_get('commentmover_promotion_'. $info->old_type, FALSE));
841 variable_del('commentmover_promotion_'. $info->old_type);
842
843 variable_set('commentmover_graft_'. $info->type, variable_get('commentmover_graft_'. $info->old_type, FALSE));
844 variable_del('commentmover_graft_'. $info->old_type);
845
846 variable_set('commentmover_prune_'. $info->type, variable_get('commentmover_prune_'. $info->old_type, FALSE));
847 variable_del('commentmover_prune_'. $info->old_type);
848
849 variable_set('commentmover_node_'. $info->type, variable_get('commentmover_node_'. $info->old_type, FALSE));
850 variable_del('commentmover_node_'. $info->old_type);
851
852 }
853 break;
854 }
855 }

  ViewVC Help
Powered by ViewVC 1.1.2