View source
<?php
define('ANTISPAM_DRUPAL_VERSION', '7');
define('ANTISPAM_MODULE_VERSION', '1.0');
define('ANTISPAM_MODULE_HOMEURL', 'http://www.drupal.org/project/antispam');
define('ANTISPAM_MODULE_USERAGENT', 'Drupal/' . ANTISPAM_DRUPAL_VERSION . ' | antispam.module/' . ANTISPAM_MODULE_VERSION);
define('ANTISPAM_AKISMET_API_HOST', 'rest.akismet.com');
define('ANTISPAM_AKISMET_API_PORT', 80);
define('ANTISPAM_AKISMET_API_VERSION', '1.1');
define('ANTISPAM_API_USERAGENT', 'Drupal/' . ANTISPAM_DRUPAL_VERSION . ' | antispam.module/' . ANTISPAM_MODULE_VERSION);
define('ANTISPAM_API_RESULT_ERROR', -1);
define('ANTISPAM_API_RESULT_SUCCESS', 0);
define('ANTISPAM_API_RESULT_IS_SPAM', 1);
define('ANTISPAM_API_RESULT_IS_HAM', 2);
define('ANTISPAM_AKISMET_SERVICE', 0);
define('ANTISPAM_COUNT_ALL', 0);
define('ANTISPAM_COUNT_SPAM_DETECTED', 1);
define('ANTISPAM_COUNT_HAM_DETECTED', 2);
define('ANTISPAM_COUNT_FALSE_NEGATIVE', 3);
define('ANTISPAM_COUNT_FALSE_POSITIVE', 4);
function antispam_debug($str) {
if (is_array($str) || is_object($str)) {
error_log(print_r($str, TRUE) . "\r\n", 3, "/tmp/antispam.txt");
}
else {
error_log($str . "\r\n", 3, "/tmp/antispam.txt");
}
}
function antispam_help($path, $arg) {
switch ($path) {
case 'admin/help#antispam':
$output = t('<p>In order to use the AntiSpam, you need a API key for the selected antispam service. If you don\'t have one already, you can get it by simply signing up for a free account at the following sites.</p>
<ul>
<li><a href="!akismet">akismet.com</a> for Akismet service
</ul>
<p>The <em>antispam 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="!permission">Permission</a> panel, to grant <em>%no-check-perm</em> permission to <em>user roles</em> of your choice.</p>
<p>Content marked as <em>spam</em> is still saved into database so it can be reviewed by content administrators. There is <a href="!antispam-settings">an option</a> that allows you to specify how long this information will be kept in the database. <em>Spam</em> older than a specified age will be automatically removed. Requires crontab.</p>
<p>Automatic spam detection can be enabled or disabled by content type and/or comments. In addition to this, the antspam service makes it easy for <em>content administrators</em> to manually <em>publish</em>/<em>unpublish</em> content and <em>mark</em>/<em>unmark</em> content as spam, from links available at the bottom of content.</p>', array(
'!akismet' => url('http://akismet.com'),
'!antispam-settings' => url('admin/config/spamprevention/antispam'),
'!permission' => url('admin/people/permissions'),
'%no-check-perm' => t('post with no antispam checking'),
));
return $output;
case 'admin/help/antispam':
case 'admin/config/spamprevention/antispam':
$output = t('<p>The <a href="!antispam-module-home">AntiSpam module</a> for <a href="!drupal">Drupal</a> allows you to use the <a href="!akismet">Akismet</a> anti-spam service to protect your site from being spammed.</p>', array(
'!antispam-module-home' => url(ANTISPAM_MODULE_HOMEURL),
'!drupal' => url('http://drupal.org'),
'!akismet' => url('http://akismet.com'),
));
$output .= t('<p>AntiSpam has caught <strong>@count spam</strong> for you since %since.</p>', array(
'@count' => antispam_get_total_counter(ANTISPAM_COUNT_SPAM_DETECTED),
'%since' => antispam_get_counting_since(),
));
return $output;
case 'admin/content/antispam/nodes/unpublished':
$output = t('Below is the list of <strong>unpublished nodes</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.');
break;
case 'admin/content/antispam/nodes/published':
$output = t('Below is the list of <strong>published nodes</strong>.');
$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.');
break;
case 'admin/content/antispam/nodes':
$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.');
break;
case 'admin/content/antispam/comments/unpublished':
$output = t('Below is the list of <strong>unpublished comments</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.');
break;
case 'admin/content/antispam/comments/published':
$output = t('Below is the list of <strong>published comments</strong>.');
$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.');
break;
case 'admin/content/antispam/comments':
$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.');
break;
}
if (arg(0) == 'admin' && arg(1) == 'content ' && arg(2) == 'antispam' && !isset($_POST) && !empty($output)) {
$output .= '<br />';
$output .= t('<strong>Note:</strong> To interact fully with the antispam service, 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 the antispam service learn from its mistakes. Thank you.');
}
}
function antispam_permission() {
$permissions = array(
'administer antispam settings' => array(
'title' => t('Administer AntiSpam module'),
'description' => '',
),
);
$names = node_type_get_names();
foreach ($names as $type => $name) {
$index = 'moderate spam in nodes of type ' . $name;
$permissions[$index] = array(
'title' => t('Moderate spam in nodes of type !type', array(
'!type' => $name,
)),
'description' => '',
);
}
$permissions['moderate spam in comments'] = array(
'title' => t('Moderate spam in comments'),
'description' => '',
);
$permissions['post with no antispam checking'] = array(
'title' => t('Post with no spam checking'),
'description' => 'Allow to post nodes/comments without being checked by AntiSpam module. ',
);
return $permissions;
}
function antispam_cron() {
module_load_include('inc', 'antispam', 'antispam.cron');
module_load_include('inc', 'comment', 'comment.admin');
antispam_cron_shutdown();
}
function antispam_get_service_provider() {
return variable_get('antispam_service_provider', 0);
}
function antispam_get_provider_name($provider, $with_link = FALSE) {
switch ($provider) {
case ANTISPAM_AKISMET_SERVICE:
return $with_link ? t('<a href="http://akismet.com">Akismet</a>') : t('Akismet');
default:
return '';
}
}
function antispam_get_api_host($provider) {
switch ($provider) {
case ANTISPAM_AKISMET_SERVICE:
$api_host = ANTISPAM_AKISMET_API_HOST;
break;
}
return $api_host;
}
function antispam_get_api_key($provider) {
switch ($provider) {
case ANTISPAM_AKISMET_SERVICE:
$api_key = variable_get('antispam_wpapikey', '');
break;
}
return $api_key;
}
function antispam_get_max_counter($counter_type = '') {
$rec = db_query("SELECT MAX(spam_detected) AS max_spam, MAX(ham_detected) AS max_ham, MAX(false_negative) AS max_fnegative, MAX(false_positive) AS max_fpositive FROM {antispam_counter}")
->fetchObject();
if ($rec->max_spam == '') {
$rec->max_spam = 0;
}
if ($rec->max_ham == '') {
$rec->max_ham = 0;
}
if ($rec->max_fnegative == '') {
$rec->max_fnegative = 0;
}
if ($rec->max_fpositive == '') {
$rec->max_fpositive = 0;
}
if (empty($counter_type)) {
return array(
'max_spam' => $rec->max_spam,
'max_ham' => $rec->max_ham,
'max_fnegative' => $rec->max_fnegative,
'max_fpositive' => $rec->max_fpositive,
);
}
switch ($counter_type) {
case ANTISPAM_COUNT_ALL:
return $rec->max_spam + $rec->max_ham;
case ANTISPAM_COUNT_SPAM_DETECTED:
return $rec->max_spam;
case ANTISPAM_COUNT_HAM_DETECTED:
return $rec->max_ham;
case ANTISPAM_COUNT_FALSE_NEGATIVE:
return $rec->max_fnegative;
case ANTISPAM_COUNT_FALSE_POSITIVE:
return $rec->max_fpositive;
default:
return 0;
}
}
function antispam_get_total_counter($counter_type = '') {
$rec = db_query("SELECT SUM(spam_detected) AS total_spam, SUM(ham_detected) AS total_ham, SUM(false_negative) AS total_fnegative, SUM(false_positive) AS total_fpositive FROM {antispam_counter}")
->fetchObject();
if ($rec->total_spam == '') {
$rec->total_spam = 0;
}
if ($rec->total_ham == '') {
$rec->total_ham = 0;
}
if ($rec->total_fnegative == '') {
$rec->total_fnegative = 0;
}
if ($rec->total_fpositive == '') {
$rec->total_fpositive = 0;
}
if (empty($counter_type)) {
return array(
'total_spam' => $rec->total_spam,
'total_ham' => $rec->total_ham,
'total_fnegative' => $rec->total_fnegative,
'total_fpositive' => $rec->total_fpositive,
);
}
switch ($counter_type) {
case ANTISPAM_COUNT_ALL:
return $rec->total_spam + $rec->total_ham;
case ANTISPAM_COUNT_SPAM_DETECTED:
return $rec->total_spam;
case ANTISPAM_COUNT_HAM_DETECTED:
return $rec->total_ham;
case ANTISPAM_COUNT_FALSE_NEGATIVE:
return $rec->total_fnegative;
case ANTISPAM_COUNT_FALSE_POSITIVE:
return $rec->total_fpositive;
default:
return 0;
}
}
function antispam_get_counter($counter_type) {
$rec = db_query("SELECT * FROM {antispam_counter} WHERE date=:date", array(
':date' => mktime(0, 0, 0, date("m"), date("d"), date("Y")),
))
->fetchObject();
if (empty($rec)) {
return 0;
}
switch ($counter_type) {
case ANTISPAM_COUNT_ALL:
return $rec->spam_detected + $rec->ham_detected;
case ANTISPAM_COUNT_SPAM_DETECTED:
return $rec->spam_detected;
case ANTISPAM_COUNT_HAM_DETECTED:
return $rec->ham_detected;
case ANTISPAM_COUNT_FALSE_NEGATIVE:
return $rec->false_negative;
case ANTISPAM_COUNT_FALSE_POSITIVE:
return $rec->false_positive;
default:
return 0;
}
}
function antispam_set_counter($counter_type, $count) {
switch ($counter_type) {
case ANTISPAM_COUNT_ALL:
return;
case ANTISPAM_COUNT_SPAM_DETECTED:
$field = 'spam_detected';
break;
case ANTISPAM_COUNT_HAM_DETECTED:
$field = 'ham_detected';
break;
case ANTISPAM_COUNT_FALSE_NEGATIVE:
$field = 'false_negative';
break;
case ANTISPAM_COUNT_FALSE_POSITIVE:
$field = 'false_positive';
break;
default:
return;
}
$today = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
$result = db_query("SELECT * FROM {antispam_counter} WHERE date=:date", array(
':date' => $today,
));
if ($result
->rowCount()) {
db_update('antispam_counter')
->fields(array(
$field => $count,
))
->condition('date', $today)
->execute();
}
else {
$provider = antispam_get_service_provider();
db_insert('antispam_counter')
->fields(array(
'date' => strtotime(date('Y-m-d 00:00:00')),
'provider' => $provider,
$field => $count,
))
->execute();
}
}
function antispam_increase_counter($counter_type) {
antispam_set_counter($counter_type, antispam_get_counter($counter_type) + 1);
}
function _antispam_moderator_types_count($types = array()) {
if (empty($types)) {
$types = antispam_get_moderator_types();
}
return count($types);
}
function _antispam_is_moderator($moderator_types = array(), $type = '') {
global $user;
if ($user->uid == 1) {
return TRUE;
}
if (empty($moderator_types)) {
$moderator_types = antispam_get_moderator_types();
}
if (_antispam_moderator_types_count($moderator_types) > 0 && (empty($type) || isset($moderator_types[$type]))) {
return TRUE;
}
else {
return FALSE;
}
}
function _antispam_is_node_moderator($moderator_types = array()) {
global $user;
if ($user->uid == 1) {
return TRUE;
}
if (empty($moderator_types)) {
$moderator_types = antispam_get_moderator_types();
}
if (_antispam_is_moderator($moderator_types) && (!_antispam_is_moderator($moderator_types, $type = 'comments') || _antispam_moderator_types_count($moderator_types) > 1)) {
return TRUE;
}
else {
return FALSE;
}
}
function _antispam_is_moderator_type($type, $types = array()) {
if (empty($types)) {
$types = antispam_get_moderator_types();
}
if (_antispam_moderator_types_count($types) > 0 && isset($types[$type])) {
return TRUE;
}
else {
return FALSE;
}
}
function antispam_menu() {
$items = array();
$moderator_types = antispam_get_moderator_types();
$items['admin/config/spamprevention'] = array(
'title' => 'AntiSpam',
'description' => 'Use the anti-spam service to protect your site from spam.',
'position' => 'right',
'page callback' => 'system_admin_menu_block_page',
'access arguments' => array(
'access administration pages',
),
'file' => 'system.admin.inc',
'file path' => drupal_get_path('module', 'system'),
);
$items['admin/config/spamprevention/antispam'] = array(
'title' => t('AntiSpam'),
'description' => t('Use the anti-spam service to protect your site from spam.'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'antispam_settings_form',
),
'access arguments' => array(
'administer antispam settings',
),
'file' => 'antispam.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/content/antispam/overview'] = array(
'title' => 'Overview',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/nodes'] = array(
'title' => 'Nodes',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'nodes',
),
'access callback' => '_antispam_is_node_moderator',
'access arguments' => array(
$moderator_types,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/nodes/spam'] = array(
'title' => 'Spam',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'nodes',
),
'access callback' => '_antispam_is_node_moderator',
'access arguments' => array(
$moderator_types,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/nodes/unpublished'] = array(
'title' => 'Unpublished nodes',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'nodes',
'unpublished',
),
'access callback' => '_antispam_is_node_moderator',
'access arguments' => array(
$moderator_types,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/nodes/published'] = array(
'title' => 'Published nodes',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'nodes',
'published',
),
'access callback' => '_antispam_is_node_moderator',
'access arguments' => array(
$moderator_types,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'antispam.admin.inc',
);
if (module_exists('comment')) {
$items['admin/content/antispam/comments'] = array(
'title' => 'Comments',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'comments',
),
'access callback' => '_antispam_is_moderator',
'access arguments' => array(
$moderator_types,
'comments',
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/comments/spam'] = array(
'title' => 'Spam',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'comments',
),
'access callback' => '_antispam_is_moderator',
'access arguments' => array(
$moderator_types,
'comments',
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/comments/unpublished'] = array(
'title' => 'Unpublished comments',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'comments',
'unpublished',
),
'access callback' => '_antispam_is_moderator',
'access arguments' => array(
$moderator_types,
'comments',
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => 'antispam.admin.inc',
);
$items['admin/content/antispam/comments/published'] = array(
'title' => 'Published comments',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'comments',
'published',
),
'access callback' => '_antispam_is_moderator',
'access arguments' => array(
$moderator_types,
'comments',
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'antispam.admin.inc',
);
}
$items['admin/content/antispam/statistics'] = array(
'title' => 'Statistics',
'page callback' => 'antispam_callback_queue',
'page arguments' => array(
'statistics',
),
'access callback' => '_antispam_is_moderator',
'access arguments' => array(
$moderator_types,
),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
'file' => 'antispam.admin.inc',
);
$item = array(
'title' => 'switch content status',
'page callback' => 'antispam_page',
'page arguments' => array(
0,
1,
2,
3,
),
'load arguments' => array(
'%map',
'%index',
),
'access callback' => 'antispam_access_callback',
'access arguments' => array(
0,
1,
2,
3,
),
);
foreach (array(
'publish',
'unpublish',
'submit-spam',
'submit-ham',
) as $op) {
$items['antispam/%antispam/%/' . $op] = $item;
}
return $items;
}
function antispam_load($arg, &$map, $index) {
if (!is_numeric($map[2])) {
return FALSE;
}
$content_type = $map[1];
if ($content_type == 'node') {
if (!($map[2] = node_load($map[2]))) {
return FALSE;
}
}
if ($content_type == 'comment') {
if (!($map[2] = comment_load($map[2]))) {
return FALSE;
}
}
$op = $map[3];
if ($op == 'publish' || $op == 'unpublish') {
$map[0] = 'antispam_callback_set_published_status';
}
elseif ($op == 'submit-spam' || $op == 'submit-ham') {
$map[0] = 'antispam_callback_set_spam_status';
}
return $map[$index];
}
function antispam_access_callback($callback, $content_type, $object, $op) {
if ($content_type == 'node' && !node_access('update', $object)) {
return FALSE;
}
$content_id = '';
if ($content_type == 'node') {
$content_id = $object->nid;
}
elseif ($content_type == 'comment') {
$content_id = $object->cid;
}
if (function_exists($callback && !antispam_is_spam_moderator(antispam_content_get_moderator_type($content_type, $content_id)))) {
return FALSE;
}
return TRUE;
}
function antispam_page($callback, $content_type, $object, $op) {
if (function_exists($callback)) {
return $callback($content_type, $object, $op);
}
drupal_not_found();
}
function antispam_callback_set_published_status($content_type, $object, $op) {
if ($content_type == 'node') {
$content = antispam_content_load($content_type, $object->nid);
$is_published = $content->status ? TRUE : FALSE;
}
else {
$content = antispam_content_load($content_type, $object->cid);
$is_published = $content->status == COMMENT_PUBLISHED ? TRUE : FALSE;
}
if ($op == 'publish' && !$is_published) {
antispam_content_publish_operation($content_type, $content, 'publish');
}
elseif ($op == 'unpublish' && $is_published) {
antispam_content_publish_operation($content_type, $content, 'unpublish');
}
if ($content_type == 'node') {
drupal_goto('node/' . $content->nid);
}
else {
drupal_goto('node/' . $content->nid, array(
'fragment' => 'comment-' . $content->cid,
));
}
}
function antispam_callback_set_spam_status($content_type, $object, $op) {
if ($content_type == 'node') {
$is_spam = antispam_content_is_spam($content_type, $object->nid);
$content = antispam_content_load($content_type, $object->nid);
$is_published = $content->status ? TRUE : FALSE;
}
else {
$is_spam = antispam_content_is_spam($content_type, $object->cid);
$content = antispam_content_load($content_type, $object->cid);
$is_published = $content->status == COMMENT_PUBLISHED ? TRUE : FALSE;
}
if ($op == 'submit-spam') {
if (!$is_spam) {
antispam_content_spam_operation($content_type, $content, 'submit-spam');
antispam_increase_counter(ANTISPAM_COUNT_FALSE_NEGATIVE);
}
if ($is_published) {
antispam_content_publish_operation($content_type, $content, 'unpublish');
}
}
elseif ($op == 'submit-ham') {
if ($is_spam) {
antispam_content_spam_operation($content_type, $content, 'submit-ham');
antispam_increase_counter(ANTISPAM_COUNT_FALSE_POSITIVE);
}
if (!$is_published) {
antispam_content_publish_operation($content_type, $content, 'publish');
}
}
if ($content_type == 'node') {
drupal_goto('node/' . $content->nid);
}
else {
drupal_goto('node/' . $content->nid, array(
'fragment' => 'comment-' . $content->cid,
));
}
}
function antispam_webform_check($form, &$form_state) {
if (variable_get('antispam_webform_enabled', FALSE)) {
foreach ($form_state['values']['submitted'] as $value) {
if (is_string($value) && !is_numeric($value) && strlen($value) > 5 && antispam_api_cmd_spam_check($value) === ANTISPAM_API_RESULT_IS_SPAM) {
watchdog('spam detected', "Spam detected in webform value '%value'", array(
'%value' => $value,
), WATCHDOG_NOTICE);
form_error($form_state['clicked_button'], t('Invalid input'));
return;
}
}
}
}
function antispam_node_load($nodes, $types) {
foreach ($nodes as $node) {
$rec = db_query("SELECT signature, spaminess FROM {antispam_spam_marks} WHERE content_type='node' AND content_id=:content_id", array(
':content_id' => $node->nid,
))
->fetchObject();
if ($rec) {
$node->signature = $rec->signature;
$node->spaminess = $rec->spaminess;
}
else {
$node->signature = '';
$node->spaminess = 0.0;
}
}
}
function antispam_node_insert($node) {
_antispam_node_save($node);
}
function antispam_node_update($node) {
_antispam_node_save($node);
}
function _antispam_node_save(&$node) {
if (!variable_get('antispam_connection_enabled', 1)) {
antispam_notify_moderators('node', $node, $node->status ? TRUE : FALSE, FALSE);
return;
}
if (antispam_is_spam_moderator($node->type) || user_access('post with no antispam checking')) {
antispam_notify_moderators('node', $node, $node->status ? TRUE : FALSE, FALSE);
return;
}
$check_nodetypes = variable_get('antispam_check_nodetypes', array());
if (!is_array($check_nodetypes) || !isset($check_nodetypes[$node->type]) || !$check_nodetypes[$node->type]) {
antispam_notify_moderators('node', $node, $node->status ? TRUE : FALSE, FALSE);
return;
}
$api_result = antispam_api_cmd_comment_check('node', $node);
if ($api_result[0] == ANTISPAM_API_RESULT_IS_HAM) {
antispam_notify_moderators('node', $node, $node->status ? TRUE : FALSE, FALSE);
antispam_increase_counter(ANTISPAM_COUNT_HAM_DETECTED);
}
else {
if ($api_result[0] == ANTISPAM_API_RESULT_IS_SPAM) {
$node->signature = $api_result[1];
$node->spaminess = $api_result[2];
antispam_increase_counter(ANTISPAM_COUNT_SPAM_DETECTED);
antispam_notify_moderators('node', $node, FALSE, TRUE);
}
else {
antispam_notify_moderators('node', $node, FALSE, FALSE);
}
if ($node->status) {
antispam_content_publish_operation('node', $node, 'unpublish', FALSE);
}
$content_type_name = node_type_get_name($node);
drupal_set_message(t('Your %content-type-name has been queued for moderation by site administrators and will be published after approval.', array(
'%content-type-name' => $content_type_name,
)));
if ($api_result[0] == ANTISPAM_API_RESULT_ERROR) {
watchdog('content', 'AntiSpam 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));
}
else {
watchdog('content', 'Spam detected by AntiSpam in %content-type-name: %title', array(
'%content-type-name' => $content_type_name,
'%title' => $node->title,
), WATCHDOG_WARNING, l(t('view'), 'node/' . $node->nid));
if (($seconds = variable_get('antispam_antispambot_delay', 60)) > 0) {
sleep($seconds);
}
}
}
}
function antispam_node_validate($node, $form, &$form_state) {
global $user;
$num_condition = 0;
$debug_info = array();
$antispambot_rules = antispam_get_anti_spambot_rules();
$query = db_select('antispam_spam_marks', 's');
if (!empty($antispambot_rules['body'])) {
$query
->join('field_data_body', 'e', 'e.entity_id = s.content_id');
}
$query
->fields('s', array(
'content_id',
));
if (!empty($antispambot_rules['body'])) {
$query
->addField('e', 'body_value', 'body');
}
$query
->condition('s.content_type', 'node');
$query
->range(0, 1);
if (!empty($antispambot_rules['ip'])) {
$query
->condition('s.hostname', ip_address());
$debug_info['IP-address'] = ip_address();
$num_condition++;
}
if (!empty($antispambot_rules['mail']) && !empty($user->mail)) {
$query
->condition('s.mail', $user->mail);
$debug_info['E-mail'] = $user->mail;
$num_condition++;
}
if (!empty($antispambot_rules['body']) && !empty($node->body)) {
$query
->condition('e.body_value', $node->body[$node->language][0]['value']);
$debug_info['Content'] = $node->body[$node->language][0]['value'];
$num_condition++;
}
if ($num_condition) {
$has_rows = $query
->execute()
->fetchField();
if ($has_rows) {
antispam_anti_spambot_action($debug_info);
}
}
}
function antispam_node_delete($node) {
db_delete('antispam_spam_marks')
->condition('content_type', 'node')
->condition('content_id', $node->nid)
->execute();
}
function antispam_node_view($node, $view_mode, $langcode) {
if (antispam_is_spam_moderator($node->type)) {
$links = array();
if (variable_get('antispam_node_publish_links', 0)) {
if ($node->status) {
$links['antispam_node_unpublish'] = array(
'title' => t('Unpublish'),
'href' => 'antispam/node/' . $node->nid . '/unpublish',
);
}
else {
$links['antispam_node_publish'] = array(
'title' => t('Publish'),
'href' => 'antispam/node/' . $node->nid . '/publish',
);
}
}
if (variable_get('antispam_node_spam_links', 0)) {
if (antispam_content_is_spam('node', $node->nid)) {
$links['antispam_node_ham'] = array(
'title' => t('Not Spam'),
'href' => 'antispam/node/' . $node->nid . '/submit-ham',
);
}
else {
$links['antispam_node_spam'] = array(
'title' => t('Spam'),
'href' => 'antispam/node/' . $node->nid . '/submit-spam',
);
}
}
$node->content['links']['node']['#links'] = array_merge($node->content['links']['node']['#links'], $links);
}
}
function antispam_comment_load($comments) {
foreach ($comments as $comment) {
$rec = db_query("SELECT signature, spaminess FROM {antispam_spam_marks} WHERE content_type='comment' AND content_id=:content_id", array(
':content_id' => $comment->cid,
))
->fetchObject();
if ($rec) {
$comment->signature = $rec->signature;
$comment->spaminess = $rec->spaminess;
}
else {
$comment->spaminess = 0.0;
}
}
}
function antispam_comment_presave($comment) {
$num_condition = 0;
$debug_info = array();
$antispambot_rules = antispam_get_anti_spambot_rules();
$query = db_select('antispam_spam_marks', 's');
$query
->fields('s', array(
'content_id',
));
$query
->condition('s.content_type', 'comment');
$query
->range(0, 1);
$rules_conditions = db_or();
if (!empty($antispambot_rules['ip'])) {
$rules_conditions
->condition('s.hostname', ip_address());
$debug_info['IP-address'] = ip_address();
$num_condition++;
}
if (!empty($antispambot_rules['mail']) && !empty($comment->mail)) {
$rules_conditions
->condition('s.mail', $comment->mail);
$debug_info['E-mail'] = $comment->mail;
$num_condition++;
}
if (!empty($antispambot_rules['body']) && !empty($comment->comment_body)) {
if ($num_condition) {
$join_type = 'LEFT OUTER';
}
else {
$join_type = 'INNER';
}
$query
->addJoin($join_type, 'field_data_comment_body', 'c', 's.content_type = c.entity_type AND s.content_id = c.entity_id');
$rules_conditions
->condition('c.comment_body_value', $comment->comment_body[$comment->language][0]['value']);
$debug_info['Content'] = $comment->comment_body[$comment->language][0]['value'];
$num_condition++;
}
if ($num_condition) {
$query
->condition($rules_conditions);
$has_rows = $query
->execute()
->fetchField();
if ($has_rows) {
antispam_anti_spambot_action($debug_info);
}
}
}
function antispam_comment_insert($comment) {
_antispam_comment_save($comment);
}
function antispam_comment_update($comment) {
_antispam_comment_save($comment);
}
function _antispam_comment_save($comment) {
if (!variable_get('antispam_connection_enabled', 1)) {
antispam_notify_moderators('node', $node, $node->status ? TRUE : FALSE, FALSE);
return;
}
if (antispam_is_spam_moderator('comments') || user_access('post with no antispam checking')) {
antispam_notify_moderators('comment', $comment, $comment->status == COMMENT_PUBLISHED ? TRUE : FALSE, FALSE);
return;
}
$api_result = antispam_api_cmd_comment_check('comment', $comment);
if ($api_result[0] == ANTISPAM_API_RESULT_IS_HAM) {
watchdog('antispam', '_antispam_comment_save: it is HAM');
antispam_notify_moderators('comment', $comment, $comment->status == COMMENT_PUBLISHED ? TRUE : FALSE, FALSE);
antispam_increase_counter(ANTISPAM_COUNT_HAM_DETECTED);
}
else {
if ($api_result[0] == ANTISPAM_API_RESULT_IS_SPAM) {
watchdog('antispam', '_antispam_comment_save: it is SPAM');
$comment->signature = $api_result[1];
$comment->spaminess = $api_result[2];
antispam_increase_counter(ANTISPAM_COUNT_SPAM_DETECTED);
antispam_notify_moderators('comment', $comment, FALSE, TRUE);
}
else {
watchdog('antispam', '_antispam_comment_save: it is ERROR');
antispam_notify_moderators('comment', $comment, FALSE, FALSE);
}
if ($comment->status == COMMENT_PUBLISHED) {
antispam_content_publish_operation('comment', $comment, 'unpublish', FALSE);
}
if ($api_result[0] == ANTISPAM_API_RESULT_ERROR) {
watchdog('content', 'AntiSpam service seems to be down, comment queued for manual approval: %subject', array(
'%subject' => $comment->subject,
), WATCHDOG_WARNING, l(t('view'), 'node/' . $comment->nid, array(
'fragment' => 'comment-' . $comment->cid,
)));
}
else {
watchdog('content', 'Spam detected by AntiSpam in comment: %subject', array(
'%subject' => $comment->subject,
), WATCHDOG_WARNING, l(t('view'), 'node/' . $comment->nid, array(
'fragment' => 'comment-' . $comment->cid,
)));
if (($seconds = variable_get('antispam_antispambot_delay', 60)) > 0) {
sleep($seconds);
}
}
}
}
function antispam_comment_delete($comment) {
db_delete('antispam_spam_marks')
->condition('content_type', 'comment')
->condition('content_id', $comment->cid)
->execute();
}
function antispam_comment_view($comment, $view_mode, $langcode) {
if (antispam_is_spam_moderator('comments')) {
$links = array();
if (variable_get('antispam_comment_publish_links', 1)) {
if ($comment->status == COMMENT_PUBLISHED) {
$links['antispam_comment_unpublish'] = array(
'title' => t('Unpublish'),
'href' => 'antispam/comment/' . $comment->cid . '/unpublish',
);
}
elseif ($comment->status == COMMENT_NOT_PUBLISHED) {
$links['antispam_comment_publish'] = array(
'title' => t('Publish'),
'href' => 'antispam/comment/' . $comment->cid . '/publish',
);
}
}
if (variable_get('antispam_comment_spam_links', 1)) {
if (antispam_content_is_spam('comment', $comment->cid)) {
$links['antispam_comment_ham'] = array(
'title' => t('Not Spam'),
'href' => 'antispam/comment/' . $comment->cid . '/submit-ham',
);
}
else {
$links['antispam_comment_spam'] = array(
'title' => t('Spam'),
'href' => 'antispam/comment/' . $comment->cid . '/submit-spam',
);
}
}
$comment->content['links']['comment']['#links'] = array_merge($comment->content['links']['comment']['#links'], $links);
}
}
function antispam_get_anti_spambot_rules() {
static $antispambot_rules = FALSE;
if (!$antispambot_rules) {
$antispambot_rules = array();
$options = variable_get('antispam_antispambot_rules', array());
if (is_array($options)) {
foreach ($options as $key => $value) {
if (is_string($key)) {
$antispambot_rules[$key] = $key === $value ? TRUE : FALSE;
}
}
}
}
return $antispambot_rules;
}
function antispam_is_anti_spambot_enabled() {
$antispambot_rules = antispam_get_anti_spambot_rules();
return count($antispambot_rules) > 0 ? TRUE : FALSE;
}
function antispam_anti_spambot_action($debug_info) {
$antispambot_action = variable_get('antispam_antispambot_action', '503');
if (($seconds = variable_get('antispam_antispambot_delay', 60)) > 0) {
sleep($seconds);
}
if ($antispambot_action == 'none') {
return;
}
$items = array();
foreach ($debug_info as $label => $value) {
$items[] = '<strong>' . check_plain($label) . '</strong>: ' . check_plain($value);
}
if ($antispambot_action == '403d') {
drupal_access_denied();
$message = t('Spambot detected (action: 403 Forbidden).');
}
elseif ($antispambot_action == '403') {
@header('HTTP/1.0 403 Forbidden');
print t('Access denied');
$message = t('Spambot detected (action: 403 Forbidden).');
}
else {
@header('HTTP/1.0 503 Service unavailable');
print t('Service unavailable');
$message = t('Spambot detected (action: 503 Service unavailable).');
}
watchdog('antispam', '%message<p>Additional information:</p>%items', array(
'%message' => $message,
'%items' => theme('item_list', $items),
));
module_invoke_all('exit');
exit;
}
function _antispam_translate_query($query) {
$args = func_get_args();
array_shift($args);
$query = db_prefix_tables($query);
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
_db_query_callback($args, TRUE);
$query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
return $query;
}
function antispam_content_is_spam($content_type, $content_id) {
return db_query_range('SELECT 1 FROM {antispam_spam_marks} WHERE content_type=:content_type AND content_id=:content_id', 0, 1, array(
':content_type' => $content_type,
':content_id' => $content_id,
))
->fetchField();
}
function antispam_content_get_moderator_type($content_type, $content_id) {
watchdog('antispam', 'antispam_content_get_moderator_type is called. type=' . $content_type . ', id=' . $content_id);
if ($content_type == 'node') {
$moderator_type = db_query('SELECT type FROM {node} WHERE nid=:nid', array(
':nid' => $content_id,
))
->fetchField();
if (!$moderator_type) {
$moderator_type = '';
}
}
elseif ($content_type == 'comment') {
$has_rows = db_query_range('SELECT 1 FROM {comment} WHERE cid=:cid', 0, 1, array(
':cid' => $content_id,
))
->fetchField();
$moderator_type = $has_rows ? 'comments' : '';
}
else {
$moderator_type = '';
}
return $moderator_type;
}
function antispam_get_moderator_types($account = NULL) {
global $user;
static $node_types = FALSE;
static $moderator_types = array();
if (is_null($account)) {
$account = $user;
}
if ($node_types === FALSE) {
$node_types = node_type_get_names();
}
$moderator_types[$account->uid] = NULL;
if (!isset($moderator_types[$account->uid])) {
if (user_access('administer nodes', $account)) {
foreach ($node_types as $type => $name) {
$moderator_types[$account->uid][$type] = $name;
}
}
else {
foreach ($node_types as $type => $name) {
if (user_access('moderate spam in nodes of type ' . $node_types[$type], $account)) {
$moderator_types[$account->uid][$type] = $name;
}
}
}
if (module_exists('comment') && (user_access('administer comments', $account) || user_access('moderate spam in comments', $account))) {
$moderator_types[$account->uid]['comments'] = t('comments');
}
}
return $moderator_types[$account->uid];
}
function antispam_is_spam_moderator($moderator_type = NULL, $account = NULL) {
global $user;
if (is_null($account)) {
$account = $user;
}
$moderator_types = antispam_get_moderator_types($account);
if (is_null($moderator_type)) {
return count($moderator_types) > 0 ? TRUE : FALSE;
}
return isset($moderator_types[$moderator_type]);
}
function antispam_notify_moderators($content_type, $content, $is_published, $is_spam) {
global $user, $base_url;
if (!variable_get('antispam_email_enabled', 0)) {
return;
}
$content = (object) $content;
if ($content_type == 'comment') {
$moderator_permission = 'moderate spam in comments';
$administer_permission = 'administer comments';
}
else {
$moderator_types = antispam_get_moderator_types();
$moderator_permission = 'moderate spam in nodes of type ' . $moderator_types[$content->type];
$administer_permission = 'administer nodes';
}
$sql = 'SELECT u.uid, u.name, u.mail, m.email_for' . ' FROM {role_permission} p' . ' INNER JOIN {users_roles} r ON r.rid = p.rid' . ' INNER JOIN {users} u ON u.uid = r.uid OR u.uid = 1' . ' LEFT JOIN {antispam_moderator} m ON m.uid = u.uid' . ' WHERE p.permission LIKE :perm1' . ' OR p.permission LIKE :perm2';
$result = db_query($sql, array(
':perm1' => '%' . $moderator_permission . '%',
':perm2' => '%' . $administer_permission . '%',
));
$moderators = array();
foreach ($result as $u) {
if ($u->uid != $user->uid) {
$moderators[$u->uid] = array(
'name' => $u->name,
'email_to' => $u->mail,
'email_for' => !is_null($u->email_for) ? $u->email_for : 'approval',
);
}
}
$sql = 'SELECT u.uid, u.name, u.mail, m.email_for' . ' FROM {users} u' . ' LEFT JOIN {antispam_moderator} m ON m.uid = u.uid' . ' WHERE u.uid=1';
$u = db_query($sql)
->fetchObject();
if (!empty($u)) {
if ($u->uid != $user->uid) {
$moderators[$u->uid] = array(
'name' => $u->name,
'email_to' => $u->mail,
'email_for' => !is_null($u->email_for) ? $u->email_for : 'approval',
);
}
}
$unique_emails = array();
foreach ($moderators as $uid => $moderator) {
if ($moderator['email_for'] == 'all' || $moderator['email_for'] == 'approval' && !$is_published) {
if (!isset($unique_emails[$moderator['email_to']])) {
$unique_emails[$moderator['email_to']] = $uid;
}
}
}
if (count($unique_emails) <= 0) {
return;
}
$site_name = variable_get('site_name', t('Drupal'));
if ($content_type == 'comment') {
if (!($node = antispam_content_load('node', $content->nid))) {
watchdog('antispam', '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, array(
'fragment' => 'comment-' . $content->cid,
)));
return;
}
$message_args = array(
'@title-label' => t('Subject'),
'@content-title' => $content->subject,
'@content-type' => t('comment'),
'!content-link' => url('node/' . $content->nid, array(
'fragment' => 'comment-' . $content->cid,
'absolute' => TRUE,
)),
);
}
else {
$message_args = array(
'@title-label' => t('Title'),
'@content-title' => $content->title,
'@content-type' => $moderator_types[$content->type],
'!content-link' => url('node/' . $content->nid, array(
'absolute' => TRUE,
)),
);
}
$message_args['@content-status'] = ($is_published ? t('published') : t('not published')) . ($is_spam ? ' (' . t('marked as spam') . ')' : '');
$message_args['@site-name'] = $site_name;
$message_args['!site-link'] = $base_url . base_path();
$message_title = t('[@site-name] moderator notification - Posted @content-type \'@content-title\'', $message_args);
$message_body = t(<<<EOT
Hello @user-name,
You can use the following information to review this @content-type:
@title-label: @content-title
URL: !content-link
Status: @content-status
Please, do not reply to this e-mail. It is an automated notification you are receiving because you are a moderator at @site-name. If you no longer wish to receive such notifications, you can change your moderator settings in your user profile.
Thank you
!site-link
EOT
, $message_args);
watchdog('antispam', 'Trying to notify the following recipients: %emails', array(
'%emails' => implode(', ', array_keys($unique_emails)),
));
foreach ($unique_emails as $email_to => $uid) {
$message_body = str_replace('@user-name', check_plain($moderators[$uid]['name']), $message_body);
$params = array(
'body' => $message_body,
'subject' => $message_title,
);
drupal_mail('antispam', date("Y-m-d"), $email_to, language_default(), $params);
}
}
function antispam_mail($key, &$message, $params) {
$headers = array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
'Content-Transfer-Encoding' => '8Bit',
'X-Mailer' => 'Drupal',
);
foreach ($headers as $key => $value) {
$message['headers'][$key] = $value;
}
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
}
function _antispam_get_email_for_options() {
return array(
'all' => t('All new (or updated) content'),
'approval' => t('Only content needing approval'),
'never' => t('Never'),
);
}
function antispam_form_alter(&$form, &$form_state, $form_id) {
if (strpos($form_id, 'webform_client_form_') !== FALSE) {
$form['#validate'][] = 'antispam_webform_check';
}
if (!($form_id == 'user_register_form' || $form_id == 'user_profile_form')) {
return;
}
if (!variable_get('antispam_email_enabled', 1)) {
return;
}
$uid = $form['#user']->uid;
$antispam_moderator_email_for = isset($form['#user']->antispam_moderator_email_for) ? $form['#user']->antispam_moderator_email_for : 'approval';
$moderator_email_for_options = _antispam_get_email_for_options();
$moderator_types = antispam_get_moderator_types(NULL);
$moderator_types_count = count($moderator_types);
if (!$moderator_types_count) {
return;
}
$form['antispam_moderator'] = array(
'#type' => 'fieldset',
'#title' => t('AntiSpam moderator settings'),
'#weight' => 5,
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#description' => t('You are currently moderator for the following content types: %types.', array(
'%types' => implode(', ', $moderator_types),
)),
);
$form['antispam_moderator']['antispam_moderator_email_for'] = array(
'#type' => 'radios',
'#title' => t('Send me e-mails for'),
'#options' => $moderator_email_for_options,
'#default_value' => isset($moderator_email_for_options[$antispam_moderator_email_for]) ? $antispam_moderator_email_for : 'approval',
);
}
function antispam_user_load($users) {
$moderator_email_for_options = _antispam_get_email_for_options();
foreach ($users as $user) {
$moderator_types = antispam_get_moderator_types($user);
$moderator_types_count = count($moderator_types);
if ($moderator_types_count > 0) {
$moderator_data = db_query('SELECT * FROM {antispam_moderator} WHERE uid=:uid', array(
':uid' => $user->uid,
))
->fetchObject();
$user->antispam_moderator_email_for = isset($moderator_data->email_for) && isset($moderator_email_for_options[$moderator_data->email_for]) ? $moderator_data->email_for : 'approval';
}
}
}
function antispam_user_insert(&$edit, $account, $category) {
$moderator_email_for_options = _antispam_get_email_for_options();
$moderator_types = antispam_get_moderator_types($account);
$moderator_types_count = count($moderator_types);
if ($moderator_types_count > 0 && isset($edit['antispam_moderator_email_for'])) {
if (!isset($moderator_email_for_options[$edit['antispam_moderator_email_for']])) {
$edit['antispam_moderator_email_for'] = 'approval';
}
$result = db_query("SELECT * FROM {antispam_moderator} WHERE uid=:uid", array(
':uid' => $account->uid,
));
if ($result
->rowCount()) {
db_update('antispam_moderator')
->fields(array(
'email_for' => $edit['antispam_moderator_email_for'],
))
->condition('uid', $account->uid)
->execute();
}
else {
db_insert('antispam_moderator')
->fields(array(
'uid' => $account->uid,
'email_for' => $edit['antispam_moderator_email_for'],
))
->execute();
}
$edit['antispam_moderator_email_for'] = NULL;
}
}
function antispam_user_update(&$edit, $account, $category) {
antispam_user_insert($edit, $account, $category);
}
function antispam_user_delete($account) {
db_delete('antispam_moderator')
->condition('uid', $account->uid)
->execute();
}
function antispam_get_counting_since() {
$since = variable_get('antispam_counter_since', array(
'day' => date('j'),
'month' => date('n'),
'year' => date('Y'),
));
$format = variable_get('antispam_counter_date_format', 'F j, Y');
$replace = array(
'd' => sprintf('%02d', $since['day']),
'j' => $since['day'],
'm' => sprintf('%02d', $since['month']),
'M' => format_date(gmmktime(0, 0, 0, $since['month'], 2, 1970), 'custom', 'M'),
'F' => format_date(gmmktime(0, 0, 0, $since['month'], 2, 1970), 'custom', 'F'),
'Y' => $since['year'],
);
return strtr($format, $replace);
}
function _antispam_get_block_fields() {
return array(
'type' => array(
'#type' => 'radios',
'#title' => t('Display counter as'),
'#options' => array(
'image' => t('Image'),
'text' => t('Text'),
),
'#default_value' => 'image',
),
'sitename' => array(
'#type' => 'radios',
'#title' => t('Show site name'),
'#options' => array(
'1' => t('Enabled'),
'0' => t('Disabled'),
),
'#default_value' => '1',
),
'newwin' => array(
'#type' => 'radios',
'#title' => t('Open AntiSpam link in new window'),
'#options' => array(
'1' => t('Enabled'),
'0' => t('Disabled'),
),
'#default_value' => '1',
),
);
}
function antispam_block_info() {
$blocks_counter = variable_get('antispam_blocks_counter', 1);
$blocks = array();
for ($i = 0; $i < $blocks_counter; $i++) {
$blocks[] = array(
'info' => t('AntiSpam spam counter (block: @count)', array(
'@count' => $i + 1,
)),
);
}
return $blocks;
}
function antispam_block_configure($delta = '') {
$block_fields = _antispam_get_block_fields();
if ($delta >= 0 && $delta < variable_get('antispam_blocks_counter', 1)) {
$form = array();
$form['description'] = array(
'#type' => 'item',
'#markup' => '<div class="description">' . t('These options allow to customize the look of this <em>antispam spam counter</em> block.') . '</div>',
);
$block_settings = variable_get('antispam_blocks_' . $delta, FALSE);
foreach ($block_fields as $field_key => $field_info) {
$field_name = 'antispam_blocks_' . $delta . '_' . $field_key;
$form[$field_name] = array();
foreach ($field_info as $key => $value) {
$form[$field_name][$key] = $value;
}
if ($block_settings && isset($block_settings[$field_key])) {
$form[$field_name]['#default_value'] = $block_settings[$field_key];
}
}
return $form;
}
}
function antispam_block_save($delta = '', $edit = array()) {
$block_fields = _antispam_get_block_fields();
if ($delta >= 0 && $delta < variable_get('antispam_blocks_counter', 1)) {
$block_settings = array();
foreach ($block_fields as $field_key => $field_info) {
$field_name = 'antispam_blocks_' . $delta . '_' . $field_key;
$block_settings[$field_key] = $edit[$field_name];
}
variable_set('antispam_blocks_' . $delta, $block_settings);
}
}
function antispam_block_view($delta = '') {
$block_fields = _antispam_get_block_fields();
if ($delta >= 0 && $delta < variable_get('antispam_blocks_counter', 1)) {
$block_settings = variable_get('antispam_blocks_' . $delta, FALSE);
if (!$block_settings) {
$block_settings = array();
}
$block_args = array(
'content' => '',
'counter' => antispam_get_total_counter(ANTISPAM_COUNT_SPAM_DETECTED),
'since' => antispam_get_counting_since(),
'text' => '',
'image' => '',
'block' => array(
'delta' => $delta,
),
);
foreach ($block_fields as $field_key => $field_info) {
if (!isset($block_settings[$field_key])) {
$block_settings[$field_key] = $field_info['#default_value'];
}
$block_args['block'][$field_key] = $block_settings[$field_key];
}
$target = $block_settings['newwin'] ? ' target="_blank"' : '';
$sitename = $block_settings['sitename'] ? variable_get('site_name', 'drupal') : t('This site');
$block_args['text'] = array(
'plain' => t('@site_name is proudly protected by AntiSpam, !spams caught since @since.', array(
'@site_name' => $sitename,
'!spams' => format_plural($block_args['counter'], '1 spam', '@count spams'),
'@since' => $block_args['since'],
)),
'html' => t('@site_name is proudly protected by <a href="!antispam"@target>AntiSpam</a>, %spams caught since @since', array(
'@site_name' => $sitename,
'!antispam' => url('http://drupal.org/project/antispam'),
'@target' => $target,
'%spams' => format_plural($block_args['counter'], '1 spam', '@count spams'),
'@since' => $block_args['since'],
)),
);
$title_text = $block_args['text']['plain'];
$image_url = base_path() . drupal_get_path('module', 'antispam') . '/antispam.png';
$block_args['image'] = '<img src="' . $image_url . '" title="' . $title_text . '" alt="' . $title_text . '" />';
if ($block_settings['type'] == 'image') {
$block_args['content'] = '<a href="http://drupal.org/project/antispam" title="' . $title_text . '"' . $target . '>' . $block_args['image'] . '</a>';
}
else {
$block_args['content'] = $block_args['text']['html'];
}
$block = array();
$block['subject'] = t('AntiSpam spam counter');
$block['content'] = theme('antispam_counter_block', $block_args);
return $block;
}
}
function antispam_theme() {
return array(
'antispam_moderation_form' => array(
'render element' => 'form',
'file' => 'antispam.admin.inc',
),
'antispam_counter_block' => array(
'variables' => array(
'args' => array(
'content',
'counter',
'since',
'text' => array(
'plain' => array(
'short',
'long',
),
'html' => array(
'short',
'long',
),
),
'image',
'block',
),
),
),
);
}
function theme_antispam_counter_block($args) {
return $args['content'];
}
function antispam_content_load($content_type, $content_id) {
switch ($content_type) {
case 'node':
$content = node_load($content_id);
break;
case 'comment':
$content = comment_load($content_id);
break;
}
return $content;
}
function antispam_content_delete($content_type, $content_id) {
module_load_include('inc', 'comment', 'comment.admin');
if ($content_type == 'node') {
node_delete($content_id);
return TRUE;
}
elseif ($content_type == 'comment') {
comment_delete($content_id);
return TRUE;
}
return FALSE;
}
function antispam_clear_cache() {
static $already_done = FALSE;
if (!$already_done) {
cache_clear_all();
$already_done = TRUE;
}
}
function antispam_content_spam_operation($content_type, $content, $op, $log_action = TRUE) {
watchdog('antispam', 'antispam_content_spam_operation: type=' . $content_type . ' . op=' . $op);
if ($content_type == 'node') {
global $user;
$content_id = $content->nid;
$content_title = $content->title;
$content_link = l(t('view'), 'node/' . $content->nid);
$user_mail = isset($user->mail) ? $user->mail : '';
}
else {
$content_id = $content->cid;
$content_title = $content->subject;
$content_link = l(t('view'), 'node/' . $content->nid, array(
'fragment' => 'comment-' . $content->cid,
));
$user_mail = $content->mail;
}
watchdog('antispam', 'antispam_content_spam_operation: content_id=' . $content_id);
if (!isset($content->signature)) {
$content->signature = '';
}
if (!isset($content->spaminess)) {
$content->spaminess = 0.0;
}
if ($op == 'submit-spam') {
if (variable_get('antispam_connection_enabled', 1)) {
antispam_api_cmd_submit_spam($content_type, $content);
$action = $content_type == 'node' ? t('Content submitted as spam') : t('Comment submitted as spam');
}
else {
$action = $content_type == 'node' ? t('Content marked as spam') : t('Comment marked as spam');
}
$hostname = !empty($content->hostname) ? $content->hostname : ip_address();
db_insert('antispam_spam_marks')
->fields(array(
'content_type' => $content_type,
'content_id' => $content_id,
'spam_created' => mktime(0, 0, 0, date("m"), date("d"), date("Y")),
'hostname' => $hostname,
'mail' => $user_mail,
'signature' => $content->signature,
'spaminess' => $content->spaminess,
))
->execute();
}
else {
if (variable_get('antispam_connection_enabled', 1)) {
antispam_api_cmd_submit_ham($content_type, $content);
$action = $content_type == 'node' ? t('Content submitted as ham') : t('Comment submitted as ham');
}
else {
$action = $content_type == 'node' ? t('Content marked as ham') : t('Comment marked as ham');
}
db_delete('antispam_spam_marks')
->condition('content_type', $content_type)
->condition('content_id', $content_id)
->execute();
}
if ($log_action) {
watchdog('content', '@action: @title', array(
'@action' => $action,
'@title' => $content_title,
), WATCHDOG_NOTICE, $content_link);
}
antispam_clear_cache();
}
function antispam_content_publish_operation($content_type, $content, $op, $log_action = TRUE) {
module_load_include('inc', 'comment', 'comment.admin');
if ($content_type == 'node') {
db_update('node')
->fields(array(
'status' => $op == 'publish' ? 1 : 0,
))
->condition('nid', $content->nid)
->execute();
db_update('node_revision')
->fields(array(
'status' => $op == 'publish' ? 1 : 0,
))
->condition('nid', $content->nid)
->condition('vid', $content->vid)
->execute();
entity_get_controller('node')
->resetCache(array(
$content->nid,
));
if ($log_action) {
$action = $op == 'publish' ? t('Content published') : t('Content unpublished');
watchdog('content', '@action: @title', array(
'@action' => $action,
'@title' => $content->title,
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $content->nid));
}
}
else {
if ($op == 'publish') {
comment_publish_action($content, array(
'cid' => $content->cid,
));
db_update('comment')
->fields(array(
'status' => COMMENT_PUBLISHED,
))
->condition('cid', $content->cid)
->execute();
module_invoke_all('comment_published', $content);
}
elseif ($op == 'unpublish') {
comment_unpublish_action($content, array(
'cid' => $content->cid,
));
db_update('comment')
->fields(array(
'status' => COMMENT_NOT_PUBLISHED,
))
->condition('cid', $content->cid)
->execute();
module_invoke_all('comment_unpublished', $content);
}
_comment_update_node_statistics($content->nid);
if ($log_action) {
$action = $op == 'publish' ? t('Comment published') : t('Comment unpublished');
watchdog('content', '@action: %subject', array(
'@action' => $action,
'%subject' => $content->subject,
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $content->nid, array(
'fragment' => 'comment-' . $content->cid,
)));
}
}
antispam_clear_cache();
}
function antispam_prepare_comment_data($content_type, $content, $provider) {
global $user, $base_url;
$comment_data = array(
'user_ip' => !empty($content->hostname) ? $content->hostname : ip_address(),
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'referrer' => $_SERVER['HTTP_REFERER'],
'comment_type' => '',
'comment_author' => $content->name,
);
if ($content_type == 'comment') {
$comment_data['permalink'] = url('node/' . $content->nid, array(
'fragment' => 'comment-' . $content->cid,
));
$comment_data['comment_author_email'] = $content->mail;
$comment_data['comment_author_url'] = $content->homepage;
$comment_data['comment_content'] = render($content->comment_body[$content->language][0]['value']);
if ($content->subject && $content->subject != $comment_data['comment_content']) {
$comment_data['comment_content'] = $content->subject . "\n\n" . $comment_data['comment_content'];
}
$comment_data['comment_content'] = trim($comment_data['comment_content']);
}
elseif ($content_type == 'node') {
$render = reset(entity_view('node', array(
$content,
)));
$rendered = drupal_html_to_text(drupal_render($render), 'a');
$comment_data['permalink'] = url('node/' . $content->nid);
$comment_data['comment_author_email'] = isset($user->mail) ? $user->mail : '';
$comment_data['comment_author_url'] = '';
$comment_data['comment_content'] = $rendered;
}
else {
$comment_data['permalink'] = '';
$comment_data['comment-author_email'] = isset($user->mail) ? $user->mail : isset($content->mail) ? $content->mail : '';
$comment_data['comment-author_url'] = isset($content->homepage) ? $content->homepage : '';
$comment_data['comment_content'] = render($content->body);
}
return $comment_data;
}
function antispam_api_cmd_verify_key($key, $provider) {
global $base_url;
if (empty($key)) {
return ANTISPAM_API_RESULT_ERROR;
}
$api_host = antispam_get_api_host($provider);
$request = 'key=' . $key . '&blog=' . $base_url . base_path();
$response = _antispam_api_http_post($request, $api_host, '/' . ANTISPAM_AKISMET_API_VERSION . '/verify-key');
if (!isset($response[1])) {
watchdog('antispam', "verifying a key: can not get a response back from the service provider " . antispam_get_provider_name($provider, FALSE));
return ANTISPAM_API_RESULT_ERROR;
}
return 'valid' == $response[1] ? ANTISPAM_API_RESULT_SUCCESS : ANTISPAM_API_RESULT_ERROR;
}
function antispam_api_cmd_spam_check($body, $name = NULL, $mail = NULL, $homepage = NULL) {
$provider = antispam_get_service_provider();
$api_host = antispam_get_api_host($provider);
$api_key = antispam_get_api_key($provider);
if (empty($api_key)) {
return array(
ANTISPAM_API_RESULT_ERROR,
);
}
$content = new stdClass();
$content->body = $body;
$content->name = $name;
$content->mail = $mail;
$content->homepage = $homepage;
$api_result = antispam_api_cmd_comment_check('other', $content);
if ($api_result[0] == ANTISPAM_API_RESULT_IS_HAM) {
return 0;
}
elseif ($api_result[0] == ANTISPAM_API_RESULT_IS_SPAM) {
return 1;
}
else {
return -1;
}
}
function antispam_api_cmd_comment_check($content_type, $content) {
if (!variable_get('antispam_connection_enabled', 1)) {
return array(
ANTISPAM_API_RESULT_ERROR,
);
}
$provider = antispam_get_service_provider();
$comment_data = antispam_prepare_comment_data($content_type, $content, $provider);
$api_host = antispam_get_api_host($provider);
$api_key = antispam_get_api_key($provider);
if (empty($api_key)) {
return array(
ANTISPAM_API_RESULT_ERROR,
);
}
$comment_data = array_merge(_antispam_api_prepare_request_data(), $comment_data);
$query_string = _antispam_api_build_query_string($comment_data);
$host = $api_key . '.' . $api_host;
$response = _antispam_api_http_post($query_string, $host, '/' . ANTISPAM_AKISMET_API_VERSION . '/comment-check');
if (!isset($response[1])) {
watchdog('antispam', "cheking a content failed: can not get a response back from the service provider " . antispam_get_provider_name($provider, FALSE));
return array(
ANTISPAM_API_RESULT_ERROR,
);
}
$result[0] = 'true' == $response[1] ? ANTISPAM_API_RESULT_IS_SPAM : ANTISPAM_API_RESULT_IS_HAM;
if (ANTISPAM_API_RESULT_IS_SPAM === $result[0]) {
if ($content_type == 'node') {
global $user;
$content_id = $content->nid;
$user_mail = isset($user->mail) ? $user->mail : '';
}
else {
$content_id = $content->cid;
$user_mail = $content->mail;
}
$hostname = !empty($content->hostname) ? $content->hostname : ip_address();
db_insert('antispam_spam_marks')
->fields(array(
'content_type' => $content_type,
'content_id' => $content_id,
'spam_created' => mktime(0, 0, 0, date("m"), date("d"), date("Y")),
'hostname' => $hostname,
'mail' => $user_mail,
))
->execute();
}
$result[1] = '';
$result[2] = 0.0;
return $result;
}
function antispam_api_cmd_submit_spam($content_type, $content) {
if (!variable_get('antispam_connection_enabled', 1)) {
return ANTISPAM_API_RESULT_ERROR;
}
$provider = antispam_get_service_provider();
$comment_data = antispam_prepare_comment_data($content_type, $content, $provider);
$api_host = antispam_get_api_host($provider);
$api_key = antispam_get_api_key($provider);
if (empty($api_key)) {
return ANTISPAM_API_RESULT_ERROR;
}
$query_string = _antispam_api_build_query_string($comment_data);
$host = $api_key . '.' . $api_host;
$response = _antispam_api_http_post($query_string, $host, '/' . ANTISPAM_AKISMET_API_VERSION . '/submit-spam');
if (!isset($response[1])) {
watchdog('antispam', "submitting spam: can not get a response back from the service provider " . antispam_get_provider_name($provider, FALSE));
return ANTISPAM_API_RESULT_ERROR;
}
else {
return ANTISPAM_API_RESULT_SUCCESS;
}
}
function antispam_api_cmd_submit_ham($content_type, $content) {
if (!variable_get('antispam_connection_enabled', 1)) {
return ANTISPAM_API_RESULT_ERROR;
}
$provider = antispam_get_service_provider();
$comment_data = antispam_prepare_comment_data($content_type, $content, $provider);
$api_host = antispam_get_api_host($provider);
$api_key = antispam_get_api_key($provider);
if (empty($api_key)) {
return ANTISPAM_API_RESULT_ERROR;
}
$query_string = _antispam_api_build_query_string($comment_data);
$host = $api_key . '.' . $api_host;
$response = _antispam_api_http_post($query_string, $host, '/' . ANTISPAM_AKISMET_API_VERSION . '/submit-ham');
if (!isset($response[1])) {
watchdog('antispam', "submitting ham: can not get a response back from the service provider " . antispam_get_provider_name($provider, FALSE));
return ANTISPAM_API_RESULT_ERROR;
}
else {
return ANTISPAM_API_RESULT_SUCCESS;
}
}
function _antispam_api_prepare_request_data() {
static $safe_to_send = array(
'CONTENT_LENGTH',
'CONTENT_TYPE',
'HTTP_ACCEPT',
'HTTP_ACCEPT_CHARSET',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_REFERER',
'HTTP_USER_AGENT',
'REMOTE_ADDR',
'REMOTE_PORT',
'SCRIPT_URI',
'SCRIPT_URL',
'SERVER_ADDR',
'SERVER_NAME',
'REQUEST_METHOD',
'REQUEST_URI',
'SCRIPT_NAME',
);
static $server_data;
if (!$server_data) {
$server_data = array();
foreach ($_SERVER as $key => $value) {
if (in_array($key, $safe_to_send)) {
$server_data[$key] = $value;
}
}
}
return $server_data;
}
function _antispam_api_build_query_string($array) {
global $base_url;
$string = 'blog=' . $base_url . base_path();
foreach ($array as $key => $value) {
$string .= '&' . $key . '=' . urlencode(stripslashes($value));
}
return $string;
}
function _antispam_api_http_post($request, $host, $path) {
$fsock_timeout = (int) variable_get('antispam_connection_timeout', 10);
$http_request = "POST {$path} HTTP/1.0\r\n" . "Host: {$host}\r\n" . "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" . 'Content-Length: ' . strlen($request) . "\r\n" . 'User-Agent: ' . ANTISPAM_API_USERAGENT . "\r\n" . "\r\n" . $request;
$response = '';
if (false !== ($fs = @fsockopen($host, ANTISPAM_AKISMET_API_PORT, $errno, $errstr, $fsock_timeout))) {
fwrite($fs, $http_request);
while (!feof($fs)) {
$response .= fgets($fs, 1160);
}
fclose($fs);
$response = explode("\r\n\r\n", $response, 2);
}
return $response;
}