| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
//Set of content status
|
| 5 |
define('ABUSE_LIVE', 0);
|
| 6 |
define('ABUSE_PENDING', 1);
|
| 7 |
define('ABUSE_HIDDEN', 2);
|
| 8 |
define('ABUSE_REMOVED', 3);
|
| 9 |
define('ABUSE_SUPERADMIN', 4);
|
| 10 |
|
| 11 |
//Set of content allowed for abuse flagging
|
| 12 |
define('ABUSE_CONTENT_NODE_TYPE', 'abuse_content_node_type_');
|
| 13 |
define('ABUSE_CONTENT_COMMENTS', 'abuse_content_comments');
|
| 14 |
define('ABUSE_CONTENT_USERS', 'abuse_content_users');
|
| 15 |
|
| 16 |
//Set of permissions
|
| 17 |
define('REPORT_ABUSE', 'report abuse');
|
| 18 |
define('ADMINISTER_ABUSE_REPORTS', 'administer abuse reports');
|
| 19 |
define('CONFIGURE_ABUSE_SETTINGS', 'configure abuse administration settings');
|
| 20 |
define('DIRECT_FLAG', 'direct flag');
|
| 21 |
define('ADMINISTER_ALL_ABUSE_REPORTS', 'administer all abuse reports');
|
| 22 |
|
| 23 |
/**
|
| 24 |
* Implementation of Drupal Hooks
|
| 25 |
*/
|
| 26 |
|
| 27 |
/**
|
| 28 |
* Implementation of hook_perm
|
| 29 |
*/
|
| 30 |
function abuse_perm() {
|
| 31 |
return array(REPORT_ABUSE, DIRECT_FLAG, ADMINISTER_ABUSE_REPORTS, ADMINISTER_ALL_ABUSE_REPORTS, CONFIGURE_ABUSE_SETTINGS);
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
| 35 |
* Implementation of access controls
|
| 36 |
*/
|
| 37 |
function abuse_access() {
|
| 38 |
$args = func_num_args();
|
| 39 |
if ($args < 1) {
|
| 40 |
return user_access(ADMINISTER_ALL_ABUSE_REPORTS);
|
| 41 |
} else {
|
| 42 |
$perms = func_get_args();
|
| 43 |
for ($i = 0; $i < $args; $i++) {
|
| 44 |
if (user_access($perms[$i])) {
|
| 45 |
return TRUE;
|
| 46 |
}
|
| 47 |
}
|
| 48 |
}
|
| 49 |
return FALSE;
|
| 50 |
}
|
| 51 |
|
| 52 |
/**
|
| 53 |
* Implementation of more complex controls to swtich between old admin system and new ticketing system
|
| 54 |
*/
|
| 55 |
function abuse_moderation_system_access($perms, $old_system = FALSE) {
|
| 56 |
if ($old_system && variable_get('abuse_assigned_moderators', FALSE)) {
|
| 57 |
return FALSE;
|
| 58 |
} else if (!$old_system && !variable_get('abuse_assigned_moderators', FALSE)) {
|
| 59 |
return FALSE;
|
| 60 |
} else {
|
| 61 |
return abuse_access($perms);
|
| 62 |
}
|
| 63 |
}
|
| 64 |
|
| 65 |
/**
|
| 66 |
* Implementation of hook_help
|
| 67 |
*/
|
| 68 |
function abuse_help($section) {
|
| 69 |
switch ($section) {
|
| 70 |
case 'admin/help#abuse':
|
| 71 |
case 'admin/modules#description':
|
| 72 |
return t('allow users to report abusive content');
|
| 73 |
break;
|
| 74 |
}
|
| 75 |
}
|
| 76 |
|
| 77 |
/**
|
| 78 |
* Implementation of hook_menu
|
| 79 |
*/
|
| 80 |
function abuse_menu() {
|
| 81 |
//Initial setup work
|
| 82 |
$flagger = array(REPORT_ABUSE, DIRECT_FLAG);
|
| 83 |
$admin = array(ADMINISTER_ABUSE_REPORTS, ADMINISTER_ALL_ABUSE_REPORTS);
|
| 84 |
$superadmin = array(ADMINISTER_ALL_ABUSE_REPORTS);
|
| 85 |
$configure = array(CONFIGURE_ABUSE_SETTINGS);
|
| 86 |
$items = array();
|
| 87 |
// Regular flagging
|
| 88 |
$items['abuse/report/%/%'] = array(
|
| 89 |
'title' => 'Flag',
|
| 90 |
'page callback' => 'abuse_report',
|
| 91 |
'page arguments' => array(2, 3),
|
| 92 |
'access callback' => 'abuse_access',
|
| 93 |
'access arguments' => $flagger,
|
| 94 |
'type' => MENU_CALLBACK,
|
| 95 |
);
|
| 96 |
|
| 97 |
// Abuse system settings
|
| 98 |
$items['admin/settings/abuse'] = array(
|
| 99 |
'title' => 'Abuse Moderation settings',
|
| 100 |
'description' => 'Configure the various parts in moderation',
|
| 101 |
'page callback' => 'drupal_get_form',
|
| 102 |
'page arguments' => array('abuse_admin_settings'),
|
| 103 |
'access callback' => 'user_access',
|
| 104 |
'access arguments' => array(CONFIGURE_ABUSE_SETTINGS),
|
| 105 |
'file' => 'abuse.admin.inc',
|
| 106 |
);
|
| 107 |
$items['admin/settings/abuse/reasons'] = array(
|
| 108 |
'title' => 'Abuse Moderation reasons',
|
| 109 |
'description' => 'Add, edit, or remove reasons for flagging content',
|
| 110 |
'page callback' => 'drupal_get_form',
|
| 111 |
'page arguments' => array('abuse_admin_reason_settings'),
|
| 112 |
'file' => 'abuse.admin.inc',
|
| 113 |
);
|
| 114 |
$items['admin/settings/abuse/reasons/edit/%'] = array(
|
| 115 |
'title' => 'Edit reason',
|
| 116 |
'description' => 'Edit a reason with a provided ID',
|
| 117 |
'page callback' => 'drupal_get_form',
|
| 118 |
'page arguments' => array('abuse_admin_edit_reason', 5),
|
| 119 |
'file' => 'abuse.admin.inc',
|
| 120 |
'type' => MENU_CALLBACK
|
| 121 |
);
|
| 122 |
|
| 123 |
// Callback admin functions
|
| 124 |
$items['admin/abuse/content/moderate/%/%'] = array(
|
| 125 |
'title' => 'Moderate content',
|
| 126 |
'page callback' => 'drupal_get_form',
|
| 127 |
'page arguments' => array('abuse_admin_moderate_content', 4, 5),
|
| 128 |
'access callback' => 'abuse_access',
|
| 129 |
'access arguments' => $admin,
|
| 130 |
'file' => 'abuse.admin.inc',
|
| 131 |
'type' => MENU_CALLBACK,
|
| 132 |
);
|
| 133 |
|
| 134 |
$items['admin/abuse/moderate/content/js'] = array(
|
| 135 |
'page callback' => 'abuse_admin_moderate_content_js',
|
| 136 |
'access callback' => 'abuse_access',
|
| 137 |
'access arguments' => $admin,
|
| 138 |
'file' => 'abuse.admin.inc',
|
| 139 |
'type' => MENU_CALLBACK,
|
| 140 |
);
|
| 141 |
|
| 142 |
|
| 143 |
$items['admin/abuse/ban/%user'] = array(
|
| 144 |
'title' => 'Warn user',
|
| 145 |
'page callback' => 'drupal_get_form',
|
| 146 |
'page arguments' => array('abuse_admin_ban', 3),
|
| 147 |
'access callback' => 'abuse_access',
|
| 148 |
'access arguments' => $admin,
|
| 149 |
'file' => 'abuse.admin.inc',
|
| 150 |
'type' => MENU_CALLBACK,
|
| 151 |
);
|
| 152 |
|
| 153 |
//Moderation functions
|
| 154 |
$items['admin/content/abuse/pending'] = array(
|
| 155 |
'title' => 'Pending Items (!num)',
|
| 156 |
'title callback' => 'abuse_title_callback',
|
| 157 |
'title arguments' => array('Pending Items (!num)', array(ABUSE_PENDING)),
|
| 158 |
'page callback' => 'abuse_admin_moderate',
|
| 159 |
'page arguments' => array(array(ABUSE_PENDING)),
|
| 160 |
'access callback' => 'abuse_moderation_system_access',
|
| 161 |
'access arguments' => array($admin, TRUE),
|
| 162 |
'file' => 'abuse.admin.inc',
|
| 163 |
'weight' => 0,
|
| 164 |
'type' => MENU_DEFAULT_LOCAL_TASK,
|
| 165 |
);
|
| 166 |
$items['admin/content/abuse/hidden'] = array(
|
| 167 |
'title callback' => 'abuse_title_callback',
|
| 168 |
'title arguments' => array('Hidden Items (!num)', array(ABUSE_HIDDEN)),
|
| 169 |
'page callback' => 'abuse_admin_moderate',
|
| 170 |
'page arguments' => array(array(ABUSE_HIDDEN)),
|
| 171 |
'access callback' => 'abuse_moderation_system_access',
|
| 172 |
'access arguments' => array($admin, TRUE),
|
| 173 |
'file' => 'abuse.admin.inc',
|
| 174 |
'weight' => 1,
|
| 175 |
'type' => MENU_LOCAL_TASK
|
| 176 |
);
|
| 177 |
$items['admin/content/abuse/removed'] = array(
|
| 178 |
'title callback' => 'abuse_title_callback',
|
| 179 |
'title arguments' => array('Removed Items (!num)', array(ABUSE_REMOVED)),
|
| 180 |
'page callback' => 'abuse_admin_moderate',
|
| 181 |
'page arguments' => array(array(ABUSE_REMOVED)),
|
| 182 |
'access callback' => 'abuse_moderation_system_access',
|
| 183 |
'access arguments' => array($admin, TRUE),
|
| 184 |
'file' => 'abuse.admin.inc',
|
| 185 |
'weight' => 2,
|
| 186 |
'type' => MENU_LOCAL_TASK,
|
| 187 |
);
|
| 188 |
|
| 189 |
$items['admin/content/abuse/assigned'] = array(
|
| 190 |
'title' => 'Removed Items (!num of !num2)',
|
| 191 |
'title callback' => 'abuse_title_assigned_callback',
|
| 192 |
'title arguments' => array('Assigned Items (!assigned of !remaining)'),
|
| 193 |
'page callback' => 'abuse_admin_moderate',
|
| 194 |
'page arguments' => array(array(ABUSE_PENDING, ABUSE_HIDDEN), TRUE),
|
| 195 |
'access callback' => 'abuse_moderation_system_access',
|
| 196 |
'access arguments' => array($admin, FALSE),
|
| 197 |
'file' => 'abuse.admin.inc',
|
| 198 |
'weight' => 0,
|
| 199 |
'type' => MENU_DEFAULT_LOCAL_TASK,
|
| 200 |
);
|
| 201 |
$items['admin/content/abuse/remaining'] = array(
|
| 202 |
'title callback' => 'abuse_title_callback',
|
| 203 |
'title arguments' => array('Remaining Items (!num)', array(ABUSE_PENDING, ABUSE_HIDDEN)),
|
| 204 |
'page callback' => 'abuse_admin_moderate',
|
| 205 |
'page arguments' => array(array(ABUSE_PENDING, ABUSE_HIDDEN)),
|
| 206 |
'access callback' => 'abuse_moderation_system_access',
|
| 207 |
'access arguments' => array($superadmin, FALSE),
|
| 208 |
'file' => 'abuse.admin.inc',
|
| 209 |
'weight' => 1,
|
| 210 |
'type' => MENU_LOCAL_TASK,
|
| 211 |
);
|
| 212 |
|
| 213 |
$items['admin/content/abuse'] = array(
|
| 214 |
'title' => 'Moderate',
|
| 215 |
'description' => 'Manage items that were either flagged by the system or by other users',
|
| 216 |
'page callback' => 'abuse_admin_default_callback',
|
| 217 |
'access callback' => 'abuse_access',
|
| 218 |
'access arguments' => $admin,
|
| 219 |
'file' => 'abuse.admin.inc',
|
| 220 |
);
|
| 221 |
|
| 222 |
$items['admin/abuse/status/%/%'] = array(
|
| 223 |
'title' => 'History',
|
| 224 |
'description' => 'Check the status of a particular item',
|
| 225 |
'page callback' => 'abuse_admin_status',
|
| 226 |
'page arguments' => array(3, 4),
|
| 227 |
'access callback' => 'abuse_access',
|
| 228 |
'access arguments' => $admin,
|
| 229 |
'file' => 'abuse.admin.inc'
|
| 230 |
);
|
| 231 |
return $items;
|
| 232 |
}
|
| 233 |
|
| 234 |
/**
|
| 235 |
* Implementation of hook_theme
|
| 236 |
*/
|
| 237 |
function abuse_theme() {
|
| 238 |
$theme = array();
|
| 239 |
$theme['abuse_page'] = array(
|
| 240 |
'template' => 'abuse-page',
|
| 241 |
'file' => 'abuse.admin.inc',
|
| 242 |
'arguments' => array(
|
| 243 |
'reports' => array(),
|
| 244 |
),
|
| 245 |
);
|
| 246 |
$theme['abuse_report'] = array(
|
| 247 |
'template' => 'abuse-report',
|
| 248 |
'file' => 'abuse.admin.inc',
|
| 249 |
'arguments' => array(
|
| 250 |
'object' => NULL,
|
| 251 |
),
|
| 252 |
);
|
| 253 |
return $theme;
|
| 254 |
}
|
| 255 |
|
| 256 |
/**
|
| 257 |
* Implementation of hook_cron
|
| 258 |
*/
|
| 259 |
function abuse_cron() {
|
| 260 |
$hour = variable_get('abuse_cleanup_hour', 0);
|
| 261 |
$hour = max(0, $hour);
|
| 262 |
$hour = min(23, $hour);
|
| 263 |
$time = time() - ($hour * 3600);
|
| 264 |
$timestamp = getdate($time);
|
| 265 |
$timestamp = mktime(0, 0, 0, $timestamp['mon'], $timestamp['mday'], $timestamp['year']);
|
| 266 |
|
| 267 |
$last_time = variable_get('abuse_cleanup_timestamp', 0);
|
| 268 |
if ($timestamp > $last_time) {
|
| 269 |
db_query('UPDATE {abuse_status} SET assigned_to_uid=0 WHERE status=%d OR status=%d OR status=%d', ABUSE_PENDING, ABUSE_HIDDEN, ABUSE_SUPERADMIN);
|
| 270 |
variable_set('abuse_cleanup_timestamp', $timestamp);
|
| 271 |
}
|
| 272 |
}
|
| 273 |
|
| 274 |
/**
|
| 275 |
* Implementation of hook_link
|
| 276 |
*/
|
| 277 |
function abuse_link($type, $object, $teaser) {
|
| 278 |
global $user;
|
| 279 |
$links = array();
|
| 280 |
if ($object && $user && $user->uid == $object->uid) {
|
| 281 |
// Don't want user to flag their own content
|
| 282 |
return $$links;
|
| 283 |
}
|
| 284 |
if ($type == 'node' && !$teaser) {
|
| 285 |
if (user_access(ADMINISTER_ABUSE_REPORTS)) {
|
| 286 |
$links['abuse_node_history'] = array(
|
| 287 |
'title' => t('View abuse history'),
|
| 288 |
'href' => 'admin/abuse/content/moderate/node/'. $object->nid,
|
| 289 |
'attributes' => array('class' => 'node-history'),
|
| 290 |
);
|
| 291 |
}
|
| 292 |
if (variable_get(ABUSE_CONTENT_NODE_TYPE . $object->type, 0) && (user_access(REPORT_ABUSE) || user_access(DIRECT_FLAG))) {
|
| 293 |
if ($user->uid && ($user->uid != $object->uid)) {
|
| 294 |
$already_reported_check = db_result(db_query("SELECT COUNT(*) FROM {abuse} WHERE type='%s' AND oid=%d AND uid=%d", $type, $object->nid, $user->uid));
|
| 295 |
if ($already_reported_check > 0) {
|
| 296 |
// $links['abuse_already_flagged'] = array(
|
| 297 |
// 'title' => t('This content is currently under review'),
|
| 298 |
// );
|
| 299 |
}
|
| 300 |
else {
|
| 301 |
$links['abuse_flag_node'] = array(
|
| 302 |
'title' => t('Flag as offensive'),
|
| 303 |
'href' => 'abuse/report/node/'. $object->nid,
|
| 304 |
'attributes' => array('class' => 'flag-content',
|
| 305 |
'title' => t('Notify administrators of problematic content')
|
| 306 |
)
|
| 307 |
);
|
| 308 |
}
|
| 309 |
}
|
| 310 |
else {
|
| 311 |
$links['abuse_flag_node'] = array(
|
| 312 |
'title' => t('Flag as offensive'),
|
| 313 |
'href' => 'abuse/report/node/'. $object->nid,
|
| 314 |
'attributes' => array('class' => 'flag-content',
|
| 315 |
'title' => t('Notify administrators of problematic content')
|
| 316 |
)
|
| 317 |
);
|
| 318 |
}
|
| 319 |
}
|
| 320 |
}
|
| 321 |
elseif ($type == 'comment' &&
|
| 322 |
variable_get(ABUSE_CONTENT_COMMENTS, 0) &&
|
| 323 |
(user_access(REPORT_ABUSE) || user_access(DIRECT_FLAG))) {
|
| 324 |
if (user_access(ADMINISTER_ABUSE_REPORTS)) {
|
| 325 |
$links['abuse_comment_history'] = array(
|
| 326 |
'title' => t('View abuse history'),
|
| 327 |
'href' => 'admin/abuse/content/moderate/comment/'. $object->cid,
|
| 328 |
'attributes' => array('class' => 'node-history'),
|
| 329 |
);
|
| 330 |
}
|
| 331 |
if ($user->uid && ($user->uid != $object->uid)) {
|
| 332 |
$already_reported_check = db_result(db_query("SELECT COUNT(*) FROM {abuse} WHERE type='%s' AND oid=%d AND uid=%d", $type, $object->cid, $user->uid));
|
| 333 |
if ($already_reported_check > 0) {
|
| 334 |
// $links['abuse_already_flagged'] = array(
|
| 335 |
// 'title' => t('This comment is currently under review'),
|
| 336 |
// );
|
| 337 |
}
|
| 338 |
else {
|
| 339 |
$links['abuse_flag_comment'] = array(
|
| 340 |
'title' => t('Flag as offensive'),
|
| 341 |
'href' => 'abuse/report/comment/'. $object->cid,
|
| 342 |
'attributes' => array('class' => 'flag-content',
|
| 343 |
'title' => t('Notify administrators of problematic comment')
|
| 344 |
)
|
| 345 |
);
|
| 346 |
}
|
| 347 |
}
|
| 348 |
else {
|
| 349 |
$links['abuse_flag_comment'] = array(
|
| 350 |
'title' => t('Flag as offensive'),
|
| 351 |
'href' => 'abuse/report/comment/'. $object->cid,
|
| 352 |
'attributes' => array('class' => 'flag-content',
|
| 353 |
'title' => t('Notify administrators of problematic comment')
|
| 354 |
)
|
| 355 |
);
|
| 356 |
}
|
| 357 |
}
|
| 358 |
return $links;
|
| 359 |
}
|
| 360 |
|
| 361 |
/**
|
| 362 |
* Implementation of hook_forms
|
| 363 |
*/
|
| 364 |
function abuse_forms() {
|
| 365 |
$args = func_get_args();
|
| 366 |
$form_id = $args[0];
|
| 367 |
|
| 368 |
$forms = array();
|
| 369 |
if (strpos($form_id, "abuse_admin_warn") === 0) {
|
| 370 |
$forms[$form_id] = array('callback' => 'abuse_admin_warn');
|
| 371 |
}
|
| 372 |
if (strpos($form_id, "abuse_admin_ban") === 0) {
|
| 373 |
$forms[$form_id] = array('callback' => 'abuse_admin_ban');
|
| 374 |
}
|
| 375 |
if (strpos($form_id, "abuse_admin_moderate_content") === 0) {
|
| 376 |
$forms[$form_id] = array('callback' => 'abuse_admin_moderate_content');
|
| 377 |
}
|
| 378 |
return $forms;
|
| 379 |
}
|
| 380 |
|
| 381 |
/**
|
| 382 |
* Implementation of abuse specific functions
|
| 383 |
*/
|
| 384 |
function abuse_title_callback($title, $type = array()) {
|
| 385 |
return t($title, array('!num' => _abuse_get_tallied_count($type)));
|
| 386 |
}
|
| 387 |
|
| 388 |
function abuse_title_assigned_callback($title) {
|
| 389 |
$assigned = _abuse_get_assigned_count(FALSE);
|
| 390 |
$remaining = _abuse_get_assigned_pending_count(FALSE);
|
| 391 |
return t($title, array('!assigned' => $assigned, '!remaining' => $remaining));
|
| 392 |
}
|
| 393 |
|
| 394 |
/**
|
| 395 |
* Flag content on the site - first check if it is a valid item that can be flagged. If so, return the form.
|
| 396 |
*/
|
| 397 |
function abuse_report($type, $oid) {
|
| 398 |
global $user;
|
| 399 |
|
| 400 |
if (empty($type) || empty($oid)) {
|
| 401 |
return drupal_not_found();
|
| 402 |
}
|
| 403 |
|
| 404 |
$object = _abuse_load($type, $oid);
|
| 405 |
if (empty($object)) {
|
| 406 |
return drupal_not_found();
|
| 407 |
} elseif ($object->uid === $user->uid) {
|
| 408 |
drupal_set_message(t('Sorry, you cannot flag your own content'));
|
| 409 |
drupal_goto($object->path['URL'], $object->path['QUERY'], $object->path['BREADCRUMB']);
|
| 410 |
} elseif ($type === 'node' && variable_get(ABUSE_CONTENT_NODE_TYPE . $object->content_type, 0) === 0) {
|
| 411 |
drupal_set_message(t('Sorry, you are not allowed to flag this content'));
|
| 412 |
drupal_goto($object->path['URL'], $object->path['QUERY'], $object->path['BREADCRUMB']);
|
| 413 |
}
|
| 414 |
return drupal_get_form('abuse_report_form', $object, $user);
|
| 415 |
}
|
| 416 |
|
| 417 |
function abuse_report_form($form_state, $object, $user) {
|
| 418 |
$form = array();
|
| 419 |
$form['object_type'] = array(
|
| 420 |
'#type' => 'value',
|
| 421 |
'#value' => $object->type
|
| 422 |
);
|
| 423 |
$form['object_oid'] = array(
|
| 424 |
'#type' => 'value',
|
| 425 |
'#value' => $object->oid
|
| 426 |
);
|
| 427 |
if ($user->uid) {
|
| 428 |
$form['user'] = array(
|
| 429 |
'#type' => 'item',
|
| 430 |
'#title' => t('from'),
|
| 431 |
'#value' => $user->name
|
| 432 |
);
|
| 433 |
$form['name'] = array(
|
| 434 |
'#type' => 'value',
|
| 435 |
'#value' => $user->name
|
| 436 |
);
|
| 437 |
$form['mail'] = array(
|
| 438 |
'#type' => 'value',
|
| 439 |
'#value' => $user->mail
|
| 440 |
);
|
| 441 |
}
|
| 442 |
else {
|
| 443 |
$form['name'] = array(
|
| 444 |
'#type' => 'textfield',
|
| 445 |
'#title' => t('from'),
|
| 446 |
'#size' => 30,
|
| 447 |
'#maxlength' => 30,
|
| 448 |
'#required' => TRUE
|
| 449 |
);
|
| 450 |
$form['mail'] = array(
|
| 451 |
'#type' => 'textfield',
|
| 452 |
'#title' => t('email'),
|
| 453 |
'#size' => 30,
|
| 454 |
'#maxlength' => 30,
|
| 455 |
'#required' => TRUE
|
| 456 |
);
|
| 457 |
}
|
| 458 |
$form['about'] = array(
|
| 459 |
'#type' => 'item',
|
| 460 |
'#title' => t('about'),
|
| 461 |
'#value' => $object->title
|
| 462 |
);
|
| 463 |
$reason_objects = _abuse_reasons();
|
| 464 |
$reasons = array(0 => '');
|
| 465 |
foreach ($reason_objects as $reason) {
|
| 466 |
$reasons[$reason->arid] = t($reason->reason);
|
| 467 |
}
|
| 468 |
$form['reason'] = array(
|
| 469 |
'#type' => 'select',
|
| 470 |
'#title' => t('reason'),
|
| 471 |
'#options' => $reasons,
|
| 472 |
'#required' => TRUE
|
| 473 |
);
|
| 474 |
$form['body'] = array(
|
| 475 |
'#type' => 'textarea',
|
| 476 |
'#title' => t('message'),
|
| 477 |
'#cols' => 30,
|
| 478 |
'#rows' => 10
|
| 479 |
);
|
| 480 |
$form['op']['send'] = array(
|
| 481 |
'#type' => 'submit',
|
| 482 |
'#value' => t('send')
|
| 483 |
);
|
| 484 |
$form['op']['cancel'] = array(
|
| 485 |
'#type' => 'submit',
|
| 486 |
'#value' => t('cancel')
|
| 487 |
);
|
| 488 |
return $form;
|
| 489 |
}
|
| 490 |
|
| 491 |
function abuse_report_form_validate($form, &$form_state) {
|
| 492 |
$form_values = $form_state['values'];
|
| 493 |
if ($form_state['clicked_button']['#value'] == t('send')) {
|
| 494 |
if (empty($form_values['name'])) {
|
| 495 |
form_set_error('name', t('<em>!field</em> is required', array('!field' => t('from'))));
|
| 496 |
}
|
| 497 |
if (empty($form_values['mail']) || !valid_email_address($form_values['mail'])) {
|
| 498 |
form_set_error('mail', t('A valid email address is required.'));
|
| 499 |
}
|
| 500 |
if (empty($form_values['reason'])) {
|
| 501 |
form_set_error('reason', t('Please give a reason.'));
|
| 502 |
}
|
| 503 |
$body = trim(strtolower($form_values['body']));
|
| 504 |
if (empty($body)) {
|
| 505 |
form_set_error('body', t('Please provide a more detailed description - no links please.'));
|
| 506 |
} elseif(
|
| 507 |
strpos($body, 'href=') !== FALSE ||
|
| 508 |
strpos($body, 'url=') !== FALSE ||
|
| 509 |
strpos($body, 'http://') !== FALSE
|
| 510 |
) {
|
| 511 |
form_set_error('body', t('Please do not use links in your description of the problem.'));
|
| 512 |
}
|
| 513 |
}
|
| 514 |
}
|
| 515 |
|
| 516 |
function abuse_report_form_submit($form, &$form_state) {
|
| 517 |
global $user;
|
| 518 |
$form_values = $form_state['values'];
|
| 519 |
$form_values['op'] = $form_state['clicked_button']['#value'];
|
| 520 |
$oid = $form_values['object_oid'];
|
| 521 |
$type = $form_values['object_type'];
|
| 522 |
$object = _abuse_load($type, $oid);
|
| 523 |
$reason = db_result(db_query("SELECT reason FROM {abuse_reasons} WHERE arid=%d", $form_values['reason']));
|
| 524 |
if (!$object) {
|
| 525 |
drupal_not_found();
|
| 526 |
}
|
| 527 |
// Object was found - system is alright from this point
|
| 528 |
$form_state['redirect'] = array($object->path['URL'], $object->path['QUERY'], $object->path['BREADCRUMB']);
|
| 529 |
$errors = ($form_values['op'] == t('cancel')) ? TRUE : FALSE;
|
| 530 |
if ($user->uid) {
|
| 531 |
if (db_result(db_query("SELECT COUNT(*) FROM {abuse} WHERE type='%s' AND oid=%d AND uid=%d", $type, $oid, $user->uid)) > 0) {
|
| 532 |
drupal_set_message(t('We have already received your report. Thank you very much!'));
|
| 533 |
$errors = TRUE;
|
| 534 |
}
|
| 535 |
|
| 536 |
// ENSURE USER IS NOT TRYING TO FLAG OWN CONTENT
|
| 537 |
if ($user->uid == $object->uid) {
|
| 538 |
drupal_set_message(t('You cannot flag your own content'));
|
| 539 |
$errors = TRUE;
|
| 540 |
}
|
| 541 |
}
|
| 542 |
|
| 543 |
if (!$errors) {
|
| 544 |
db_query("INSERT INTO {abuse} (type, oid, created, body, reason, uid, name, mail) VALUES ('%s', %d, %d, '%s', '%s', %d, '%s', '%s')",
|
| 545 |
$type, $oid, time(), $form_values['body'], $form_values['reason'], $user->uid, $form_values['name'], $form_values['mail']);
|
| 546 |
_abuse_set_status($type, $oid, ABUSE_PENDING);
|
| 547 |
$result = _abuse_disable($type, $oid);
|
| 548 |
// Call the sequencer for sequencing content
|
| 549 |
if ($result) {
|
| 550 |
drupal_set_message(t('Thank you for your report. We will look into this shortly.'));
|
| 551 |
$form_state['redirect'] = '';
|
| 552 |
}
|
| 553 |
else {
|
| 554 |
drupal_set_message(t('Thank you for your report.'));
|
| 555 |
}
|
| 556 |
}
|
| 557 |
}
|
| 558 |
|
| 559 |
/**
|
| 560 |
* PRIVATE FUNCTIONS
|
| 561 |
*/
|
| 562 |
|
| 563 |
/**
|
| 564 |
* Load an Abuse Object
|
| 565 |
*/
|
| 566 |
function _abuse_load($obj, $second_value = NULL) {
|
| 567 |
if ($second_value !== NULL) {
|
| 568 |
$object->type = $type = $obj;
|
| 569 |
$object->oid = $oid = $second_value;
|
| 570 |
} else {
|
| 571 |
$object->type = $type = $obj->type;
|
| 572 |
$object->oid = $oid = $obj->oid;
|
| 573 |
$object->abuse_status_number = $obj->status;
|
| 574 |
$object->abuse_status_string = _abuse_retrieve_status($object->abuse_status_number);
|
| 575 |
$object->abuse_assigned_to_uid = $obj->assigned_to_uid;
|
| 576 |
$object->abuse_assigned_to_name = db_result(db_query("SELECT name FROM {users} WHERE uid=%d", $object->abuse_assigned_to_uid));
|
| 577 |
if (!$object->abuse_assigned_to_name) {
|
| 578 |
$object->abuse_assigned_to_name = 'N/A';
|
| 579 |
}
|
| 580 |
}
|
| 581 |
switch ($type) {
|
| 582 |
case 'node' :
|
| 583 |
$node = node_load(array('nid' => $oid));
|
| 584 |
if (!$node->nid) {
|
| 585 |
return false;
|
| 586 |
}
|
| 587 |
$formatted_body = check_markup($node->body, $node->format, FALSE);
|
| 588 |
$object->title = $node->title;
|
| 589 |
$object->uid = $node->uid;
|
| 590 |
$object->name = $node->name;
|
| 591 |
$object->description = $node->body;
|
| 592 |
$object->content_type = $node->type;
|
| 593 |
if (function_exists($node->type .'_replacement_content')) {
|
| 594 |
$function = $node->type .'_replacement_content';
|
| 595 |
$object->content = check_markup($function($node), $node->format, FALSE);
|
| 596 |
}
|
| 597 |
else {
|
| 598 |
$formatted_body = check_markup($node->body, $node->format, FALSE);
|
| 599 |
$object->content = $node->body;
|
| 600 |
}
|
| 601 |
$object->status = $node->status;
|
| 602 |
$object->path = array('URL' => 'node/'. $node->nid, 'QUERY' => NULL, 'BREADCRUMB' => NULL);
|
| 603 |
$object->link = 'node/'.$node->nid;
|
| 604 |
break;
|
| 605 |
case 'comment':
|
| 606 |
$result = db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d', $oid);
|
| 607 |
$comment = db_fetch_object($result);
|
| 608 |
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
|
| 609 |
$comment = drupal_unpack($comment);
|
| 610 |
if (!$comment->cid) {
|
| 611 |
return false;
|
| 612 |
}
|
| 613 |
$object->title = $comment->subject;
|
| 614 |
$object->name = $comment->name;
|
| 615 |
$object->uid = $comment->uid;
|
| 616 |
$object->content_type = 'comment';
|
| 617 |
$object->description = $comment->comment;
|
| 618 |
$object->status = ( $comment->status == 0);
|
| 619 |
$object->path = array('URL' => 'node/'. $comment->nid, 'QUERY' => NULL, 'BREADCRUMB' => 'comment-'. $comment->cid);
|
| 620 |
$object->link = 'node/'.$comment->nid . '#comment-'.$comment->cid;
|
| 621 |
break;
|
| 622 |
}
|
| 623 |
$object->reports = _abuse_load_reports($object->type, $object->oid);
|
| 624 |
$object->history = _abuse_load_history($object->type, $object->oid);
|
| 625 |
$object->warnings = _abuse_load_warnings($object->type, $object->oid);
|
| 626 |
return $object;
|
| 627 |
}
|
| 628 |
|
| 629 |
function _abuse_load_reports($type, $oid) {
|
| 630 |
$reports = array();
|
| 631 |
$result = db_query("SELECT a.*, u.name as registered_name, u.uid FROM {abuse} a INNER JOIN {users} u ON u.uid=a.uid WHERE a.type = '%s' AND a.oid = %d", $type, $oid);
|
| 632 |
while ($report = db_fetch_object($result)) {
|
| 633 |
$report->name = $report->uid ? $report->registered_name : $report->name;
|
| 634 |
$reports[] = $report;
|
| 635 |
}
|
| 636 |
return $reports;
|
| 637 |
}
|
| 638 |
|
| 639 |
function _abuse_load_history($type, $oid) {
|
| 640 |
$history = array();
|
| 641 |
$result = db_query("SELECT a.*, u.name as flagger FROM {abuse_status_log} a INNER JOIN {users} u ON u.uid=a.uid WHERE a.type='%s' AND a.oid=%d ORDER BY timestamp DESC", $type, $oid);
|
| 642 |
while ($log = db_fetch_object($result)) {
|
| 643 |
$log->readable_status = _abuse_retrieve_status($log->status);
|
| 644 |
$history[] = $log;
|
| 645 |
}
|
| 646 |
return $history;
|
| 647 |
}
|
| 648 |
|
| 649 |
function _abuse_load_warnings($type, $oid) {
|
| 650 |
$warnings = array();
|
| 651 |
$result = db_query("SELECT a.*, u.name FROM {abuse_warnings} a INNER JOIN {users} u ON a.sent_by_uid=u.uid WHERE a.type='%s' AND a.oid=%d ORDER BY created DESC",
|
| 652 |
$type, $oid);
|
| 653 |
while($warning = db_fetch_object($result)) {
|
| 654 |
$warning->date = date("d/m/Y - h:i", $warning->created);
|
| 655 |
$warning->name = (empty($warning->name)) ? t('Anonymous Admin') : $warning->name;
|
| 656 |
$warnings[] = $warning;
|
| 657 |
}
|
| 658 |
return $warnings;
|
| 659 |
}
|
| 660 |
|
| 661 |
function _abuse_reasons() {
|
| 662 |
static $reasons;
|
| 663 |
if (!$reasons) {
|
| 664 |
$reasons = array();
|
| 665 |
$resultset = db_query("SELECT * FROM {abuse_reasons}");
|
| 666 |
while ($reason = db_fetch_object($resultset)) {
|
| 667 |
$reasons[] = $reason;
|
| 668 |
}
|
| 669 |
}
|
| 670 |
return $reasons;
|
| 671 |
}
|
| 672 |
|
| 673 |
function _abuse_get_assigned_count($status = FALSE) {
|
| 674 |
global $user;
|
| 675 |
$result = 0;
|
| 676 |
if ($status !== FALSE) {
|
| 677 |
$query = db_query("UPDATE {abuse_status} SET assigned_to_uid=%d WHERE (assigned_to_uid=0 OR assigned_to_uid=%d) AND status=%d ORDER BY assigned_to_uid DESC, oid DESC LIMIT %d",
|
| 678 |
$user->uid, $user->uid, $status, variable_get('abuse_num_assigned', 20));
|
| 679 |
} else {
|
| 680 |
if (user_access('administer all abuse reports')) {
|
| 681 |
$result = db_query("UPDATE {abuse_status} SET assigned_to_uid=%d WHERE (assigned_to_uid=0 OR assigned_to_uid=%d) AND (status=%d OR status=%d OR status=%d) ORDER BY assigned_to_uid DESC, oid DESC LIMIT %d",
|
| 682 |
$user->uid, $user->uid, ABUSE_PENDING, ABUSE_HIDDEN, ABUSE_SUPERADMIN, variable_get('abuse_num_assigned', 20));
|
| 683 |
} else {
|
| 684 |
$result = db_query("UPDATE {abuse_status} SET assigned_to_uid=%d WHERE (assigned_to_uid=0 OR assigned_to_uid=%d) AND (status=%d OR status=%d) ORDER BY assigned_to_uid DESC, oid DESC LIMIT %d",
|
| 685 |
$user->uid, $user->uid, ABUSE_PENDING, ABUSE_HIDDEN, variable_get('abuse_num_assigned', 20));
|
| 686 |
}
|
| 687 |
$result = db_result(db_query("SELECT count(*) FROM {abuse_status} WHERE assigned_to_uid=%d AND (status=%d OR status=%d OR status=%d)",
|
| 688 |
$user->uid, ABUSE_PENDING, ABUSE_HIDDEN, ABUSE_SUPERADMIN));
|
| 689 |
}
|
| 690 |
return $result;
|
| 691 |
}
|
| 692 |
|
| 693 |
function _abuse_get_assigned_pending_count($status = FALSE) {
|
| 694 |
global $user;
|
| 695 |
$result = 0;
|
| 696 |
if ($status !== FALSE) {
|
| 697 |
$result = db_result(db_query("SELECT COUNT(*) FROM {abuse_status} WHERE (assigned_to_uid=0 OR assigned_to_uid=%d) AND status=%d",
|
| 698 |
$user->uid, $status));
|
| 699 |
} else {
|
| 700 |
if (user_access('administer all abuse reports')) {
|
| 701 |
$result = db_result(db_query("SELECT COUNT(*) FROM {abuse_status} WHERE (assigned_to_uid=0 OR assigned_to_uid=%d) AND (status=%d OR status=%d OR status=%d)",
|
| 702 |
$user->uid, ABUSE_PENDING, ABUSE_HIDDEN, ABUSE_SUPERADMIN));
|
| 703 |
} else {
|
| 704 |
$result = db_result(db_query("SELECT COUNT(*) FROM {abuse_status} WHERE (assigned_to_uid=0 OR assigned_to_uid=%d) AND (status=%d OR status=%d OR status=%d)",
|
| 705 |
$user->uid, ABUSE_PENDING, ABUSE_HIDDEN, ABUSE_SUPERADMIN));
|
| 706 |
}
|
| 707 |
}
|
| 708 |
return intval($result);
|
| 709 |
}
|
| 710 |
function _abuse_get_tallied_count($status = array(ABUSE_LIVE)) {
|
| 711 |
$query = "SELECT COUNT(*) FROM {abuse_status}";
|
| 712 |
$run_once = FALSE;
|
| 713 |
foreach ($status as $type) {
|
| 714 |
$query .= ($run_once) ? " OR status=%d" : " WHERE status=%d";
|
| 715 |
$run_once = TRUE;
|
| 716 |
}
|
| 717 |
return db_result(db_query($query, $status));
|
| 718 |
}
|
| 719 |
|
| 720 |
function _abuse_get_status($type, $oid) {
|
| 721 |
$res = db_result(db_query("SELECT status FROM {abuse_status} WHERE type='%s' AND oid=%d", $type, $oid));
|
| 722 |
return _abuse_retrieve_status((int)$res);
|
| 723 |
}
|
| 724 |
|
| 725 |
function _abuse_retrieve_status($current_status) {
|
| 726 |
static $status;
|
| 727 |
if (!$status) {
|
| 728 |
$status = array(ABUSE_LIVE => t('OK'),
|
| 729 |
ABUSE_PENDING => t('Pending'),
|
| 730 |
ABUSE_HIDDEN => t('Hidden'),
|
| 731 |
ABUSE_REMOVED => t('Removed'),
|
| 732 |
ABUSE_SUPERADMIN => t('Superadmin Assigned'),
|
| 733 |
);
|
| 734 |
}
|
| 735 |
return $status[$current_status];
|
| 736 |
}
|
| 737 |
|
| 738 |
function _abuse_set_status($type, $oid, $status) {
|
| 739 |
$nid = $oid;
|
| 740 |
global $user;
|
| 741 |
$assigned_to_uid = 0;
|
| 742 |
if (user_access('administer abuse reports')) {
|
| 743 |
$assigned_to_uid = (ABUSE_SUPERADMIN == $status) ? 0 : $user->uid;
|
| 744 |
db_query("INSERT IGNORE INTO {abuse_status_log} (oid, type, uid, status, timestamp) VALUES (%d, '%s', %d, %d, %d)",
|
| 745 |
$oid, $type, $user->uid, $status, time());
|
| 746 |
}
|
| 747 |
db_query("DELETE FROM {abuse_status} WHERE type='%s' AND oid=%d", $type, $oid);
|
| 748 |
db_query("INSERT INTO {abuse_status} (type, oid, changed, status, assigned_to_uid) VALUES ('%s', %d, %d, %d, %d)",
|
| 749 |
$type, $oid, time(), $status, $assigned_to_uid);
|
| 750 |
if ('comment' == $type) {
|
| 751 |
$nid = db_result(db_query("SELECT nid FROM {comments} where cid=%d", $oid));
|
| 752 |
} if ($nid) {
|
| 753 |
db_query("UPDATE {node} SET changed=%d WHERE nid=%d", time(), $nid);
|
| 754 |
}
|
| 755 |
}
|
| 756 |
|
| 757 |
function _abuse_allow($type, $oid) {
|
| 758 |
$object = _abuse_load($type, $oid);
|
| 759 |
$account = user_load(array('uid' => $object->uid, 'status' => 1));
|
| 760 |
if ($account->uid) {
|
| 761 |
db_query("UPDATE {abuse} SET valid=-1 WHERE type='%s' AND oid=%d", $type, $oid);
|
| 762 |
// Re-Save the node so it can get indexed if not already done so and any other important functionality is carried out by being published
|
| 763 |
switch ($type) {
|
| 764 |
case 'node':
|
| 765 |
$node = node_load($object->nid);
|
| 766 |
$node->status = 1;
|
| 767 |
node_save($node);
|
| 768 |
//db_query("UPDATE {node} SET status=1 WHERE nid=%d", $oid);
|
| 769 |
break;
|
| 770 |
case 'comment':
|
| 771 |
db_query("UPDATE {comments} SET status=0 WHERE cid=%d", $oid);
|
| 772 |
$node = node_load($object->nid);
|
| 773 |
$node->status = 1;
|
| 774 |
node_save($node);
|
| 775 |
break;
|
| 776 |
}
|
| 777 |
_abuse_set_status($type, $oid, ABUSE_LIVE);
|
| 778 |
_abuse_clear_oid_cache($oid);
|
| 779 |
return true;
|
| 780 |
} else {
|
| 781 |
drupal_set_message(t('Invalid user account - content cannot be allowed'), 'error');
|
| 782 |
return false;
|
| 783 |
}
|
| 784 |
}
|
| 785 |
|
| 786 |
function _abuse_remove($type, $oid) {
|
| 787 |
db_query("UPDATE {abuse} SET valid=1 WHERE type='%s' AND oid=%d", $type, $oid);
|
| 788 |
switch ($type) {
|
| 789 |
case 'node':
|
| 790 |
db_query("UPDATE {node} SET status=-1 WHERE nid=%d", $oid);
|
| 791 |
break;
|
| 792 |
case 'comment':
|
| 793 |
db_query("UPDATE {comments} SET status=1 WHERE cid=%d", $oid);
|
| 794 |
break;
|
| 795 |
}
|
| 796 |
_abuse_clear_oid_cache($oid);
|
| 797 |
_abuse_set_status($type, $oid, ABUSE_REMOVED);
|
| 798 |
}
|
| 799 |
|
| 800 |
function _abuse_assign_superadmin($type, $oid) {
|
| 801 |
_abuse_clear_oid_cache($oid);
|
| 802 |
_abuse_set_status($type, $oid, ABUSE_SUPERADMIN);
|
| 803 |
}
|
| 804 |
|
| 805 |
function _abuse_disable($type, $oid) {
|
| 806 |
$count = db_result(db_query("SELECT count(*) FROM {abuse} WHERE type='%s' AND oid=%d AND valid >= 0", $type, $oid));
|
| 807 |
if (user_access('direct flag') || $count >= variable_get('abuse_threshold', 3)) {
|
| 808 |
switch ($type) {
|
| 809 |
case 'node':
|
| 810 |
db_query("UPDATE {node} SET status=-1 WHERE nid=%d", $oid);
|
| 811 |
break;
|
| 812 |
case 'comment':
|
| 813 |
db_query("UPDATE {comments} SET status=1 WHERE cid=%d", $oid);
|
| 814 |
break;
|
| 815 |
}
|
| 816 |
_abuse_set_status($type, $oid, ABUSE_HIDDEN);
|
| 817 |
_abuse_clear_oid_cache($oid);
|
| 818 |
return true;
|
| 819 |
}
|
| 820 |
return false;
|
| 821 |
}
|
| 822 |
|
| 823 |
function _abuse_clear_oid_cache($oid) {
|
| 824 |
$cache_tables = array('cache', 'cache_block', 'cache_filter', 'cache_page');
|
| 825 |
foreach ($cache_tables as $table) {
|
| 826 |
cache_clear_all($oid, $table, TRUE);
|
| 827 |
}
|
| 828 |
}
|
| 829 |
|
| 830 |
/**
|
| 831 |
* Add an item into the abuse list
|
| 832 |
*
|
| 833 |
* @param string $type type of object being provided
|
| 834 |
* @param int $oid Object ID
|
| 835 |
* @param string[] $matches array of word matches found
|
| 836 |
* @param boolean $pre_moderated if the content is to be un-published
|
| 837 |
* @param boolean $hidden if the content is to be un-published and flagged as hidden from other users
|
| 838 |
* */
|
| 839 |
function _abuse_report_generated($object = NULL, $type = NULL, $oid = NULL, $matches = array(), $unpublished = FALSE, $hidden=FALSE) {
|
| 840 |
if (!empty($object) && !empty($type) && !empty($oid)) {
|
| 841 |
$admin = array(
|
| 842 |
'uid' => 0,
|
| 843 |
'name' => 'AUTO_ADMIN',
|
| 844 |
'mail' => variable_get('site_mail', 'AUTO_ADMIN@abuse_generator.com'),
|
| 845 |
'reason' => 0,
|
| 846 |
'body' => 'WATCHLIST: '. implode(', ', $matches),
|
| 847 |
);
|
| 848 |
if(empty($matches)) {
|
| 849 |
$admin['body'] = t("AUTO MESSAGE: No questionable words were found in this @type", array('@type' => $type));
|
| 850 |
}
|
| 851 |
|
| 852 |
// If unpublishing the content
|
| 853 |
if ($unpublished === TRUE) {
|
| 854 |
switch ($type) {
|
| 855 |
case 'node':
|
| 856 |
db_query("UPDATE {node} SET STATUS=0 WHERE nid=%d", $object->nid);
|
| 857 |
if (module_exists('search')) {
|
| 858 |
search_touch_node($object->nid);
|
| 859 |
}
|
| 860 |
break;
|
| 861 |
case 'comment':
|
| 862 |
db_query("UPDATE {comments} SET status=1 WHERE cid=%d", $object->cid);
|
| 863 |
if (module_exists('search')) {
|
| 864 |
search_touch_node($object->nid);
|
| 865 |
}
|
| 866 |
break;
|
| 867 |
case 'user':
|
| 868 |
db_query("UPDATE {users} SET status=0 WHERE nid=%d", $object->uid);
|
| 869 |
break;
|
| 870 |
}
|
| 871 |
}
|
| 872 |
|
| 873 |
// Check if movie needs to be in hidden pile
|
| 874 |
if ($hidden === TRUE) {
|
| 875 |
_abuse_set_status($type, $oid, ABUSE_HIDDEN);
|
| 876 |
} else {
|
| 877 |
_abuse_set_status($type, $oid, ABUSE_PENDING);
|
| 878 |
}
|
| 879 |
|
| 880 |
// Add or update the auto field
|
| 881 |
$aid = db_result(db_query("SELECT aid FROM {abuse} WHERE type='%s' AND oid=%d AND uid=%d AND name='%s'", $type, $oid, $admin['uid'], $admin['name']));
|
| 882 |
if ($aid === FALSE) {
|
| 883 |
db_query("INSERT INTO {abuse} (type, oid, created, body, reason, uid, name, mail) VALUES ('%s', %d, %d, '%s', '%s', %d, '%s', '%s')",
|
| 884 |
$type, $oid, time(), $admin['body'], $admin['reason'], $admin['uid'], $admin['name'], $admin['mail']);
|
| 885 |
} else {
|
| 886 |
db_query("UPDATE {abuse} SET body='%s', created=%d WHERE aid=%d", $admin['body'], time());
|
| 887 |
}
|
| 888 |
}
|
| 889 |
}
|
| 890 |
|
| 891 |
?>
|