* @link http://wiki.foosel.net/snippets/dokuwiki/linkback
*/
class action_plugin_linkback_antispam extends DokuWiki_Action_Plugin {
/**
* Register the eventhandlers.
*/
function register(Doku_Event_Handler $controller) {
$controller->register_hook('ACTION_LINKBACK_RECEIVED', 'BEFORE', $this, 'handle_linkback_received', array ());
}
/**
* Handler for the ACTION_LINKBACK_RECEIVED event.
*/
function handle_linkback_received(Doku_Event $event, $param) {
$linkback = $event->data['trackback_data'];
$page = $event->data['page'];
$target = $event->data['target'];
if ($this->getConf('antispam_linkcount_enable') && !$this->_clean_linkcount($linkback['raw_excerpt'])) {
$event->data['log'][] = "\tLinkcount exceeded, marked as spam";
$event->data['show'] = false;
if (!$this->getConf('antispam_linkcount_moderate'))
$event->preventDefault();
else
$event->data['log'][] = "\t -> moderated";
} else {
$event->data['log'][] = "\tLinkcount ok, marked as ham";
}
if ($this->getConf('antispam_wordblock_enable') && !$this->_clean_wordblock($linkback['raw_excerpt'])) {
$event->data['log'][] = "\tWordblock active, marked as spam";
$event->data['show'] = false;
if (!$this->getConf('antispam_wordblock_moderate'))
$event->preventDefault();
else
$event->data['log'][] = "\t -> moderated";
} else {
$event->data['log'][] = "\tWordblock ok, marked as ham";
}
if ($this->getConf('antispam_host_enable') && !$this->_clean_host($linkback['url'], $linkback['submitter_ip'])) {
$event->data['log'][] = "\tHosts do not match, marked as spam";
$event->data['show'] = false;
if (!$this->getConf('antispam_host_moderate'))
$event->preventDefault();
else
$event->data['log'][] = "\t -> moderated";
} else {
$event->data['log'][] = "\tHosts ok, marked as ham";
}
if ($this->getConf('antispam_link_enable') && !$this->_clean_link($target, $page, $linkback['type'])) {
$event->data['log'][] = "\tURL not contained in linking page, marked as spam";
$event->data['show'] = false;
if (!$this->getConf('antispam_link_moderate'))
$event->preventDefault();
else
$event->data['log'][] = "\t -> moderated";
} else {
$event->data['log'][] = "\tURL found in linking page, marked as ham";
}
}
/**
* Check against linkcount limit.
*/
function _clean_linkcount($excerpt) {
$regex = '!!is';
if (preg_match($regex, $excerpt) > $this->getConf('antispam_linkcount_max'))
return false;
return true;
}
/**
* Check against wordblock.
*/
function _clean_wordblock($excerpt) {
global $TEXT;
$otext = $TEXT;
$TEXT = $excerpt;
$retval = checkwordblock();
$TEXT = $otext;
return !$retval;
}
/**
* Check whether source host matches requesting host.
*/
function _clean_host($sourceUri, $remote_addr) {
$urlparts = parse_url($sourceUri);
$source_addr = gethostbyname($urlparts['host']);
return ($source_addr == $remote_addr);
}
/**
* Check whether linking page contains link to us.
*
* Only used for trackbacks (pingbacks get this treatment right on arrival
* for excerpt extraction anyway...)
*/
function _clean_link($targetUri, $page, $type) {
if ($type == 'pingback')
return true;
$searchurl = preg_quote($targetUri, '!');
$regex = '!]+?href="' . $searchurl . '"[^>]*?>(.*?)!is';
$regex2 = '!\s(' . $searchurl . ')\s!is';
if (!preg_match($regex, $page['body'], $match) && !preg_match($regex2, $page['body'], $match)) {
if ($this->getConf('ping_internal') && (strstr($targetUri, DOKU_URL) == $targetUri)) {
$ID = substr($_SERVER['PATH_INFO'], 1);
$searchurl = preg_quote(wl($ID), '!');
$regex = '!]+?href="' . $searchurl . '"[^>]*?>(.*?)!is';
$regex2 = '!\s(' . $searchurl . ')\s!is';
if (!preg_match($regex, $page['body'], $match) && !preg_match($regex2, $page['body'], $match))
return false;
} else {
return false;
}
}
return true;
}
}