| 1 |
<?php |
<?php |
| 2 |
// $Id: akismet.module,v 1.20 2008/03/18 23:02:20 drewish Exp $ |
// $Id: akismet.module,v 1.21 2008/03/18 23:09:28 drewish Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* Akismet Drupal and Module versions. |
* Akismet Drupal and Module versions. |
| 6 |
*/ |
*/ |
| 7 |
define('AKISMET_DRUPAL_VERSION', '5'); |
define('AKISMET_DRUPAL_VERSION', '6'); |
| 8 |
define('AKISMET_MODULE_VERSION', '1.2'); |
define('AKISMET_MODULE_VERSION', '2.0'); |
| 9 |
define('AKISMET_MODULE_HOMEURL', 'http://www.drupal.org/project/akismet'); |
define('AKISMET_MODULE_HOMEURL', 'http://www.drupal.org/project/akismet'); |
| 10 |
define('AKISMET_MODULE_USERAGENT', 'Drupal/'. AKISMET_DRUPAL_VERSION .' | akismet.module/'. AKISMET_MODULE_VERSION); |
define('AKISMET_MODULE_USERAGENT', 'Drupal/'. AKISMET_DRUPAL_VERSION .' | akismet.module/'. AKISMET_MODULE_VERSION); |
| 11 |
|
|
| 26 |
/** |
/** |
| 27 |
* Implementation of hook_help(). |
* Implementation of hook_help(). |
| 28 |
*/ |
*/ |
| 29 |
function akismet_help($section) { |
function akismet_help($path, $arg) { |
| 30 |
switch ($section) { |
switch ($path) { |
| 31 |
case 'admin/help#akismet': |
case 'admin/help#akismet': |
| 32 |
$output = t('<p>In order to use the <a href="!akismet">Akismet Service</a>, you need a <a href="!wpapikey">WordPress.com API key</a>. If you don\'t have one already, you can get it by simply signing up for a free account at <a href="!wordpress-com">wordpress.com</a>. Please, consult the <a href="!akismet-faq">Akismet FAQ</a> for further information.</p> |
$output = t('<p>In order to use the <a href="!akismet">Akismet Service</a>, you need a <a href="!wpapikey">WordPress.com API key</a>. If you don\'t have one already, you can get it by simply signing up for a free account at <a href="!wordpress-com">wordpress.com</a>. Please, consult the <a href="!akismet-faq">Akismet FAQ</a> for further information.</p> |
| 33 |
<p>The <em>akismet module</em> may automatically check for spam posted in content (nodes and/or comments) by any user, except node or comment administrators respectively. It is also possible, from the <a href="!access-control">access control</a> panel, to grant <em>%no-check-perm</em> permission to <em>user roles</em> of your choice.</p> |
<p>The <em>akismet module</em> may automatically check for spam posted in content (nodes and/or comments) by any user, except node or comment administrators respectively. It is also possible, from the <a href="!access-control">access control</a> panel, to grant <em>%no-check-perm</em> permission to <em>user roles</em> of your choice.</p> |
| 54 |
)); |
)); |
| 55 |
$output .= t('<p>Akismet has caught <strong>@count spam</strong> for you since %since.</p>', array('@count' => akismet_get_spam_counter(), '%since' => akismet_get_counting_since())); |
$output .= t('<p>Akismet has caught <strong>@count spam</strong> for you since %since.</p>', array('@count' => akismet_get_spam_counter(), '%since' => akismet_get_counting_since())); |
| 56 |
return $output; |
return $output; |
| 57 |
default: |
case 'admin/content/akismet/nodes/unpublished': |
| 58 |
if (arg(0) == 'admin' && arg(1) == 'content '&& arg(2) == 'akismet' && !isset($_POST)) { |
$output = t('Below is the list of <strong>unpublished nodes</strong> awaiting for moderation.'); |
| 59 |
if (arg(3) == 'nodes') { |
$output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.'); |
| 60 |
if (arg(4) == 'unpublished') { |
break; |
| 61 |
$output = t('Below is the list of <strong>unpublished nodes</strong> awaiting for moderation.'); |
case 'admin/content/akismet/nodes/published': |
| 62 |
} |
$output = t('Below is the list of <strong>published nodes</strong>.'); |
| 63 |
else if (arg(4) == 'published') { |
$output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.'); |
| 64 |
$output = t('Below is the list of <strong>published nodes</strong>.'); |
break; |
| 65 |
} |
case 'admin/content/akismet/nodes': // spam |
| 66 |
else { // spam |
$output = t('Below is the list of <strong>nodes marked as spam</strong> awaiting for moderation.'); |
| 67 |
$output = t('Below is the list of <strong>nodes marked as spam</strong> awaiting for moderation.'); |
$output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.'); |
| 68 |
} |
break; |
| 69 |
$output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.'); |
case 'admin/content/akismet/comments/unpublished': |
| 70 |
} |
$output = t('Below is the list of <strong>unpublished comments</strong> awaiting for moderation.'); |
| 71 |
else if (arg(3) == 'comments') { |
$output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.'); |
| 72 |
if (arg(4) == 'unpublished') { |
break; |
| 73 |
$output = t('Below is the list of <strong>unpublished comments</strong> awaiting for moderation.'); |
case 'admin/content/akismet/comments/published': |
| 74 |
} |
$output = t('Below is the list of <strong>published comments</strong>.'); |
| 75 |
else if (arg(4) == 'published') { |
$output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.'); |
| 76 |
$output = t('Below is the list of <strong>published comments</strong>.'); |
break; |
| 77 |
} |
case 'admin/content/akismet/comments': // spam |
| 78 |
else { // spam |
$output = t('Below is the list of <strong>comments marked as spam</strong> awaiting for moderation.'); |
| 79 |
$output = t('Below is the list of <strong>comments marked as spam</strong> awaiting for moderation.'); |
$output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.'); |
| 80 |
} |
break; |
| 81 |
$output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.'); |
} |
| 82 |
} |
if (arg(0) == 'admin' && arg(1) == 'content '&& arg(2) == 'akismet' && !isset($_POST) && !empty($output)) { |
| 83 |
if (!empty($output)) { |
$output .= '<br />'. t('<strong>Note:</strong> To interact fully with the <a href="!akismet">Akismet Service</a> you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use the submit <em>ham</em> operation rather than simply publishing content that was identified as spam (false positives). This is necessary in order to let Akismet learn from its mistakes. Thank you.', array('!akismet' => url('http://akismet.com'))); |
|
$output .= '<br />'. t('<strong>Note:</strong> To interact fully with the <a href="!akismet">Akismet Service</a> you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use the submit <em>ham</em> operation rather than simply publishing content that was identified as spam (false positives). This is necessary in order to let Akismet learn from its mistakes. Thank you.', array('!akismet' => url('http://akismet.com'))); |
|
|
return $output; |
|
|
} |
|
|
} |
|
|
break; |
|
| 84 |
} |
} |
| 85 |
} |
} |
| 86 |
|
|
| 129 |
register_shutdown_function('akismet_cron_shutdown'); |
register_shutdown_function('akismet_cron_shutdown'); |
| 130 |
} |
} |
| 131 |
|
|
| 132 |
/** |
function _akismet_moderator_types_count($types = array()) { |
| 133 |
* Implementation of hook_settings(). |
if (empty($types)) { |
| 134 |
*/ |
$types = akismet_get_moderator_types(); |
| 135 |
function akismet_settings() { |
} |
| 136 |
require_once('./'. drupal_get_path('module', 'akismet') . '/akismet_admin.inc'); |
return count($types); |
| 137 |
return _akismet_settings_form(); |
} |
| 138 |
|
|
| 139 |
|
function _akismet_is_moderator($moderator_types = array(), $type = '') { |
| 140 |
|
if (empty($moderator_types)) { |
| 141 |
|
$moderator_types = akismet_get_moderator_types(); |
| 142 |
|
} |
| 143 |
|
if (_akismet_moderator_types_count($moderator_types) > 0 && (empty($type) || isset($moderator_types[$type]))) { |
| 144 |
|
return TRUE; |
| 145 |
|
} |
| 146 |
|
else { |
| 147 |
|
return FALSE; |
| 148 |
|
} |
| 149 |
|
} |
| 150 |
|
|
| 151 |
|
function _akismet_is_node_moderator($moderator_types = array()) { |
| 152 |
|
if (empty($moderator_types)) { |
| 153 |
|
$moderator_types = akismet_get_moderator_types(); |
| 154 |
|
} |
| 155 |
|
if (_akismet_is_moderator($moderator_types) && (!_akismet_is_moderator($moderator_types, $type = 'comments') || _akismet_moderator_types_count($moderator_types) > 1)) { |
| 156 |
|
return TRUE; |
| 157 |
|
} |
| 158 |
|
else { |
| 159 |
|
return FALSE; |
| 160 |
|
} |
| 161 |
|
} |
| 162 |
|
|
| 163 |
|
function _akismet_is_moderator_type($type, $types = array()) { |
| 164 |
|
if (empty($types)) { |
| 165 |
|
$types = akismet_get_moderator_types(); |
| 166 |
|
} |
| 167 |
|
if (_akismet_moderator_types_count($types) > 0 && isset($types[$type])) { |
| 168 |
|
return TRUE; |
| 169 |
|
} |
| 170 |
|
else { |
| 171 |
|
return FALSE; |
| 172 |
|
} |
| 173 |
} |
} |
| 174 |
|
|
| 175 |
/** |
/** |
| 176 |
* Implementation of hook_menu(). |
* Implementation of hook_menu(). |
| 177 |
*/ |
*/ |
| 178 |
function akismet_menu($may_cache) { |
function akismet_menu() { |
| 179 |
$items = array(); |
$items = array(); |
| 180 |
|
|
| 181 |
if ($may_cache) { |
$items['admin/settings/akismet'] = array( |
| 182 |
// Changes in content types force the menu to be rebuilt, |
'title' => t('Akismet'), |
| 183 |
// so it should be safe to cache this menu items here. |
'description' => t('Use the Akismet Service to protect your site from spam.'), |
| 184 |
// Users will only see this menu if they actually can |
'page callback' => 'drupal_get_form', |
| 185 |
// moderate, at least, one content type. |
'page arguments' => array('akismet_settings'), |
| 186 |
$items[] = array('path' => 'admin/settings/akismet', |
'access arguments' => array('administer akismet settings'), |
| 187 |
'title' => t('Akismet'), 'description' => t('Use the Akismet Service to protect your site from spam.'), |
'file' => 'akismet.admin.inc', |
| 188 |
'callback' => 'drupal_get_form', 'callback arguments' => array('akismet_settings'), |
); |
|
'access' => user_access('administer akismet settings')); |
|
| 189 |
|
|
| 190 |
$moderator_types = akismet_get_moderator_types(); |
$moderator_types = akismet_get_moderator_types(); |
| 191 |
$moderator_types_count = count($moderator_types); |
if (_akismet_is_moderator($moderator_types)) { |
| 192 |
if ($moderator_types_count > 0) { |
$items['admin/content/akismet'] = array( |
| 193 |
$items[] = array('path' => 'admin/content/akismet', 'title' => t('Akismet moderation queue'), |
'title' => t('Akismet moderation queue'), |
| 194 |
'description' => t('Manage the Akismet spam queue, appropving or deleting content in need of moderation.'), |
'description' => t('Manage the Akismet spam queue, appropving or deleting content in need of moderation.'), |
| 195 |
'callback' => 'akismet_callback_queue', |
'page callback' => 'akismet_callback_queue', |
| 196 |
'access' => ($moderator_types_count > 0 ? TRUE : FALSE)); |
'access callback' => array('_akismet_is_moderator'), |
| 197 |
$items[] = array('path' => 'admin/content/akismet/overview', 'title' => t('Overview'), |
'access arguments' => array($moderator_types), |
| 198 |
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0); |
'file' => 'akismet.admin.inc', |
| 199 |
if (!isset($moderator_types['comments']) || $moderator_types_count > 1) { |
); |
| 200 |
$items[] = array('path' => 'admin/content/akismet/nodes', 'title' => t('Nodes'), |
$items['admin/content/akismet/overview'] = array( |
| 201 |
'callback' => 'akismet_callback_queue', |
'title' => t('Overview'), |
| 202 |
'callback arguments' => array('nodes'), |
'type' => MENU_DEFAULT_LOCAL_TASK, |
| 203 |
'type' => MENU_LOCAL_TASK, 'weight' => 1); |
'weight' => 0, |
| 204 |
$items[] = array('path' => 'admin/content/akismet/nodes/spam', 'title' => t('Spam'), |
'file' => 'akismet.admin.inc', |
| 205 |
'callback' => 'akismet_callback_queue', |
); |
| 206 |
'callback arguments' => array('nodes'), |
if (_akismet_is_node_moderator($moderator_types)) { |
| 207 |
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0); |
$items['admin/content/akismet/nodes'] = array( |
| 208 |
$items[] = array('path' => 'admin/content/akismet/nodes/unpublished', 'title' => t('Unpublished nodes'), |
'title' => t('Nodes'), |
| 209 |
'callback' => 'akismet_callback_queue', |
'page callback' => 'akismet_callback_queue', |
| 210 |
'callback arguments' => array('nodes', 'unpublished'), |
'page arguments' => array('nodes'), |
| 211 |
'type' => MENU_LOCAL_TASK, 'weight' => 1); |
'access callback' => array('_akismet_is_node_moderator'), |
| 212 |
$items[] = array('path' => 'admin/content/akismet/nodes/published', 'title' => t('Published nodes'), |
'access arguments' => array($moderator_types), |
| 213 |
'callback' => 'akismet_callback_queue', |
'type' => MENU_LOCAL_TASK, |
| 214 |
'callback arguments' => array('nodes', 'published'), |
'weight' => 1, |
| 215 |
'type' => MENU_LOCAL_TASK, 'weight' => 2); |
'file' => 'akismet.admin.inc', |
| 216 |
} |
); |
| 217 |
if (isset($moderator_types['comments'])) { |
$items['admin/content/akismet/nodes/spam'] = array( |
| 218 |
$items[] = array('path' => 'admin/content/akismet/comments', 'title' => t('Comments'), |
'title' => t('Spam'), |
| 219 |
'callback' => 'akismet_callback_queue', |
'page arguments' => array('nodes'), |
| 220 |
'callback arguments' => array('comments'), |
'type' => MENU_DEFAULT_LOCAL_TASK, |
| 221 |
'type' => MENU_LOCAL_TASK, 'weight' => 2); |
'weight' => 0, |
| 222 |
$items[] = array('path' => 'admin/content/akismet/comments/spam', 'title' => t('Spam'), |
'file' => 'akismet.admin.inc', |
| 223 |
'callback' => 'akismet_callback_queue', |
); |
| 224 |
'callback arguments' => array('comments'), |
$items['admin/content/akismet/nodes/unpublished'] = array( |
| 225 |
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0); |
'title' => t('Unpublished nodes'), |
| 226 |
$items[] = array('path' => 'admin/content/akismet/comments/unpublished', 'title' => t('Unpublished comments'), |
'page arguments' => array('nodes', 'unpublished'), |
| 227 |
'callback' => 'akismet_callback_queue', |
'type' => MENU_LOCAL_TASK, |
| 228 |
'callback arguments' => array('comments', 'unpublished'), |
'weight' => 1, |
| 229 |
'type' => MENU_LOCAL_TASK, 'weight' => 1); |
'file' => 'akismet.admin.inc', |
| 230 |
$items[] = array('path' => 'admin/content/akismet/comments/published', 'title' => t('Published comments'), |
); |
| 231 |
'callback' => 'akismet_callback_queue', |
$items['admin/content/akismet/nodes/published'] = array( |
| 232 |
'callback arguments' => array('comments', 'published'), |
'title' => t('Published nodes'), |
| 233 |
'type' => MENU_LOCAL_TASK, 'weight' => 2); |
'callback arguments' => array('nodes', 'published'), |
| 234 |
} |
'type' => MENU_LOCAL_TASK, |
| 235 |
|
'weight' => 2, |
| 236 |
|
'file' => 'akismet.admin.inc', |
| 237 |
|
); |
| 238 |
|
} |
| 239 |
|
if (_akismet_is_moderator($moderator_types, 'comments')) { |
| 240 |
|
$items['admin/content/akismet/comments'] = array( |
| 241 |
|
'title' => t('Comments'), |
| 242 |
|
'page callback' => 'akismet_callback_queue', |
| 243 |
|
'page arguments' => array('comments'), |
| 244 |
|
'access callback' => array('_akismet_is_moderator'), |
| 245 |
|
'access arguments' => array($moderator_types, 'comments'), |
| 246 |
|
'type' => MENU_LOCAL_TASK, |
| 247 |
|
'weight' => 2, |
| 248 |
|
'file' => 'akismet.admin.inc', |
| 249 |
|
); |
| 250 |
|
$items['admin/content/akismet/comments/spam'] = array( |
| 251 |
|
'title' => t('Spam'), |
| 252 |
|
'page arguments' => array('comments'), |
| 253 |
|
'type' => MENU_DEFAULT_LOCAL_TASK, |
| 254 |
|
'weight' => 0, |
| 255 |
|
'file' => 'akismet.admin.inc', |
| 256 |
|
); |
| 257 |
|
$items['admin/content/akismet/comments/unpublished'] = array( |
| 258 |
|
'title' => t('Unpublished comments'), |
| 259 |
|
'page arguments' => array('comments', 'unpublished'), |
| 260 |
|
'type' => MENU_LOCAL_TASK, |
| 261 |
|
'weight' => 1, |
| 262 |
|
'file' => 'akismet.admin.inc', |
| 263 |
|
); |
| 264 |
|
$items['admin/content/akismet/comments/published'] = array( |
| 265 |
|
'title' => t('Published comments'), |
| 266 |
|
'page arguments' => array('comments', 'published'), |
| 267 |
|
'type' => MENU_LOCAL_TASK, |
| 268 |
|
'weight' => 2, |
| 269 |
|
'file' => 'akismet.admin.inc', |
| 270 |
|
); |
| 271 |
} |
} |
| 272 |
} |
} |
| 273 |
else { |
else { |
| 274 |
// Paths may look like 'akismet/content_type/content_id/operation' |
$item = array( |
| 275 |
if (arg(0) == 'akismet' && is_numeric(arg(2))) { |
'title' => 'switch content status', |
| 276 |
$content_type = arg(1); |
'page callback' => 'akismet_page', |
| 277 |
if ($content_type == 'node' || ($content_type == 'comment' && module_exists('comment'))) { |
'page arguments' => array(0, 1, 2, 3), |
| 278 |
$op = arg(3); |
'load arguments' => array('%map', '%index'), |
| 279 |
if ($op == 'publish' || $op == 'unpublish') { |
'access callback' => array('akismet_access_callback'), |
| 280 |
$callback = 'akismet_callback_set_published_status'; |
'access argument' => array(0, 1, 2, 3), |
| 281 |
} |
); |
| 282 |
else if ($op == 'submit-spam' || $op == 'submit-ham') { |
foreach (array('publish', 'unpublish', 'submit-spam', 'submit-ham') as $op) { |
| 283 |
$callback = 'akismet_callback_set_spam_status'; |
$items['akismet/%akismet/%/'. $op] = $item; |
|
} |
|
|
if (isset($callback)) { |
|
|
$moderator_type = akismet_content_get_moderator_type($content_type, arg(2)); |
|
|
if (!empty($moderator_type)) { |
|
|
$items[] = array('path' => 'akismet', 'title' => t('switch content status'), |
|
|
'callback' => $callback, |
|
|
'access' => akismet_is_spam_moderator($moderator_type), |
|
|
'type' => MENU_CALLBACK); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else { |
|
|
// Load the administration specific code? |
|
|
if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'akismet') { |
|
|
require_once('./'. drupal_get_path('module', 'akismet') . '/akismet_admin.inc'); |
|
|
} |
|
| 284 |
} |
} |
| 285 |
} |
} |
| 286 |
|
|
| 287 |
return $items; |
return $items; |
| 288 |
} |
} |
| 289 |
|
|
| 290 |
|
function akismet_load($arg, &$map, $index) { |
| 291 |
|
if (!is_numeric($map[2])) { |
| 292 |
|
// Node and comment ids are always numeric! |
| 293 |
|
return FALSE; |
| 294 |
|
} |
| 295 |
|
$content_type = $map[1]; |
| 296 |
|
if ($content_type == 'node') { |
| 297 |
|
if (!$map[2] = node_load($map[2])) { |
| 298 |
|
return FALSE; |
| 299 |
|
} |
| 300 |
|
} |
| 301 |
|
if ($content_type == 'comment' && module_exists('comment')) { |
| 302 |
|
if (!$map[2] = comment_load($map[2])) { |
| 303 |
|
return FALSE; |
| 304 |
|
} |
| 305 |
|
} |
| 306 |
|
$op == $map[3]; |
| 307 |
|
if ($op == 'publish' || $op == 'unpublish') { |
| 308 |
|
$map[0] = 'akismet_callback_set_published_status'; |
| 309 |
|
} |
| 310 |
|
else if ($op == 'submit-spam' || $op == 'submit-ham') { |
| 311 |
|
$map[0] = 'akismet_callback_set_spam_status'; |
| 312 |
|
} |
| 313 |
|
return $map[$index]; |
| 314 |
|
} |
| 315 |
|
|
| 316 |
|
function akismet_access_callback($callback, $content_type, $object, $op) { |
| 317 |
|
if ($content_type == 'node' && !node_access($map[2])) { |
| 318 |
|
return FALSE; |
| 319 |
|
} |
| 320 |
|
if (function_exists($callback && !akismet_is_spam_moderator(akismet_content_get_moderator_type($content_type, $object)))) { |
| 321 |
|
return FALSE; |
| 322 |
|
} |
| 323 |
|
// Is there a comment access check we need to run? If yes, then do the same as above. |
| 324 |
|
return TRUE; |
| 325 |
|
} |
| 326 |
|
|
| 327 |
|
function akismet_page($callback, $content_type, $object, $op) { |
| 328 |
|
if (function_exists($callback)) { |
| 329 |
|
return $callback($content_type, $object, $op); |
| 330 |
|
} |
| 331 |
|
drupal_not_found(); |
| 332 |
|
} |
| 333 |
|
|
| 334 |
/** |
/** |
| 335 |
* Implementation of hook_link(). |
* Implementation of hook_link(). |
| 336 |
*/ |
*/ |
| 382 |
* @param integer Content ID; can be either a nid or a cid. |
* @param integer Content ID; can be either a nid or a cid. |
| 383 |
* @param string Operation; it can be 'publish' or 'unpublish'. |
* @param string Operation; it can be 'publish' or 'unpublish'. |
| 384 |
*/ |
*/ |
| 385 |
function akismet_callback_set_published_status($content_type, $content_id, $op) { |
function akismet_callback_set_published_status($content_type, $object, $op) { |
| 386 |
// Load the content (existence has been checked in hook_menu). |
// Load the content (existence has been checked in hook_menu). |
| 387 |
$content = akismet_content_load($content_type, $content_id); |
$content = akismet_content_load($content_type, $object); |
| 388 |
|
|
| 389 |
if ($content_type == 'node') { |
if ($content_type == 'node') { |
| 390 |
$is_published = ($content->status ? TRUE : FALSE); |
$is_published = ($content->status ? TRUE : FALSE); |
| 417 |
* @param integer Content ID; can be either a nid or a cid. |
* @param integer Content ID; can be either a nid or a cid. |
| 418 |
* @param string Operation; it can be 'submit-spam' or 'submit-ham'. |
* @param string Operation; it can be 'submit-spam' or 'submit-ham'. |
| 419 |
*/ |
*/ |
| 420 |
function akismet_callback_set_spam_status($content_type, $content_id, $op) { |
function akismet_callback_set_spam_status($content_type, $object, $op) { |
| 421 |
$is_spam = akismet_content_is_spam($content_type, $content_id); |
$is_spam = akismet_content_is_spam($content_type, $object); |
| 422 |
|
|
| 423 |
// Load the content (existence has been checked in hook_menu). |
// Load the content (existence has been checked in hook_menu). |
| 424 |
$content = akismet_content_load($content_type, $content_id); |
$content = akismet_content_load($content_type, $object); |
| 425 |
|
|
| 426 |
if ($content_type == 'node') { |
if ($content_type == 'node') { |
| 427 |
$is_published = ($content->status ? TRUE : FALSE); |
$is_published = ($content->status ? TRUE : FALSE); |
| 511 |
|
|
| 512 |
// Record the event to watchdog. |
// Record the event to watchdog. |
| 513 |
if ($akismet_api_result == AKISMET_API_RESULT_ERROR) { |
if ($akismet_api_result == AKISMET_API_RESULT_ERROR) { |
| 514 |
watchdog('content', t('Akismet service seems to be down, %content-type-name queued for manual approval: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title)), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid)); |
watchdog('content', 'Akismet service seems to be down, %content-type-name queued for manual approval: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid)); |
| 515 |
} |
} |
| 516 |
else { |
else { |
| 517 |
watchdog('content', t('Spam detected by Akismet in %content-type-name: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title)), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid)); |
watchdog('content', 'Spam detected by Akismet in %content-type-name: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid)); |
| 518 |
// If requested to, generate a delay so the spammer has to wait for a while. |
// If requested to, generate a delay so the spammer has to wait for a while. |
| 519 |
if (($seconds = variable_get('akismet_antispambot_delay', 60)) > 0) { |
if (($seconds = variable_get('akismet_antispambot_delay', 60)) > 0) { |
| 520 |
sleep($seconds); |
sleep($seconds); |
| 548 |
/** |
/** |
| 549 |
* Implementation of hook_form_alter(). |
* Implementation of hook_form_alter(). |
| 550 |
*/ |
*/ |
| 551 |
function akismet_form_alter($form_id, &$form) { |
function akismet_form_alter(&$form, &$form_state, $form_id) { |
| 552 |
// Hook into comment edit/reply form. |
// Hook into comment edit/reply form. |
| 553 |
if ($form_id == 'comment_form' && variable_get('akismet_check_comments', 1)) { |
if ($form_id == 'comment_form' && variable_get('akismet_check_comments', 1)) { |
| 554 |
// ...only if current user is not moderator. |
// ...only if current user is not moderator. |
| 555 |
if (!akismet_is_spam_moderator('comments')) { |
if (!akismet_is_spam_moderator('comments')) { |
| 556 |
// ...also check if Akismet connections are enabled. |
// ...also check if Akismet connections are enabled. |
| 557 |
if (variable_get('akismet_connection_enabled', 1)) { |
if (variable_get('akismet_connection_enabled', 1)) { |
| 558 |
if (isset($form['cid']) && isset($form['cid']['#value']) && is_numeric($form['cid']['#value'])) { |
// This is the simple hook method, *if* we already have the $cid. |
| 559 |
// This is the simple hook method, we already have the $cid. |
$form['#submit'][] = '_akismet_comment_form_submit'; |
| 560 |
$form['#submit']['_akismet_comment_form_submit'] = array(); |
if (!isset($form['cid']) || !isset($form['cid']['#value']) || !is_numeric($form['cid']['#value'])) { |
|
} |
|
|
else { |
|
| 561 |
// This is a bit more complex, because the user is creating a new comment, so |
// This is a bit more complex, because the user is creating a new comment, so |
| 562 |
// how can we get the $cid? See comments below, within our own submit callback. |
// how can we get the $cid? See comments below, within our own submit callback. |
| 563 |
$form['#submit'] = array('_akismet_comment_form_submit' => array($form['#submit'])); |
$form['#comment_form_param1'] = $form['#submit']; |
| 564 |
} |
} |
| 565 |
} |
} |
| 566 |
// Inject anti-spambot code, if requested to. |
// Inject anti-spambot code, if requested to. |
| 567 |
if (akismet_is_anti_spambot_enabled()) { |
if (akismet_is_anti_spambot_enabled()) { |
| 568 |
$form['#validate']['_akismet_comment_form_validate'] = array(); |
$form['#validate'][] = '_akismet_comment_form_validate'; |
| 569 |
} |
} |
| 570 |
} |
} |
| 571 |
} |
} |
| 579 |
if (is_array($check_nodetypes) && isset($check_nodetypes[$node_type]) && $check_nodetypes[$node_type]) { |
if (is_array($check_nodetypes) && isset($check_nodetypes[$node_type]) && $check_nodetypes[$node_type]) { |
| 580 |
// Inject anti-spambot code, if requested to. |
// Inject anti-spambot code, if requested to. |
| 581 |
if (akismet_is_anti_spambot_enabled()) { |
if (akismet_is_anti_spambot_enabled()) { |
| 582 |
$form['#validate']['_akismet_node_form_validate'] = array(); |
$form['#validate'][] = '_akismet_node_form_validate'; |
| 583 |
} |
} |
| 584 |
} |
} |
| 585 |
} |
} |
| 589 |
/** |
/** |
| 590 |
* Node form validate callback; check for spambots. |
* Node form validate callback; check for spambots. |
| 591 |
*/ |
*/ |
| 592 |
function _akismet_node_form_validate($form_id, $form_values) { |
function _akismet_node_form_validate($form, &$form_state) { |
| 593 |
// Quit if there have already been errors in the form. |
// Quit if there have already been errors in the form. |
| 594 |
if (form_get_errors()) { |
if (form_get_errors()) { |
| 595 |
return; |
return; |
| 602 |
$sql_args = array(); |
$sql_args = array(); |
| 603 |
if ($antispambot_rules['ip']) { |
if ($antispambot_rules['ip']) { |
| 604 |
$sql_where[] = 's.hostname = \'%s\''; |
$sql_where[] = 's.hostname = \'%s\''; |
| 605 |
$sql_args[] = $_SERVER['REMOTE_ADDR']; |
$sql_args[] = ip_address(); |
| 606 |
} |
} |
| 607 |
if ($antispambot_rules['body'] && !empty($form_values['body'])) { |
if ($antispambot_rules['body'] && !empty($form_state['values']['body'])) { |
| 608 |
$sql_where[] = 'r.body = \'%s\''; |
$sql_where[] = 'r.body = \'%s\''; |
| 609 |
$sql_args[] = $form_values['body']; |
$sql_args[] = $form_state['values']['body']; |
| 610 |
} |
} |
| 611 |
if ($antispambot_rules['mail'] && !empty($user->mail)) { |
if ($antispambot_rules['mail'] && !empty($user->mail)) { |
| 612 |
$sql_where[] = 's.mail = \'%s\''; |
$sql_where[] = 's.mail = \'%s\''; |
| 625 |
akismet_anti_spambot_action(array( |
akismet_anti_spambot_action(array( |
| 626 |
t('SQL') => _akismet_translate_query($sql_stmt, $sql_args), |
t('SQL') => _akismet_translate_query($sql_stmt, $sql_args), |
| 627 |
t('E-mail') => (isset($user->mail) ? $user->mail : ''), |
t('E-mail') => (isset($user->mail) ? $user->mail : ''), |
| 628 |
t('Body') => $form_values['body'] |
t('Body') => $form_state['values']['body'] |
| 629 |
)); |
)); |
| 630 |
} |
} |
| 631 |
} |
} |
| 634 |
/** |
/** |
| 635 |
* Comment form validate callback; check for spambots. |
* Comment form validate callback; check for spambots. |
| 636 |
*/ |
*/ |
| 637 |
function _akismet_comment_form_validate($form_id, $form_values) { |
function _akismet_comment_form_validate($form, &$form_state) { |
| 638 |
// Quit if there have already been errors in the form. |
// Quit if there have already been errors in the form. |
| 639 |
if (form_get_errors()) { |
if (form_get_errors()) { |
| 640 |
return; |
return; |
| 646 |
$sql_args = array(); |
$sql_args = array(); |
| 647 |
if ($antispambot_rules['ip']) { |
if ($antispambot_rules['ip']) { |
| 648 |
$sql_where[] = 's.hostname = \'%s\''; |
$sql_where[] = 's.hostname = \'%s\''; |
| 649 |
$sql_args[] = $_SERVER['REMOTE_ADDR']; |
$sql_args[] = ip_address(); |
| 650 |
} |
} |
| 651 |
if ($antispambot_rules['body'] && !empty($form_values['comment'])) { |
if ($antispambot_rules['body'] && !empty($form_state['values']['comment'])) { |
| 652 |
$sql_where[] = 'c.comment = \'%s\''; |
$sql_where[] = 'c.comment = \'%s\''; |
| 653 |
$sql_args[] = $form_values['comment']; |
$sql_args[] = $form_state['values']['comment']; |
| 654 |
} |
} |
| 655 |
if ($antispambot_rules['mail'] && !empty($form_values['mail'])) { |
if ($antispambot_rules['mail'] && !empty($form_state['values']['mail'])) { |
| 656 |
$sql_where[] = 's.mail = \'%s\''; |
$sql_where[] = 's.mail = \'%s\''; |
| 657 |
$sql_args[] = $form_values['mail']; |
$sql_args[] = $$form_state['values']['mail']; |
| 658 |
} |
} |
| 659 |
|
|
| 660 |
if (count($sql_where) > 0) { |
if (count($sql_where) > 0) { |
| 668 |
if (db_result(db_query($sql_stmt, $sql_args, 0, 1))) { |
if (db_result(db_query($sql_stmt, $sql_args, 0, 1))) { |
| 669 |
akismet_anti_spambot_action(array( |
akismet_anti_spambot_action(array( |
| 670 |
t('SQL') => _akismet_translate_query($sql_stmt, $sql_args), |
t('SQL') => _akismet_translate_query($sql_stmt, $sql_args), |
| 671 |
t('E-mail') => $form_values['mail'], |
t('E-mail') => $form_state['values']['mail'], |
| 672 |
t('Comment') => $form_values['comment'] |
t('Comment') => $form_state['values']['comment'] |
| 673 |
)); |
)); |
| 674 |
} |
} |
| 675 |
} |
} |
| 678 |
/** |
/** |
| 679 |
* Comment form submit callback; check for spam. |
* Comment form submit callback; check for spam. |
| 680 |
*/ |
*/ |
| 681 |
function _akismet_comment_form_submit($form_id, $form_values, $original_submit_callback = NULL) { |
function _akismet_comment_form_submit($form, &$form_state, $original_submit_callback = NULL) { |
| 682 |
// Our default destination. It doesn't need to override the original. |
// Our default destination. It doesn't need to override the original. |
| 683 |
$goto = NULL; |
$goto = NULL; |
| 684 |
|
|
| 685 |
// If the comment is being edited, then there's no problem to get the $cid. |
// If the comment is being edited, then there's no problem to get the $cid. |
| 686 |
// In this case, the original #submit callback has already been called. |
// In this case, the original #submit callback has already been called. |
| 687 |
if (isset($form_values['cid'])) { |
if (isset($form_state['values']['cid'])) { |
| 688 |
$cid = $form_values['cid']; |
$cid = $form_state['values']['cid']; |
| 689 |
} |
} |
| 690 |
// However, if the comment is being created, we'll try to get the $cid from the |
// However, if the comment is being created, we'll try to get the $cid from the |
| 691 |
// return value of the original #submit callback. It's an array that customizes |
// return value of the original #submit callback. It's an array that customizes |
| 743 |
|
|
| 744 |
// Record the event to watchdog. |
// Record the event to watchdog. |
| 745 |
if ($akismet_api_result == AKISMET_API_RESULT_ERROR) { |
if ($akismet_api_result == AKISMET_API_RESULT_ERROR) { |
| 746 |
watchdog('content', t('Akismet service seems to be down, comment queued for manual approval: %subject', array('%subject' => $comment->subject)), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid)); |
watchdog('content', 'Akismet service seems to be down, comment queued for manual approval: %subject', array('%subject' => $comment->subject), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid)); |
| 747 |
} |
} |
| 748 |
else { |
else { |
| 749 |
watchdog('content', t('Spam detected by Akismet in comment: %subject', array('%subject' => $comment->subject)), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid)); |
watchdog('content', 'Spam detected by Akismet in comment: %subject', array('%subject' => $comment->subject), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid)); |
| 750 |
// If requested to, generate a delay so the spammer has to wait for a while. |
// If requested to, generate a delay so the spammer has to wait for a while. |
| 751 |
if (($seconds = variable_get('akismet_antispambot_delay', 60)) > 0) { |
if (($seconds = variable_get('akismet_antispambot_delay', 60)) > 0) { |
| 752 |
sleep($seconds); |
sleep($seconds); |
| 830 |
$message = t('Spambot detected (action: 503 Service unavailable).'); |
$message = t('Spambot detected (action: 503 Service unavailable).'); |
| 831 |
} |
} |
| 832 |
|
|
| 833 |
watchdog('akismet', $message .'<p>'. t('Additional information:') .'</p>'. theme('item_list', $items)); |
watchdog('akismet', '%message<p>Additional information:</p>%items', array('%message' => $message, '%items' => theme('item_list', $items))); |
| 834 |
|
|
| 835 |
module_invoke_all('exit'); |
module_invoke_all('exit'); |
| 836 |
exit; |
exit; |
| 1016 |
$site_name = variable_get('site_name', t('Drupal')); |
$site_name = variable_get('site_name', t('Drupal')); |
| 1017 |
if ($content_type == 'comment') { |
if ($content_type == 'comment') { |
| 1018 |
if (!($node = akismet_content_load('node', $content->nid))) { |
if (!($node = akismet_content_load('node', $content->nid))) { |
| 1019 |
watchdog('akismet', t('An error has ocurred while trying to notify moderators about a comment. The associated node could not be loaded.'), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid)); |
watchdog('akismet', 'An error has ocurred while trying to notify moderators about a comment. The associated node could not be loaded.', array(), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid)); |
| 1020 |
return; |
return; |
| 1021 |
} |
} |
| 1022 |
$message_args = array( |
$message_args = array( |
| 1059 |
, $message_args); |
, $message_args); |
| 1060 |
|
|
| 1061 |
// Log the notification to watchdog. |
// Log the notification to watchdog. |
| 1062 |
watchdog('akismet', t('Trying to notify the following recipients: %emails', array('%emails' => implode(', ', array_keys($unique_emails))))); |
watchdog('akismet', 'Trying to notify the following recipients: %emails', array('%emails' => implode(', ', array_keys($unique_emails)))); |
| 1063 |
|
|
| 1064 |
// Send e-mails. |
// Send e-mails. |
| 1065 |
foreach ($unique_emails as $email_to => $uid) { |
foreach ($unique_emails as $email_to => $uid) { |
| 1289 |
} |
} |
| 1290 |
|
|
| 1291 |
/** |
/** |
| 1292 |
|
* Implementation of hook_theme(). |
| 1293 |
|
*/ |
| 1294 |
|
function akismet_theme() { |
| 1295 |
|
return array( |
| 1296 |
|
'akismet_counter_block' => array( |
| 1297 |
|
'arguments' => array( |
| 1298 |
|
'args' => array( |
| 1299 |
|
'content', |
| 1300 |
|
'counter', |
| 1301 |
|
'since', |
| 1302 |
|
'text' => array( |
| 1303 |
|
'plain' => array('short', 'long'), |
| 1304 |
|
'html' => array('short', 'long'), |
| 1305 |
|
), |
| 1306 |
|
'image', |
| 1307 |
|
'block', |
| 1308 |
|
), |
| 1309 |
|
), |
| 1310 |
|
), |
| 1311 |
|
); |
| 1312 |
|
} |
| 1313 |
|
|
| 1314 |
|
/** |
| 1315 |
* Allow themes customize the content of the akismet spam counter block. |
* Allow themes customize the content of the akismet spam counter block. |
| 1316 |
* |
* |
| 1317 |
* @param array arguments where each element is: |
* @param array arguments where each element is: |
| 1389 |
} |
} |
| 1390 |
|
|
| 1391 |
// Record the event to watchdog. |
// Record the event to watchdog. |
| 1392 |
watchdog('content', t('%type: deleted @title.', array('%type' => t($node->type), '@title' => $node->title))); |
watchdog('content', '%type: deleted @title.', array('%type' => t($node->type), '@title' => $node->title)); |
| 1393 |
return TRUE; |
return TRUE; |
| 1394 |
} |
} |
| 1395 |
} |
} |
| 1442 |
} |
} |
| 1443 |
|
|
| 1444 |
if ($op == 'submit-spam') { |
if ($op == 'submit-spam') { |
| 1445 |
$hostname = (!empty($content->hostname) ? $content->hostname : $_SERVER['REMOTE_ADDR']); |
$hostname = (!empty($content->hostname) ? $content->hostname : ip_address()); |
| 1446 |
db_query('INSERT INTO {akismet_spam_marks} (content_type, content_id, spam_created, hostname, mail) VALUES (\'%s\', %d, %d, \'%s\', \'%s\')', $content_type, $content_id, time(), $hostname, $user_mail); |
db_query('INSERT INTO {akismet_spam_marks} (content_type, content_id, spam_created, hostname, mail) VALUES (\'%s\', %d, %d, \'%s\', \'%s\')', $content_type, $content_id, time(), $hostname, $user_mail); |
| 1447 |
|
|
| 1448 |
if (variable_get('akismet_connection_enabled', 1)) { |
if (variable_get('akismet_connection_enabled', 1)) { |
| 1466 |
} |
} |
| 1467 |
|
|
| 1468 |
if ($log_action) { |
if ($log_action) { |
| 1469 |
watchdog('content', t('@action: @title', array('@action' => $action, '@title' => $content_title)), WATCHDOG_NOTICE, $content_link); |
watchdog('content', '@action: @title', array('@action' => $action, '@title' => $content_title), WATCHDOG_NOTICE, $content_link); |
| 1470 |
} |
} |
| 1471 |
akismet_clear_cache(); |
akismet_clear_cache(); |
| 1472 |
} |
} |
| 1489 |
|
|
| 1490 |
if ($log_action) { |
if ($log_action) { |
| 1491 |
$action = ($op == 'publish' ? t('Content published') : t('Content unpublished')); |
$action = ($op == 'publish' ? t('Content published') : t('Content unpublished')); |
| 1492 |
watchdog('content', t('@action: @title', array('@action' => $action, '@title' => $content->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid)); |
watchdog('content', '@action: @title', array('@action' => $action, '@title' => $content->title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid)); |
| 1493 |
} |
} |
| 1494 |
} |
} |
| 1495 |
else { // comment |
else { // comment |
| 1513 |
|
|
| 1514 |
if ($log_action) { |
if ($log_action) { |
| 1515 |
$action = ($op == 'publish' ? t('Comment published') : t('Comment unpublished')); |
$action = ($op == 'publish' ? t('Comment published') : t('Comment unpublished')); |
| 1516 |
watchdog('content', t('@action: %subject', array('@action' => $action, '%subject' => $content->subject)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid)); |
watchdog('content', '@action: %subject', array('@action' => $action, '%subject' => $content->subject), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid)); |
| 1517 |
} |
} |
| 1518 |
} |
} |
| 1519 |
|
|
| 1531 |
// Prepare data that is common to nodes/comments. |
// Prepare data that is common to nodes/comments. |
| 1532 |
$comment_data = array( |
$comment_data = array( |
| 1533 |
// IP address of the comment submitter. |
// IP address of the comment submitter. |
| 1534 |
'user_ip' => (!empty($content->hostname) ? $content->hostname : $_SERVER['REMOTE_ADDR']), |
'user_ip' => (!empty($content->hostname) ? $content->hostname : ip_address()), |
| 1535 |
// User agent information of the comment submitter. |
// User agent information of the comment submitter. |
| 1536 |
'user_agent' => $_SERVER['HTTP_USER_AGENT'], |
'user_agent' => $_SERVER['HTTP_USER_AGENT'], |
| 1537 |
// The content of the HTTP_REFERER header should be sent here. |
// The content of the HTTP_REFERER header should be sent here. |