Dotclear

source: plugins/akismet/class.dc.filter.akismet.php @ 3874:ab8368569446

Revision 3874:ab8368569446, 7.3 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

short notation for array (array() → [])

Line 
1<?php
2/**
3 * @brief akismet, an antispam filter plugin for Dotclear 2
4 *
5 * @package Dotclear
6 * @subpackage Plugins
7 *
8 * @copyright Olivier Meunier & Association Dotclear
9 * @copyright GPL-2.0-only
10 */
11
12if (!defined('DC_RC_PATH')) {return;}
13
14class dcFilterAkismet extends dcSpamFilter
15{
16    public $name    = 'Akismet';
17    public $has_gui = true;
18    public $active  = false;
19    public $help    = 'akismet-filter';
20
21    public function __construct($core)
22    {
23        parent::__construct($core);
24
25        if (defined('DC_AKISMET_SUPER') && DC_AKISMET_SUPER && !$core->auth->isSuperAdmin()) {
26            $this->has_gui = false;
27        }
28    }
29
30    protected function setInfo()
31    {
32        $this->description = __('Akismet spam filter');
33    }
34
35    public function getStatusMessage($status, $comment_id)
36    {
37        return sprintf(__('Filtered by %s.'), $this->guiLink());
38    }
39
40    private function akInit()
41    {
42        $blog = &$this->core->blog;
43
44        if (!$blog->settings->akismet->ak_key) {
45            return false;
46        }
47
48        return new akismet($blog->url, $blog->settings->akismet->ak_key);
49    }
50
51    public function isSpam($type, $author, $email, $site, $ip, $content, $post_id, &$status)
52    {
53        if (($ak = $this->akInit()) === false) {
54            return;
55        }
56
57        $blog = &$this->core->blog;
58
59        try
60        {
61            if ($ak->verify()) {
62                $post = $blog->getPosts(['post_id' => $post_id]);
63
64                $c = $ak->comment_check(
65                    $post->getURL(),
66                    $type,
67                    $author,
68                    $email,
69                    $site,
70                    $content
71                );
72
73                if ($c) {
74                    $status = 'Filtered by Akismet';
75                    return true;
76                }
77            }
78        } catch (Exception $e) {} # If http or akismet is dead, we don't need to know it
79    }
80
81    public function trainFilter($status, $filter, $type, $author, $email, $site, $ip, $content, $rs)
82    {
83        # We handle only false positive from akismet
84        if ($status == 'spam' && $filter != 'dcFilterAkismet') {
85            return;
86        }
87
88        $f = $status == 'spam' ? 'submit_spam' : 'submit_ham';
89
90        if (($ak = $this->akInit()) === false) {
91            return;
92        }
93
94        try
95        {
96            if ($ak->verify()) {
97                $ak->{$f}($rs->getPostURL(), $type, $author, $email, $site, $content);
98            }
99        } catch (Exception $e) {} # If http or akismet is dead, we don't need to know it
100    }
101
102    public function gui($url)
103    {
104        $blog = &$this->core->blog;
105
106        $blog->settings->addNamespace('akismet');
107        $ak_key      = $blog->settings->akismet->ak_key;
108        $ak_verified = null;
109
110        if (isset($_POST['ak_key'])) {
111            try
112            {
113                $ak_key = $_POST['ak_key'];
114
115                $blog->settings->akismet->put('ak_key', $ak_key, 'string');
116
117                dcPage::addSuccessNotice(__('Filter configuration have been successfully saved.'));
118                http::redirect($url);
119            } catch (Exception $e) {
120                $this->core->error->add($e->getMessage());
121            }
122        }
123
124        if ($blog->settings->akismet->ak_key) {
125            try {
126                $ak          = new akismet($blog->url, $blog->settings->akismet->ak_key);
127                $ak_verified = $ak->verify();
128            } catch (Exception $e) {
129                $this->core->error->add($e->getMessage());
130            }
131        }
132
133        $res = dcPage::notices();
134
135        $res .=
136        '<form action="' . html::escapeURL($url) . '" method="post" class="fieldset">' .
137        '<p><label for="ak_key" class="classic">' . __('Akismet API key:') . '</label> ' .
138        form::field('ak_key', 12, 128, $ak_key);
139
140        if ($ak_verified !== null) {
141            if ($ak_verified) {
142                $res .= ' <img src="images/check-on.png" alt="" /> ' . __('API key verified');
143            } else {
144                $res .= ' <img src="images/check-off.png" alt="" /> ' . __('API key not verified');
145            }
146        }
147
148        $res .= '</p>';
149
150        $res .=
151        '<p><a href="http://akismet.com/">' . __('Get your own API key') . '</a></p>' .
152        '<p><input type="submit" value="' . __('Save') . '" />' .
153        $this->core->formNonce() . '</p>' .
154            '</form>';
155
156        return $res;
157    }
158}
159
160class akismet extends netHttp
161{
162    protected $base_host  = 'rest.akismet.com';
163    protected $ak_host    = '';
164    protected $ak_version = '1.1';
165    protected $ak_path    = '/%s/%s';
166
167    protected $ak_key = null;
168    protected $blog_url;
169
170    protected $timeout = 3;
171
172    public function __construct($blog_url, $api_key)
173    {
174        $this->blog_url = $blog_url;
175        $this->ak_key   = $api_key;
176
177        $this->ak_path = sprintf($this->ak_path, $this->ak_version, '%s');
178        $this->ak_host = $this->ak_key . '.' . $this->base_host;
179
180        parent::__construct($this->ak_host, 80);
181    }
182
183    public function verify()
184    {
185        $this->host = $this->base_host;
186        $path       = sprintf($this->ak_path, 'verify-key');
187
188        $data = [
189            'key'  => $this->ak_key,
190            'blog' => $this->blog_url
191        ];
192
193        if ($this->post($path, $data, 'UTF-8')) {
194            return $this->getContent() == 'valid';
195        }
196
197        return false;
198    }
199
200    public function comment_check($permalink, $type, $author, $email, $url, $content)
201    {
202        $info_ignore = ['HTTP_COOKIE'];
203        $info        = [];
204
205        foreach ($_SERVER as $k => $v) {
206            if (strpos($k, 'HTTP_') === 0 && !in_array($k, $info_ignore)) {
207                $info[$k] = $v;
208            }
209        }
210
211        return $this->callFunc('comment-check', $permalink, $type, $author, $email, $url, $content, $info);
212    }
213
214    public function submit_spam($permalink, $type, $author, $email, $url, $content)
215    {
216        $this->callFunc('submit-spam', $permalink, $type, $author, $email, $url, $content);
217        return true;
218    }
219
220    public function submit_ham($permalink, $type, $author, $email, $url, $content)
221    {
222        $this->callFunc('submit-ham', $permalink, $type, $author, $email, $url, $content);
223        return true;
224    }
225
226    protected function callFunc($function, $permalink, $type, $author, $email, $url, $content, $info = [])
227    {
228        $ua      = isset($info['HTTP_USER_AGENT']) ? $info['HTTP_USER_AGENT'] : '';
229        $referer = isset($info['HTTP_REFERER']) ? $info['HTTP_REFERER'] : '';
230
231        # Prepare comment data
232        $data = [
233            'blog'                 => $this->blog_url,
234            'user_ip'              => http::realIP(),
235            'user_agent'           => $ua,
236            'referrer'             => $referer,
237            'permalink'            => $permalink,
238            'comment_type'         => $type,
239            'comment_author'       => $author,
240            'comment_author_email' => $email,
241            'comment_author_url'   => $url,
242            'comment_content'      => $content
243        ];
244
245        $data = array_merge($data, $info);
246
247        $this->host = $this->ak_host;
248        $path       = sprintf($this->ak_path, $function);
249
250        if (!$this->post($path, $data, 'UTF-8')) {
251            throw new Exception('HTTP error: ' . $this->getError());
252        }
253
254        return $this->getContent() == 'true';
255    }
256}
Note: See TracBrowser for help on using the repository browser.

Sites map