| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* Implementation of hook_help().
|
| 6 |
*/
|
| 7 |
function content_moderator_help($section) {
|
| 8 |
switch ($section) {
|
| 9 |
case 'admin/help#content_moderator':
|
| 10 |
$output = '<p>'. t("This module allows users with the 'moderate nodes' permission to view a list of content and move items out of (or into) moderation").'</p>';
|
| 11 |
$output .= '<p>'. t('Users with this permission will also be able to edit nodes without having the moderations setting revert to the default setting for that content type.') .
|
| 12 |
t("For example, if book pages are put in moderation by defualt when created or edited by users, a user with the 'moderate nodes' permission may edit the a book page that has been approved (moved out of moderation) without having it revert to a moderated state").'</p>';
|
| 13 |
return $output;
|
| 14 |
case 'admin/modules#description':
|
| 15 |
return t('Allows a user role to approve content or place it in moderation.');
|
| 16 |
case 'admin/content_moderator':
|
| 17 |
return t('<p>Below is a list of all of the posts. </p><p>Clicking a title views the post, while clicking an author\'s name views their user information.</p>');
|
| 18 |
}
|
| 19 |
}
|
| 20 |
|
| 21 |
/**
|
| 22 |
* Implementation of hook_perm().
|
| 23 |
*/
|
| 24 |
function content_moderator_perm() {
|
| 25 |
return array('moderate nodes');
|
| 26 |
}
|
| 27 |
|
| 28 |
/**
|
| 29 |
* Implementation of hook_menu().
|
| 30 |
*/
|
| 31 |
function content_moderator_menu($may_cache) {
|
| 32 |
$items = array();
|
| 33 |
|
| 34 |
if ($may_cache) {
|
| 35 |
$items[] = array('path' => 'admin/content_moderator', 'title' => t('moderate content'),
|
| 36 |
'callback' => 'moderate_nodes',
|
| 37 |
'access' => (user_access('moderate nodes')),
|
| 38 |
'type' => MENU_NORMAL_ITEM);
|
| 39 |
}
|
| 40 |
return $items;
|
| 41 |
}
|
| 42 |
|
| 43 |
/**
|
| 44 |
* Implementation of hook_nodeapi()
|
| 45 |
*
|
| 46 |
* Used to save/restore the moderation state of a node to keep it from being reset
|
| 47 |
* if a content moderator edits the node.
|
| 48 |
*/
|
| 49 |
function content_moderator_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
|
| 50 |
static $n_moderate=array();
|
| 51 |
|
| 52 |
switch ($op) {
|
| 53 |
case 'submit':
|
| 54 |
if (isset($n_moderate[$node->nid])) { // not set if it's a new node
|
| 55 |
if (user_access('moderate nodes') && !user_access('administer nodes')) {
|
| 56 |
$node->moderate = $n_moderate[$node->nid];
|
| 57 |
}
|
| 58 |
}
|
| 59 |
break;
|
| 60 |
case 'load':
|
| 61 |
$n_moderate=array();
|
| 62 |
$n_moderate[$node->nid]=$node->moderate;
|
| 63 |
break;
|
| 64 |
}
|
| 65 |
}
|
| 66 |
|
| 67 |
/**
|
| 68 |
* List node administration operations that can be performed.
|
| 69 |
*/
|
| 70 |
function content_moderator_operations() {
|
| 71 |
if (user_access('moderate nodes')) {
|
| 72 |
$operations = array(
|
| 73 |
'approve' => array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d'),
|
| 74 |
'remoderate' => array(t('Put the selected posts into moderation'), 'UPDATE {node} SET moderate = 1 WHERE nid = %d'),
|
| 75 |
);
|
| 76 |
}
|
| 77 |
return $operations;
|
| 78 |
}
|
| 79 |
|
| 80 |
/**
|
| 81 |
* List node administration filters that can be applied.
|
| 82 |
*/
|
| 83 |
function content_moderator_filters() {
|
| 84 |
// Regular filters
|
| 85 |
$filters['status'] = array('title' => t('status'),
|
| 86 |
'options' => array('moderate-1' => t('in moderation'), 'moderate-0' => t('not in moderation'),
|
| 87 |
'promote-1' => t('promoted'), 'promote-0' => t('not promoted'),
|
| 88 |
'sticky-1' => t('sticky'), 'sticky-0' => t('not sticky')));
|
| 89 |
$filters['type'] = array('title' => t('type'), 'options' => node_get_types());
|
| 90 |
// The taxonomy filter
|
| 91 |
if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
|
| 92 |
$filters['category'] = array('title' => t('category'), 'options' => $taxonomy);
|
| 93 |
}
|
| 94 |
|
| 95 |
return $filters;
|
| 96 |
}
|
| 97 |
|
| 98 |
/**
|
| 99 |
* Build query for node administration filters based on session.
|
| 100 |
*/
|
| 101 |
function content_moderator_build_filter_query() {
|
| 102 |
$filters = content_moderator_filters();
|
| 103 |
|
| 104 |
// Build query
|
| 105 |
$where = $args = array();
|
| 106 |
$join = '';
|
| 107 |
foreach ($_SESSION['moderate_overview_filter'] as $index => $filter) {
|
| 108 |
list($key, $value) = $filter;
|
| 109 |
switch($key) {
|
| 110 |
case 'status':
|
| 111 |
// Note: no exploitable hole as $key/$value have already been checked when submitted
|
| 112 |
list($key, $value) = explode('-', $value, 2);
|
| 113 |
$where[] = 'n.'. $key .' = %d';
|
| 114 |
break;
|
| 115 |
case 'category':
|
| 116 |
$table = "tn$index";
|
| 117 |
$where[] = "$table.tid = %d";
|
| 118 |
$join .= "INNER JOIN {term_node} $table ON n.nid = $table.nid ";
|
| 119 |
break;
|
| 120 |
case 'type':
|
| 121 |
$where[] = "n.type = '%s'";
|
| 122 |
}
|
| 123 |
$args[] = $value;
|
| 124 |
}
|
| 125 |
$where = 'WHERE n.status = 1 '. (count($where) ? 'AND ' . implode(' AND ', $where) : '');
|
| 126 |
|
| 127 |
return array('where' => $where, 'join' => $join, 'args' => $args);
|
| 128 |
}
|
| 129 |
|
| 130 |
/**
|
| 131 |
* Return form for node administration filters.
|
| 132 |
*/
|
| 133 |
function content_moderator_filter_form() {
|
| 134 |
$session = &$_SESSION['moderate_overview_filter'];
|
| 135 |
$session = is_array($session) ? $session : array();
|
| 136 |
$filters = content_moderator_filters();
|
| 137 |
|
| 138 |
$i = 0;
|
| 139 |
$form['filters'] = array('#type' => 'fieldset',
|
| 140 |
'#title' => t('Show only items where'),
|
| 141 |
'#theme' => 'node_filters',
|
| 142 |
);
|
| 143 |
foreach ($session as $filter) {
|
| 144 |
list($type, $value) = $filter;
|
| 145 |
if ($type == 'category') {
|
| 146 |
// Load term name from DB rather than search and parse options array.
|
| 147 |
$value = module_invoke('taxonomy', 'get_term', $value);
|
| 148 |
$value = $value->name;
|
| 149 |
}
|
| 150 |
else {
|
| 151 |
$value = $filters[$type]['options'][$value];
|
| 152 |
}
|
| 153 |
$string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
|
| 154 |
$form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $value)));
|
| 155 |
}
|
| 156 |
|
| 157 |
foreach ($filters as $key => $filter) {
|
| 158 |
$names[$key] = $filter['title'];
|
| 159 |
$form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']);
|
| 160 |
}
|
| 161 |
|
| 162 |
$form['filters']['filter'] = array('#type' => 'radios', '#options' => $names, '#default_value' => 'status');
|
| 163 |
$form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter')));
|
| 164 |
if (count($session)) {
|
| 165 |
$form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
|
| 166 |
$form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
|
| 167 |
}
|
| 168 |
// use the functions in node.module to display/validate the form
|
| 169 |
return drupal_get_form('moderate_filter_form', $form, 'node_filter_form');
|
| 170 |
}
|
| 171 |
|
| 172 |
/**
|
| 173 |
* Process result from node administration filter form.
|
| 174 |
*/
|
| 175 |
function moderate_filter_form_submit() {
|
| 176 |
global $form_values;
|
| 177 |
$op = $_POST['op'];
|
| 178 |
$filters = content_moderator_filters();
|
| 179 |
switch ($op) {
|
| 180 |
case t('Filter'):
|
| 181 |
case t('Refine'):
|
| 182 |
if (isset($form_values['filter'])) {
|
| 183 |
$filter = $form_values['filter'];
|
| 184 |
|
| 185 |
// Flatten the options array to accommodate hierarchical/nested options.
|
| 186 |
$flat_options = form_options_flatten($filters[$filter]['options']);
|
| 187 |
|
| 188 |
if (isset($flat_options[$form_values[$filter]])) {
|
| 189 |
$_SESSION['moderate_overview_filter'][] = array($filter, $form_values[$filter]);
|
| 190 |
}
|
| 191 |
}
|
| 192 |
break;
|
| 193 |
case t('Undo'):
|
| 194 |
array_pop($_SESSION['moderate_overview_filter']);
|
| 195 |
break;
|
| 196 |
case t('Reset'):
|
| 197 |
$_SESSION['moderate_overview_filter'] = array();
|
| 198 |
break;
|
| 199 |
}
|
| 200 |
}
|
| 201 |
|
| 202 |
/**
|
| 203 |
* Generate the content administration overview.
|
| 204 |
*/
|
| 205 |
function moderate_nodes_submit($form_id, $edit) {
|
| 206 |
$operations = content_moderator_operations();
|
| 207 |
if ($operations[$edit['operation']][1]) {
|
| 208 |
// Flag changes
|
| 209 |
$operation = $operations[$edit['operation']][1];
|
| 210 |
foreach ($edit['nodes'] as $nid => $value) {
|
| 211 |
if ($value) {
|
| 212 |
db_query($operation, $nid);
|
| 213 |
}
|
| 214 |
}
|
| 215 |
drupal_set_message(t('The update has been performed.'));
|
| 216 |
}
|
| 217 |
}
|
| 218 |
|
| 219 |
|
| 220 |
/**
|
| 221 |
* Menu callback: content administration.
|
| 222 |
*/
|
| 223 |
function moderate_nodes() {
|
| 224 |
global $form_values;
|
| 225 |
$output = content_moderator_filter_form();
|
| 226 |
|
| 227 |
$filter = content_moderator_build_filter_query();
|
| 228 |
|
| 229 |
//rewrite the SQL since moderators may only be able to see a subset of content
|
| 230 |
$result = pager_query(db_rewrite_sql('SELECT n.*, u.name, u.uid FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC'), 50, 0, NULL, $filter['args']);
|
| 231 |
|
| 232 |
$form['options'] = array('#type' => 'fieldset',
|
| 233 |
'#title' => t('Update options'),
|
| 234 |
'#prefix' => '<div class="container-inline">',
|
| 235 |
'#suffix' => '</div>',
|
| 236 |
);
|
| 237 |
$form['#theme']='node_admin_nodes';
|
| 238 |
$options = array();
|
| 239 |
foreach (content_moderator_operations() as $key => $value) {
|
| 240 |
$options[$key] = $value[0];
|
| 241 |
}
|
| 242 |
$form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => 'approve');
|
| 243 |
$form['options']['submit'] = array('#type' => 'submit', '#value' => t('Update'));
|
| 244 |
|
| 245 |
$destination = drupal_get_destination();
|
| 246 |
while ($node = db_fetch_object($result)) {
|
| 247 |
$nodes[$node->nid] = '';
|
| 248 |
$form['title'][$node->nid] = array('#value' => l($node->title, 'node/'. $node->nid) .' '. theme('mark', node_mark($node->nid, $node->changed)));
|
| 249 |
$form['name'][$node->nid] = array('#value' => node_get_name($node));
|
| 250 |
$form['username'][$node->nid] = array('#value' => theme('username', $node));
|
| 251 |
$form['status'][$node->nid] = array('#value' => ($node->moderate ? t('in moderation') : t('approved')));
|
| 252 |
if (node_access('update', $node)) {
|
| 253 |
$form['operations'][$node->nid] = array('#value' => l(t('edit'), 'node/'. $node->nid .'/edit', array(), $destination));
|
| 254 |
}
|
| 255 |
else {
|
| 256 |
$form['operations'][$node->nid] = array();
|
| 257 |
}
|
| 258 |
}
|
| 259 |
$form['nodes'] = array('#type' => 'checkboxes', '#options' => $nodes);
|
| 260 |
$form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
|
| 261 |
|
| 262 |
// Call the form first, to allow for the form_values array to be populated.
|
| 263 |
// mostly use the node.module theme functions and validate function
|
| 264 |
$output .= drupal_get_form('moderate_nodes', $form, 'node_admin_nodes');
|
| 265 |
|
| 266 |
return $output;
|
| 267 |
}
|
| 268 |
|
| 269 |
/**
|
| 270 |
* Implementation of hook_block().
|
| 271 |
*/
|
| 272 |
function content_moderator_block($op = 'list', $delta = 0) {
|
| 273 |
if ($op == 'list') {
|
| 274 |
$blocks[0]['info'] = t('Content moderator block');
|
| 275 |
return $blocks;
|
| 276 |
}
|
| 277 |
elseif ($op == 'view') {
|
| 278 |
if (user_access('moderate nodes')){
|
| 279 |
$block['subject'] = t('moderation queue');
|
| 280 |
$count = db_result(db_query(db_rewrite_sql('SELECT COUNT(*) FROM {node} n WHERE n.status = 1 AND n.moderate = 1 ORDER BY n.changed DESC')));
|
| 281 |
$sql = db_rewrite_sql('SELECT n.nid, n.title FROM {node} n WHERE n.status = 1 AND n.moderate = 1 ORDER BY n.changed DESC');
|
| 282 |
$result = db_query_range($sql,0,6);
|
| 283 |
$content = '<p>'. l(t('%items in moderation',array('%items' => format_plural($count, '1 node', '%count nodes'))),'admin/content_moderator'). '</p>';
|
| 284 |
$content .= node_title_list($result, t('Recent additions:'));
|
| 285 |
$block['content'] = $content;
|
| 286 |
return $block;
|
| 287 |
}
|
| 288 |
}
|
| 289 |
}
|
| 290 |
|