1<?php
2
3/**
4 * Akismet plugin for use with the Linkback Plugin for DokuWiki
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Gina Haeussge <osd@foosel.net>
8 * @author     Andreas Gohr <gohr@cosmocode.de>
9 */
10
11// must be run within Dokuwiki
12if (!defined('DOKU_INC'))
13    die();
14
15if (!defined('DOKU_PLUGIN'))
16    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
17require_once (DOKU_PLUGIN . 'action.php');
18
19require_once (DOKU_INC . 'inc/common.php');
20require_once (DOKU_INC . 'inc/infoutils.php');
21
22class action_plugin_linkback_akismet extends DokuWiki_Action_Plugin {
23
24    /**
25     * register the eventhandlers
26     */
27    function register(Doku_Event_Handler $controller) {
28        $controller->register_hook('ACTION_LINKBACK_RECEIVED', 'BEFORE', $this, 'handle_linkback_received', array ());
29        $controller->register_hook('ACTION_LINKBACK_HAM', 'AFTER', $this, 'handle_linkback_ham', array ());
30        $controller->register_hook('ACTION_LINKBACK_SPAM', 'AFTER', $this, 'handle_linkback_spam', array ());
31    }
32
33    /**
34     * Handler for the ACTION_LINKBACK_RECEIVED event
35     */
36    function handle_linkback_received(Doku_Event $event, $param) {
37        $linkback = $event->data['linkback'];
38
39        $tools =& plugin_load('tools', 'linkback');
40
41        if (!$this->getConf('akismet_enable') || !$this->getConf('akismet_apikey'))
42            return;
43
44        $data = $this->_prepareData($linkback);
45        if ($this->_checkForSpam($data)) {
46            $event->data['log'][] = "\tAkismet marked linkback as spam";
47            $event->data['show'] = false;
48            if (!$this->getConf('akismet_moderate'))
49                $event->preventDefault();
50            else
51            	$event->data['log'][] = "\t -> moderated";
52        } else {
53        	$event->data['log'][] = "\tAkismet marked linkback as ham";
54        }
55
56        return;
57    }
58
59    /**
60     * Handler for the ACTION_LINKBACK_HAM event
61     */
62    function handle_linkback_ham(Doku_Event $event, $params) {
63        $linkback = $event->data['linkback'];
64
65        if (!$this->getConf('akismet_enabled') || !$this->getConf('akismet_apikey'))
66            return;
67
68        $data = $this->_prepareData($linkback);
69        $this->_reportHam($data);
70    }
71
72    /**
73     * Handler for the ACTION_LINKBACK_SPAM event
74     */
75    function handle_linkback_spam(Doku_Event $event, $params) {
76        $linkback = $event->data['linkback'];
77
78        if (!$this->getConf('akismet_enabled') || !$this->getConf('akismet_apikey'))
79            return;
80
81        $data = $this->_prepareData($linkback);
82        $this->_reportSpam($data);
83    }
84
85    /**
86     * Submit the data to the Akismet comment-check webservice and return whether it was
87     * classified as spam (true) or ham (false)
88     */
89    function _checkForSpam($data) {
90        $resp = $this->_submitData('comment-check', $data);
91        if ($resp == 'true')
92            return true;
93        return false;
94    }
95
96    /**
97     * Submit the data to the Akismet submit-ham webservice
98     */
99    function _reportHam($data) {
100        $this->_submitData('submit-ham', $data);
101    }
102
103    /**
104     * Submit the data to the Akismet submit-spam webservice
105     */
106    function _reportSpam($data) {
107        $this->_submitData('submit-spam', $data);
108    }
109
110    /**
111     * Prepares the data to send to Akismet
112     */
113    function _prepareData($linkback) {
114        $data = array (
115            'blog' => DOKU_URL,
116            'user_ip' => $linkback['submitter_ip'],
117            'user_agent' => $linkback['submitter_useragent'],
118            'referrer' => $linkback['submitter_referer'],
119            'comment_author_url' => $linkback['url'],
120            'comment_type' => $linkback['type'],
121            'comment_content' => $linkback['raw_excerpt'],
122        );
123
124        return $data;
125    }
126
127    /**
128     * Submits the given data to the given Akismet service.
129     *
130     * @param $function string  Akismet service to use. Can be
131     *                          'comment-check', 'submit-ham' or
132     *                          'submit-spam'
133     * @param $data     array   Linkback data to submit
134     * @return          string  The response of Akismet
135     */
136    function _submitData($function, $data) {
137        $info = $this->getInfo();
138        $http = new DokuHTTPClient();
139        // The Aksimet guys ask for a verbose UserAgent:
140        $http->agent = 'DokuWiki/' . getVersion() . ' | ' . $info['name'] . '/' . $info['date'];
141        $http->timeout = 5;
142        $resp = $http->post('http://' . $this->getConf('akismet_apikey') . '.rest.akismet.com/1.1/comment-check', $data);
143        return $resp;
144    }
145
146}
147