/[drupal]/contributions/modules/modr8/modr8_admin.inc
ViewVC logotype

Contents of /contributions/modules/modr8/modr8_admin.inc

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


Revision 1.27 - (show annotations) (download) (as text)
Sun May 17 02:35:53 2009 UTC (6 months, 1 week ago) by pwolanin
Branch: MAIN
CVS Tags: HEAD
Changes since 1.26: +12 -9 lines
File MIME type: text/x-php
#450142 by marcingy & pwolanin, respect nodes per page setting, avoid duplicate query
1 <?php
2 // $Id: modr8_admin.inc,v 1.26 2009/02/23 20:29:15 pwolanin Exp $
3
4 function modr8_settings_form($form_state) {
5
6 $form['modr8_default_option'] = array(
7 '#type' => 'radios',
8 '#title' => t('Default action'),
9 '#options' => array(
10 'approve' => t('approve'),
11 'delete' => t('delete'),
12 'nada' => t('no action'),
13 ),
14 '#default_value' => variable_get('modr8_default_option', 'nada'),
15 );
16
17 $form['modr8_nodes_per_page'] = array(
18 '#type' => 'select',
19 '#title' => t('Number of moderated posts to display per page'),
20 '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 50, 75, 100, 150, 200)),
21 '#default_value' => variable_get('modr8_nodes_per_page', 10),
22 );
23 $period = drupal_map_assoc(array(86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 7257600), 'format_interval');
24 $period[0] = t('Never');
25 $form['modr8_log_clear'] = array(
26 '#type' => 'select',
27 '#title' => t('Discard log entries older than'),
28 '#default_value' => variable_get('modr8_log_clear', 0),
29 '#options' => $period,
30 '#description' => t('The time log entries should be kept. Older entries will be automatically discarded. Requires crontab.')
31 );
32 $form['text'] = array(
33 '#type' => 'fieldset',
34 '#title' => t('E-mail'),
35 );
36
37 $form['text']['modr8_email_from'] = array(
38 '#type' => 'textfield',
39 '#title' => t('Moderator email adress'),
40 '#description' => t('E-mail notices sent by modr8 will have this as the "From" address. Leave empty to use same "From" address as is used for user registration other administrative notices as set at <a href="@site-info">Site information</a>.', array('@site-info' => url('admin/settings/site-information'))),
41 '#default_value' => variable_get('modr8_email_from', ''),
42 );
43
44 $form['text']['modr8_send_approve'] = array(
45 '#type' => 'checkbox',
46 '#title' => t('Send approval messages'),
47 '#default_value' => variable_get('modr8_send_approve', FALSE),
48 );
49
50 $form['text']['modr8_accepted_subject'] = array(
51 '#type' => 'textfield',
52 '#title' => t('Acceptance e-mail subject'),
53 '#default_value' => variable_get('modr8_accepted_subject', "[%site] %title has been approved"),
54 );
55
56 $macros = implode(', ', array_keys(modr8_replacements()));
57
58 $accept_default = modr8_accept_default();
59
60 $form['text']['modr8_accepted_text'] = array(
61 '#type' => 'textarea',
62 '#title' => t('Acceptance e-mail'),
63 '#default_value' => variable_get('modr8_accepted_text', $accept_default),
64 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
65 );
66
67 $form['text']['modr8_send_deny'] = array(
68 '#type' => 'checkbox',
69 '#title' => t('Send denial messages'),
70 '#default_value' => variable_get('modr8_send_deny', FALSE),
71 );
72
73 $form['text']['modr8_denial_subject'] = array(
74 '#type' => 'textfield',
75 '#title' => t('Denial e-mail subject'),
76 '#default_value' => variable_get('modr8_denial_subject', "[%site] %title has been denied"),
77 );
78
79 $denial_default = modr8_denial_default();
80
81 $form['text']['modr8_denial_text'] = array(
82 '#type' => 'textarea',
83 '#title' => t('Denial e-mail'),
84 '#default_value' => variable_get('modr8_denial_text', $denial_default),
85 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
86 );
87
88 $form['text']['modr8_send_noact'] = array(
89 '#type' => 'checkbox',
90 '#title' => t('Send a message when taking no action, but only if the moderator enters a "Note to author".'),
91 '#default_value' => variable_get('modr8_send_noact', FALSE),
92 );
93
94 $form['text']['modr8_noact_subject'] = array(
95 '#type' => 'textfield',
96 '#title' => t('No action e-mail subject'),
97 '#default_value' => variable_get('modr8_noact_subject', "[%site] note to author about %title"),
98 );
99
100 $noact_default = modr8_noact_default();
101
102 $form['text']['modr8_noact_text'] = array(
103 '#type' => 'textarea',
104 '#title' => t('No action e-mail note'),
105 '#default_value' => variable_get('modr8_noact_text', $noact_default),
106 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
107 );
108 $form['#validate'] = array('modr8_settings_validate');
109
110 return system_settings_form($form);
111 }
112
113 function modr8_settings_validate($form, &$form_state) {
114 if ($form_state['values']['modr8_email_from'] && !valid_email_address($form_state['values']['modr8_email_from'])) {
115 form_set_error('modr8_email_from', t('You must either enter a valid e-mail address, or leave the moderator e-mail field empty.'));
116 }
117 }
118
119 /**
120 * Menu callback; the moderation response page.
121 */
122 function modr8_response_page($node) {
123 if ($node->moderate) {
124 drupal_set_title(t('Submit response regarding %title', array('%title' => $node->title)));
125 return drupal_get_form('modr8_response_form', $node);
126 }
127 else {
128 drupal_set_title(t('The moderator already approved %title', array('%title' => $node->title)));
129 return '<p>'. t('This post has already been approved by the moderator. No response is needed.') .'</p>';
130 }
131 }
132
133 function modr8_response_form($form_state, $node) {
134 $form = array();
135 $form['title'] = array(
136 '#type' => 'textfield',
137 '#title' => t('Response title'),
138 '#required' => TRUE,
139 '#maxlength' => 80,
140 '#weight' => -5,
141 );
142 $form['body'] = array(
143 '#type' => 'textarea',
144 '#title' => t('Message to the moderator'),
145 '#description' => t('Please respond to the moderation messsage you received and provide additional information as appropriate to help the moderator.'),
146 '#rows' => 20,
147 '#required' => TRUE,
148 );
149 $form['buttons']['submit'] = array(
150 '#type' => 'submit',
151 '#value' => t('Submit'),
152 '#weight' => 5,
153 );
154 // This flag can be used by modr8, or other modules to change the teaser specifically
155 // for when it's being shown in the moderation list.
156 $node->modr8_form_teaser = TRUE;
157 $teaser = node_view($node, TRUE, FALSE, FALSE);
158 $form['preview'] = array(
159 '#type' => 'value',
160 '#value' => $teaser,
161 );
162 $form['author_uid'] = array(
163 '#type' => 'value',
164 '#value' => $node->uid,
165 );
166 $form['nid'] = array(
167 '#type' => 'value',
168 '#value' => $node->nid,
169 );
170
171 return $form;
172 }
173
174 /**
175 * Form submit handler - log author response.
176 *
177 * @see.modr8_response_form().
178 */
179 function modr8_response_form_submit($form, &$form_state) {
180 $form_state['values']['title'] = check_plain($form_state['values']['title']);
181 $message = filter_xss(nl2br($form_state['values']['body']), array('br'));
182 modr8_log_action('response', $form_state['values']['nid'], $form_state['values'], $message);
183 $form_state['redirect'] = 'node/'. $form_state['values']['nid'];
184 drupal_set_message(t('Your response has been logged.'));
185 }
186
187 /**
188 * Menu callback; displays the content moderation form.
189 */
190 function modr8_page() {
191
192 $is_published = '';
193 if (!user_access('administer nodes')) {
194 // Users who don't have the 'administer nodes' permission can only see published nodes.
195 $is_published = 'n.status = 1 AND ';
196 }
197 $count_sql = db_rewrite_sql('SELECT COUNT(*) FROM {node} n WHERE '. $is_published .' n.moderate = 1');
198 $page_sql = db_rewrite_sql('SELECT n.nid FROM {node} n WHERE '. $is_published .' n.moderate = 1 ORDER BY n.changed DESC');
199 $result = pager_query($page_sql, variable_get('modr8_nodes_per_page', 10), 0, $count_sql);
200 $output = '<p>'. l(t('Show log of all actions on moderated content.'), 'admin/reports/modr8') .'</p>';
201
202 $nid_list = array();
203 while ($r = db_fetch_object($result)) {
204 $nid_list[] = $r->nid;
205 }
206 if ($nid_list) {
207 $output .= drupal_get_form('modr8_form', $nid_list);
208 $output .= theme('pager');
209
210 }
211 else {
212 $output .= '<p>'. t('@items in moderation', array('@items' => format_plural(0, '1 post', '@count posts'))) .'</p>';
213 }
214 return $output;
215 }
216
217 function modr8_form($form_state, $nid_list = array()) {
218 $form = array(
219 '#theme' => 'modr8_form',
220 '#tree' => TRUE,
221 );
222
223 foreach ($nid_list as $nid) {
224 $op_options = array();
225 $node = node_load($nid);
226 // This flag can be used by modr8, or other modules to change the teaser specifically
227 // for when it's being shown in the moderation list.
228 $node->modr8_form_teaser = TRUE;
229 $node->build_mode = NODE_BUILD_MODR8_TEASER;
230 $teaser = node_view($node, TRUE, FALSE, FALSE);
231
232 $form[$node->nid] = array(
233 '#tree' => TRUE,
234 );
235
236 $op_options['approve'] = t('Approve');
237 if (node_access("delete", $node)) {
238 $op_options['delete'] = t('Delete');
239 }
240 $op_options['nada'] = t('No action');
241
242 $form[$node->nid]['ops'] = array(
243 '#type' => 'radios',
244 '#options' => $op_options,
245 '#default_value' => variable_get('modr8_default_option', 'nada'),
246 );
247 if (variable_get('modr8_send_approve', FALSE) || variable_get('modr8_send_deny', FALSE)) {
248 $form[$node->nid]['note'] = array(
249 '#type' => 'textarea',
250 '#title' => t('Note to author'),
251 '#cols' => 15, // keep it narrow
252 );
253 }
254 $form[$node->nid]['preview'] = array(
255 '#type' => 'value',
256 '#value' => $teaser,
257 );
258
259 $log_link = '';
260 $events = db_query("SELECT modid FROM {modr8_log} WHERE nid = %d", $node->nid);
261 $count = db_result(db_query("SELECT COUNT(modid) FROM {modr8_log} WHERE nid = %d", $node->nid));
262 if ($count) {
263 if ($count == 1) {
264 $url = 'admin/reports/modr8/event/'. db_result($events);
265 }
266 else {
267 $url = 'node/'. $node->nid .'/modr8/';
268 }
269 $message = format_plural($count, 'See the 1 moderation log event for this post', 'Overview of the @count moderation log events for this post');
270 $log_link .= l($message, $url);
271 }
272 $form[$node->nid]['log_link'] = array(
273 '#value' => $log_link,
274 );
275 $form[$node->nid]['author_uid'] = array(
276 '#type' => 'value',
277 '#value' => $node->uid,
278 );
279 $form[$node->nid]['title'] = array(
280 '#type' => 'value',
281 '#value' => check_plain($node->title),
282 );
283
284 $form[$node->nid]['type'] = array(
285 '#type' => 'value',
286 '#value' => node_get_types('name', $node),
287 );
288 }
289 $form['submit'] = array(
290 '#type' => 'submit',
291 '#value' => t('Save'),
292 );
293
294 return $form;
295 }
296
297 /**
298 * Themes the content moderation form.
299 */
300 function theme_modr8_form(&$form) {
301 $headers = array(
302 t('Operations'),
303 t('Content')
304 );
305 foreach (element_children($form) as $key) {
306 // Only do this for nodes; not the submit button.
307 if (is_numeric($key)) {
308 $row = array();
309 $note_field = '';
310 if (variable_get('modr8_send_approve', FALSE) || variable_get('modr8_send_deny', FALSE)) {
311 $note_field .= drupal_render($form[$key]['note']);
312 }
313 $row[] = array(
314 'data' => drupal_render($form[$key]['ops']) . $note_field,
315 'style' => 'vertical-align:top;'
316 );
317 // Apply extra filtering to insure we don't have nested form elements,
318 // unexpected script, etc.
319 $preview = filter_xss_admin($form[$key]['preview']['#value']);
320
321 if (!empty($form[$key]['log_link']['#value'])) {
322 $preview .= '<div><em>'. drupal_render($form[$key]['log_link']) .'</em></div>';
323 }
324 $row[] = array(
325 'data' => $preview,
326 'style' => 'vertical-align:top;',
327 );
328 $rows[] = $row;
329 }
330 }
331 $output = theme('table', $headers, $rows);
332 $output .= drupal_render($form);
333
334 return $output;
335 }
336
337 /**
338 * Form submit handler, which approves or deletes the node.
339 */
340 function modr8_form_submit($form, &$form_state) {
341 foreach ($form_state['values'] as $nid => $values) {
342 $message = '';
343 switch ($values['ops']) {
344 case 'approve':
345 if (variable_get('modr8_send_approve', FALSE)) {
346 $message = modr8_usermail('approve', $nid, $values);
347 }
348 $publish = '';
349 if (user_access('administer nodes')) {
350 $publish = ', status = 1';
351 }
352 db_query('UPDATE {node} SET moderate = 0 '. $publish .' WHERE nid = %d', $nid);
353 drupal_set_message(t('The %type with title %title has been approved.', array('%title' => $values['title'], '%type' => $values['type'])));
354 cache_clear_all();
355 modr8_log_action('approve', $nid, $values, $message);
356 break;
357 case 'delete':
358 if (variable_get('modr8_send_deny', FALSE)) {
359 $message = modr8_usermail('deny', $nid, $values);
360 }
361 node_delete($nid);
362 // drupal does its own message
363 modr8_log_action('delete', $nid, $values, $message);
364 break;
365 case 'nada':
366 if (variable_get('modr8_send_noact', FALSE) && !empty($values['note'])) {
367 $message = modr8_usermail('nada', $nid, $values);
368 modr8_log_action('nada', $nid, $values, $message);
369 }
370 break;
371 }
372 }
373 }
374
375 function modr8_log_action($op, $nid, $values, $message) {
376 global $user;
377 $actions = array('approve' => 'Approve', 'delete' => 'Delete', 'nada' => 'No action', 'response' => 'Response');
378
379 db_query("INSERT INTO {modr8_log} (nid, uid, author_uid, action, title, message, teaser, timestamp) VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', %d)", $nid, $user->uid, $values['author_uid'], $actions[$op], $values['title'], $message, $values['preview'], time());
380 // Notify modules interested in each action we took.
381 // modules have to implement the function: hook_modr8_log ( $op ,$nid , $values, $message);
382 module_invoke_all('modr8_log', $op, $nid, $values, $message);
383 }
384
385 function modr8_usermail($op, $nid, $values) {
386 $node = node_load($nid);
387
388 if (is_object($node)) {
389
390 switch ($op) {
391 case 'approve':
392 $subject = variable_get('modr8_accepted_subject', '[%site] %title has been approved');
393 $message = variable_get('modr8_accepted_text', modr8_accept_default());
394 $optype = t('approval');
395 break;
396 case 'deny':
397 $subject = variable_get('modr8_denial_subject', '[%site] %title has been denied');
398 $message = variable_get('modr8_denial_text', modr8_denial_default());
399 $optype = t('denial');
400 break;
401 case 'nada':
402 $subject = variable_get('modr8_noact_subject', "[%site] note to author about %title");
403 $message = variable_get('modr8_noact_text', modr8_noact_default());
404 $optype = t('note (no action)');
405 break;
406 }
407
408 // get the user info for author
409 $account = user_load(array('uid' => $node->uid));
410
411 $note = theme('modr8_note', $values['note']);
412
413 $sendmail_from = '';
414 $site_mail = variable_get('modr8_email_from', '');
415 if (!$site_mail) {
416 $sendmail_from = ini_get('sendmail_from');
417 $site_mail = variable_get('site_mail', $sendmail_from);
418 }
419 if (empty($site_mail) || $site_mail == $sendmail_from) {
420 drupal_set_message(t('You should create an administrator mail address for your site! <a href="@url">Do it here</a>.', array('@url' => url('admin/settings/site-information'))), 'error');
421 }
422 // send the email
423 $language = user_preferred_language($account);
424 $params = array('account' => $account, 'node' => $node, 'subject' => $subject, 'message' => $message, 'note' => $note);
425
426 if ($account->uid == 0) {
427 $message = t('Anonymous user; no %type message was sent.', array('%type' => $optype));
428 }
429 else {
430 $sent = drupal_mail('modr8', 'notify', $account->mail, user_preferred_language($account), $params);
431 if (!empty($sent['result'])) {
432 drupal_set_message(t('%type message was sent to %username', array('%type' => $optype, '%username' => $account->name)));
433 $message = filter_xss(nl2br($sent['body']), array('br', 'a')); // Return sanitized e-mail with HTML breaks added.
434 }
435 else {
436 $message = t('There was a problem sending the %type message to %username', array('%type' => $optype, '%username' => $account->name));
437 drupal_set_message($message, 'error');
438 }
439 }
440 }
441 else {
442 $message = t('An error occurred when trying to load this content.');
443 drupal_set_message($message); // this probably won't ever get called
444 }
445 return $message;
446 }
447
448 /**
449 * Implementation of hook_mail()
450 */
451 function modr8_mail($key, &$message, $params) {
452 $language = $message['language'];
453 $node = $params['node'];
454 $account = $params['account'];
455 $note = $params['note'];
456 switch ($key) {
457 case 'notify':
458 // eval the replacements
459 $replacements_raw = modr8_replacements();
460 foreach ($replacements_raw as $key => $val) {
461 eval('$replacements["$key"] = '. $val .';');
462 }
463 $params['subject'] = strtr($params['subject'], $replacements);
464 $params['message'] = strtr($params['message'], $replacements);
465 $message['subject'] = $params['subject'];
466 $message['body'] = $params['message'];
467 break;
468 }
469 }
470
471 function theme_modr8_note($note) {
472 if ($note) {
473 // Do not filter here (use !) since this note is sanitized after e-mailing
474 $note = t("Note:
475 !note", array('!note' => $note));
476 }
477 return $note;
478 }
479
480 function modr8_replacements() {
481 return array(
482 '%title' => '$node->title',
483 '%teaser' => '$node->teaser',
484 '%body' => '$node->body',
485 '%short_date' => 'format_date($node->created, "short")',
486 '%medium_date' => 'format_date($node->created, "medium")',
487 '%long_date' => 'format_date($node->created, "long")',
488 '%type' => 'node_get_types("name", $node)',
489 '%node_url' => 'url("node/". $node->nid, array("absolute" => TRUE))',
490 '%nid' => '$node->nid',
491 '%author_name' => '$account->name',
492 '%author_mail' => '$account->mail',
493 '%author_url' => 'url("user/". $account->uid, array("absolute" => TRUE))',
494 '%site' => 'variable_get("site_name", "Drupal")',
495 '%note' => '$note',
496 '%response_url' => 'url("node/". $node->nid ."/log/response/". modr8_response_token($node->nid, $account->uid), array("absolute" => TRUE))',
497 );
498 }
499
500 function modr8_accept_default() {
501 return t(
502 'Your %type entry entitled "%title" has been approved by our content moderator! Other visitors to %site will now be able to view it.
503
504 You can visit %node_url to view it yourself.
505
506 %note
507
508 Regards,
509 The %site team');
510 }
511
512 function modr8_denial_default() {
513 return t(
514 'Your %type entry entitled "%title" has been denied by our content moderator. The content has been deleted from our site.
515
516 %note
517
518 Regards,
519 The %site team');
520 }
521
522 function modr8_noact_default() {
523 return t(
524 'Your %type entry entitled "%title" has been reviewed by our content moderator, but not yet approved.
525
526 %note
527
528 To respond to the moderator, you can visit %response_url
529
530 You can visit %node_url to view it yourself, but is is not yet visible to other site visitors.
531
532 Regards,
533 The %site team');
534 }
535
536
537 /**
538 * menu callback for moderation log.
539 */
540 function modr8_log_view($op = '', $id = 0) {
541
542 switch ($op) {
543 case '':
544 return modr8_log_overview();
545 case 'node':
546 if (is_numeric($id)) {
547 $node = node_load($id);
548 if (!empty($node->title)) {
549 drupal_set_title(check_plain($node->title));
550 }
551 return modr8_log_overview($id);
552 }
553 break;
554 case 'event':
555 if (is_numeric($id)) {
556 drupal_set_title(t('Moderation log event'));
557 return modr8_log_event($id);
558
559 }
560 break;
561 }
562 drupal_not_found();
563 }
564
565 function modr8_log_overview($nid = 0) {
566
567 $header = array(
568 array('data' => t('Action'), ),
569 array('data' => t('User'), 'field' => 'u.name'),
570 array('data' => t('Date'), 'field' => 'ml.modid', 'sort' => 'desc'),
571 array('data' => t('Title (view event)')),
572 );
573 $tablesort = tablesort_sql($header);
574
575 $count_sql = "SELECT COUNT(*) FROM {modr8_log} ml";
576 $pager_sql = "SELECT ml.modid, ml.action, ml.title, ml.timestamp, u.name, u.uid FROM {modr8_log} ml LEFT JOIN {users} u ON u.uid = ml.uid";
577 if ($nid) {
578 $count_sql .= " WHERE ml.nid = %d";
579 $pager_sql .= " WHERE ml.nid = %d";
580 }
581 $count_sql = db_rewrite_sql($count_sql, 'ml');
582 $pager_sql = db_rewrite_sql($pager_sql, 'ml');
583 $result = pager_query($pager_sql . $tablesort, 50, 0, $count_sql, $nid);
584
585 $rows = array();
586
587 while ($event = db_fetch_object($result)) {
588 $rows[] = array(t($event->action), theme('username', $event), format_date($event->timestamp, 'small'),
589 l(truncate_utf8($event->title, 50, TRUE, TRUE), 'admin/reports/modr8/event/'. $event->modid, array(), NULL, NULL, FALSE, TRUE)
590 );
591 }
592
593 if (!$rows) {
594 $rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 4));
595 }
596 $output = '';
597 $output .= theme('table', $header, $rows);
598 $output .= theme('pager', NULL, 50, 0);
599
600 return $output;
601 }
602
603 function modr8_log_event($modid) {
604
605 if (is_numeric($modid)) {
606 $sql = db_rewrite_sql("SELECT ml.*, u.name FROM {modr8_log} ml LEFT JOIN {users} u ON u.uid = ml.uid WHERE ml.modid = %d", 'ml');
607 $event = db_fetch_object(db_query($sql, $modid));
608 if ($event) {
609 $event->author = db_fetch_object(db_query("SELECT u.name, u.uid from {users} u WHERE u.uid = %d", $event->author_uid));
610 return theme('moderation_event', $event);
611 }
612 }
613
614 drupal_not_found();
615 }
616
617 function theme_moderation_event($event) {
618
619 $rows[] = array(array('data' => l(t('Overview of all moderation log events for this post'), 'node/'. $event->nid .'/modr8/'), 'colspan' => 2));
620 $rows[] = array(t('Action:'), t($event->action));
621 $rows[] = array(t('Date:'), format_date($event->timestamp, 'small'));
622 if ($event->action == 'Response') {
623 $rows[] = array(t('Author:'), theme('username', $event));
624 $rows[] = array(t('Response title:'), $event->title);
625 $rows[] = array('data' => array(t('Response message:'), $event->message), 'style' => 'vertical-align:top;');
626 $rows[] = array('data' => array(t('Teaser (as of response):'), $event->teaser), 'style' => 'vertical-align:top;');
627 }
628 else {
629 $rows[] = array(t('Moderator:'), theme('username', $event));
630 $rows[] = array('data' => array(t('E-mail message:'), $event->message), 'style' => 'vertical-align:top;');
631 $rows[] = array(t('Author:'), theme('username', $event->author));
632 $rows[] = array('data' => array(t('Teaser (as reviewed):'), $event->teaser), 'style' => 'vertical-align:top;');
633 }
634
635 return theme('table', NULL, $rows);
636 }

  ViewVC Help
Powered by ViewVC 1.1.2