'smarty' => '2.6.7',
'php' => '4.1.0'
));
- $propbag->add('version', '1.40');
+ $propbag->add('version', '1.50');
$propbag->add('event_hooks', array(
'frontend_saveComment' => true,
'external_plugin' => true,
'backend_comments_top' => true,
'backend_view_comment' => true
));
- $propbag->add('configuration', array('killswitch', 'hide_for_authors', 'bodyclone', 'entrytitle', 'ipflood', 'captchas', 'captchas_ttl', 'captcha_color', 'forcemoderation', 'disable_api_comments', 'trackback_check_url', 'links_moderate', 'links_reject', 'contentfilter_activate', 'contentfilter_urls', 'bloggdeblacklist', 'contentfilter_authors', 'hide_email', 'checkmail', 'required_fields', 'logtype', 'logfile'));
+ $propbag->add('configuration', array(
+ 'killswitch',
+ 'hide_for_authors',
+ 'bodyclone',
+ 'entrytitle',
+ 'ipflood',
+ 'captchas',
+ 'captchas_ttl',
+ 'captcha_color',
+ 'forcemoderation',
+ 'disable_api_comments',
+ 'trackback_check_url',
+ 'links_moderate',
+ 'links_reject',
+ 'contentfilter_activate',
+ 'contentfilter_urls',
+ 'contentfilter_authors',
+ 'bloggdeblacklist',
+ 'akismet',
+ 'akismet_filter',
+ 'hide_email',
+ 'checkmail',
+ 'required_fields',
+ 'logtype',
+ 'logfile'));
$propbag->add('groups', array('ANTISPAM'));
$this->filter_defaults = array(
break;
+ case 'akismet':
+ $propbag->add('type', 'string');
+ $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_AKISMET);
+ $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_AKISMET_DESC);
+ $propbag->add('default', '');
+ $propbag->add('radio', array(
+ 'value' => array('moderate', 'reject', 'none'),
+ 'desc' => array(PLUGIN_EVENT_SPAMBLOCK_API_MODERATE, PLUGIN_EVENT_SPAMBLOCK_API_REJECT, NONE)
+ ));
+ $propbag->add('radio_per_row', '1');
+
+ break;
+
+ case 'akismet_filter':
+ $propbag->add('type', 'radio');
+ $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_AKISMET_FILTER);
+ $propbag->add('description', '');
+ $propbag->add('default', 'reject');
+ $propbag->add('radio', array(
+ 'value' => array('moderate', 'reject', 'none'),
+ 'desc' => array(PLUGIN_EVENT_SPAMBLOCK_API_MODERATE, PLUGIN_EVENT_SPAMBLOCK_API_REJECT, NONE)
+ ));
+ $propbag->add('radio_per_row', '1');
+
+ break;
+
case 'contentfilter_urls':
$propbag->add('type', 'text');
$propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_FILTER_URLS);
return true;
}
- function getBlacklist($where) {
+ function &getBlacklist($where, $api_key = '', &$eventData, &$addData) {
global $serendipity;
+ $ret = false;
+ if (function_exists('serendipity_request_start')) serendipity_request_start();
switch($where) {
+ case 'akismet.com':
+ $ret = array();
+ $data = array(
+ 'blog' => $serendipity['baseURL'],
+ 'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+ 'referrer' => $_SERVER['HTTP_REFERER'],
+ 'user_ip' => $_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR') ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR'),
+ 'permalink' => serendipity_archiveURL($eventData['id'], $eventData['title'], 'serendipityHTTPPath', true, array('timestamp' => $eventData['timestamp'])),
+ 'comment_type' => ($addData['type'] == 'NORMAL' ? 'comment' : 'trackback'),
+ 'comment_author' => $addData['name'],
+ 'comment_author_email' => $addData['email'],
+ 'comment_author_url' => $addData['url'],
+ 'comment_content' => $addData['comment']
+ );
+ $opt = array(
+ 'method' => 'POST',
+ 'http' => '1.1',
+ 'timeout' => 20,
+ 'allowRedirects' => true,
+ 'maxRedirects' => 3
+ );
+
+ require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
+
+ $req = &new HTTP_Request(
+ 'http://rest.akismet.com/1.1/verify-key',
+ $opt
+ );
+
+ $req->addPostData('key', $api_key);
+ $req->addPostData('blog', $serendipity['baseURL']);
+
+ if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
+ $ret['is_spam'] = false;
+ $ret['message'] = 'API Verification Request failed';
+ $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet HTTP verification request failed.', $addData);
+ break;
+ } else {
+ // Fetch response
+ $reqdata = $req->getResponseBody();
+ }
+
+ if (!preg_match('@valid@i', $reqdata)) {
+ $ret['is_spam'] = false;
+ $ret['message'] = 'API Verification failed';
+ $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet API verification failed: ' . $reqdata, $addData);
+ break;
+ }
+
+ $req = &new HTTP_Request(
+ 'http://' . $api_key . '.rest.akismet.com/1.1/comment-check',
+ $opt
+ );
+
+ foreach($data AS $key => $value) {
+ $req->addPostData($key, $value);
+ }
+
+ if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
+ $ret['is_spam'] = false;
+ $ret['message'] = 'Akismet Request failed';
+ $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet HTTP request failed.', $addData);
+ break;
+ } else {
+ // Fetch response
+ $reqdata = $req->getResponseBody();
+ }
+
+ if (preg_match('@true@i', $reqdata)) {
+ $ret['is_spam'] = true;
+ $ret['message'] = $reqdata;
+ } elseif (preg_match('@false@i', $reqdata)) {
+ $ret['is_spam'] = false;
+ $ret['message'] = $reqdata;
+ $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet API verification failed: ' . $reqdata, $addData);
+ } else {
+ $ret['is_spam'] = false;
+ $ret['message'] = 'Akismet API failure';
+ $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet API failure: ' . $reqdata, $addData);
+ }
+
+ break;
+
case 'blogg.de':
$target = $serendipity['serendipityPath'] . PATH_SMARTY_COMPILE . '/blogg.de.blacklist.txt';
$timeout = 3600; // One hour
$data = file_get_contents($target);
} else {
$data = '';
- require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
+
$req = &new HTTP_Request('http://spam.blogg.de/blacklist.txt');
if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
}
$blacklist = explode("\n", $data);
- return $blacklist;
+ $ret =& $blacklist;
default:
- return false;
+ break;
}
+
+ if (function_exists('serendipity_request_end')) serendipity_request_end();
+ return $ret;
}
function checkScheme($maxVersion) {
}
$serendipity['csuccess'] = 'true';
- $logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log');
+ $logfile = $this->logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log');
$required_fields = $this->get_config('required_fields', '');
// Check required fields
}
}
+ // Filter Akismet Blacklist?
+ $akismet_apikey = $this->get_config('akismet');
+ $akismet = $this->get_config('akismet_filter');
+ if (!empty($akismet_apikey) && ($akismet == 'moderate' || $akismet == 'reject')) {
+ $spam = $this->getBlacklist('akismet.com', $akismet_apikey, $eventData, $addData);
+ if ($spam['is_spam'] !== false) {
+ if ($akismet == 'moderate') {
+ $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST . ': ' . $spam['message'], $addData);
+ $eventData['moderate_comments'] = true;
+ $serendipity['csuccess'] = 'moderate';
+ $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+ } else {
+ $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST . ': ' . $spam['message'], $addData);
+ $eventData = array('allow_comments' => false);
+ $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+ return false;
+ }
+ }
+ }
+
// Check Trackback URLs?
if ($addData['type'] == 'TRACKBACK' && serendipity_db_bool($this->get_config('trackback_check_url'))) {
require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
+ if (function_exists('serendipity_request_start')) serendipity_request_start();
$req = &new HTTP_Request($addData['url'], array('allowRedirects' => true, 'maxRedirects' => 5));
$is_valid = false;
if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
$is_valid = false;
}
}
+ if (function_exists('serendipity_request_end')) serendipity_request_end();
if ($is_valid === false) {
$this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_TRACKBACKURL, $addData);
}
}
}
+ }
- // Filter Content
- $filter_bodys = explode(';', $this->get_config('contentfilter_words', $this->filter_defaults['words']));
- if (is_array($filter_bodys)) {
- foreach($filter_bodys AS $filter_body) {
- if (empty($filter_body)) {
- continue;
- }
- if (preg_match('@' . $filter_body . '@', $addData['comment'])) {
- if ($filter_type == 'moderate') {
- $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
- $eventData['moderate_comments'] = true;
- $serendipity['csuccess'] = 'moderate';
- $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
- } else {
- $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
- $eventData = array('allow_comments' => false);
- $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
- return false;
- }
+ // Filter Content
+ $filter_bodys = explode(';', $this->get_config('contentfilter_words', $this->filter_defaults['words']));
+ if (is_array($filter_bodys)) {
+ foreach($filter_bodys AS $filter_body) {
+ if (empty($filter_body)) {
+ continue;
+ }
+ if (preg_match('@' . $filter_body . '@', $addData['comment'])) {
+ if ($filter_type == 'moderate') {
+ $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
+ $eventData['moderate_comments'] = true;
+ $serendipity['csuccess'] = 'moderate';
+ $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+ } else {
+ $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
+ $eventData = array('allow_comments' => false);
+ $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+ return false;
}
}
}
}
+ } // Content filtering end
+
+ // Filter Blogg.de Blacklist?
+ $bloggdeblacklist = $this->get_config('bloggdeblacklist');
+ if ($bloggdeblacklist == 'moderate' || $bloggdeblacklist == 'reject') {
+ $domains = $this->getBlacklist('blogg.de', '', $eventData, $addData);
+ if (is_array($domains)) {
+ foreach($domains AS $domain) {
+ $domain = trim($domain);
+ if (empty($domain)) {
+ continue;
+ }
- // Filter Blogg.de Blacklist?
- $bloggdeblacklist = $this->get_config('bloggdeblacklist');
- if ($bloggdeblacklist == 'moderate' || $bloggdeblacklist == 'reject') {
- $domains = $this->getBlacklist('blogg.de');
- if (is_array($domains)) {
- foreach($domains AS $domain) {
- $domain = trim($domain);
- if (empty($domain)) {
- continue;
- }
-
- if (preg_match('@' . preg_quote($domain) . '@i', $addData['url'])) {
- if ($bloggdeblacklist == 'moderate') {
- $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
- $eventData['moderate_comments'] = true;
- $serendipity['csuccess'] = 'moderate';
- $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
- } else {
- $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
- $eventData = array('allow_comments' => false);
- $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
- return false;
- }
+ if (preg_match('@' . preg_quote($domain) . '@i', $addData['url'])) {
+ if ($bloggdeblacklist == 'moderate') {
+ $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
+ $eventData['moderate_comments'] = true;
+ $serendipity['csuccess'] = 'moderate';
+ $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+ } else {
+ $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
+ $eventData = array('allow_comments' => false);
+ $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+ return false;
}
}
}