root/branches/1.4.5-wp2.2/lib/akismet.class.php

Revision 62, 8.6 kB (checked in by root, 9 months ago)

replaced akismet.class

Line 
1<?php
2/**
3 * 01.07.2008 22:32:28est
4 *
5 * Akismet PHP4 class
6 *
7 * <b>Usage</b>
8 * <code>
9 *    $comment = array(
10 *           'author'    => 'viagra-test-123',
11 *           'email'     => 'test@example.com',
12 *           'website'   => 'http://www.example.com/',
13 *           'body'      => 'This is a test comment',
14 *           'permalink' => 'http://yourdomain.com/yourblogpost.url',
15 *        );
16 *
17 *    $akismet = new Akismet('http://www.yourdomain.com/', 'YOUR_WORDPRESS_API_KEY', $comment);
18 *
19 *    if($akismet->errorsExist()) {
20 *        echo"Couldn't connected to Akismet server!";
21 *    } else {
22 *        if($akismet->isSpam()) {
23 *            echo"Spam detected";
24 *        } else {
25 *            echo"yay, no spam!";
26 *        }
27 *    }
28 * </code>
29 *
30 * @author Bret Kuhns {@link www.miphp.net}
31 * @link http://www.miphp.net/blog/view/new_akismet_class/
32 * @version 0.3.4
33 * @license http://www.opensource.org/licenses/mit-license.php MIT License
34 */
35
36
37
38// Error constants
39define("AKISMET_SERVER_NOT_FOUND",      0);
40define("AKISMET_RESPONSE_FAILED",       1);
41define("AKISMET_INVALID_KEY",           2);
42
43
44
45// Base class to assist in error handling between Akismet classes
46class AkismetObject {
47        var $errors = array();
48       
49       
50        /**
51         * Add a new error to the errors array in the object
52         *
53         * @param       String  $name   A name (array key) for the error
54         * @param       String  $string The error message
55         * @return void
56         */ 
57        // Set an error in the object
58        function setError($name, $message) {
59                $this->errors[$name] = $message;
60        }
61       
62
63        /**
64         * Return a specific error message from the errors array
65         *
66         * @param       String  $name   The name of the error you want
67         * @return mixed        Returns a String if the error exists, a false boolean if it does not exist
68         */
69        function getError($name) {
70                if($this->isError($name)) {
71                        return $this->errors[$name];
72                } else {
73                        return false;
74                }
75        }
76       
77       
78        /**
79         * Return all errors in the object
80         *
81         * @return String[]
82         */ 
83        function getErrors() {
84                return (array)$this->errors;
85        }
86       
87       
88        /**
89         * Check if a certain error exists
90         *
91         * @param       String  $name   The name of the error you want
92         * @return boolean
93         */ 
94        function isError($name) {
95                return isset($this->errors[$name]);
96        }
97       
98       
99        /**
100         * Check if any errors exist
101         *
102         * @return boolean
103         */
104        function errorsExist() {
105                return (count($this->errors) > 0);
106        }
107       
108       
109}
110
111
112
113
114
115// Used by the Akismet class to communicate with the Akismet service
116class AkismetHttpClient extends AkismetObject {
117        var $akismetVersion = '1.1';
118        var $con;
119        var $host;
120        var $port;
121        var $apiKey;
122        var $blogUrl;
123        var $errors = array();
124       
125       
126        // Constructor
127        function AkismetHttpClient($host, $blogUrl, $apiKey, $port = 80) {
128                $this->host = $host;
129                $this->port = $port;
130                $this->blogUrl = $blogUrl;
131                $this->apiKey = $apiKey;
132        }
133       
134       
135        // Use the connection active in $con to get a response from the server and return that response
136        function getResponse($request, $path, $type = "post", $responseLength = 1160) {
137                $this->_connect();
138               
139                if($this->con && !$this->isError(AKISMET_SERVER_NOT_FOUND)) {
140                        $request  = 
141                                        strToUpper($type)." /{$this->akismetVersion}/$path HTTP/1.1\r\n" .
142                                        "Host: ".((!empty($this->apiKey)) ? $this->apiKey."." : null)."{$this->host}\r\n" .
143                                        "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" .
144                                        "Content-Length: ".strlen($request)."\r\n" .
145                                        "User-Agent: Akismet PHP4 Class\r\n" .
146                                        "\r\n" .
147                                        $request
148                                ;
149                        $response = "";
150
151                        @fwrite($this->con, $request);
152
153                        while(!feof($this->con)) {
154                                $response .= @fgets($this->con, $responseLength);
155                        }
156
157                        $response = explode("\r\n\r\n", $response, 2);
158                        return $response[1];
159                } else {
160                        $this->setError(AKISMET_RESPONSE_FAILED, "The response could not be retrieved.");
161                }
162               
163                $this->_disconnect();
164        }
165       
166       
167        // Connect to the Akismet server and store that connection in the instance variable $con
168        function _connect() {
169                if(!($this->con = @fsockopen($this->host, $this->port))) {
170                        $this->setError(AKISMET_SERVER_NOT_FOUND, "Could not connect to akismet server.");
171                }
172        }
173       
174       
175        // Close the connection to the Akismet server
176        function _disconnect() {
177                @fclose($this->con);
178        }
179       
180       
181}
182
183
184
185
186
187// The controlling class. This is the ONLY class the user should instantiate in
188// order to use the Akismet service!
189class Akismet extends AkismetObject {
190        var $apiPort = 80;
191        var $akismetServer = 'rest.akismet.com';
192        var $akismetVersion = '1.1';
193        var $http;
194       
195        var $ignore = array(
196                        'HTTP_COOKIE',
197                        'HTTP_X_FORWARDED_FOR',
198                        'HTTP_X_FORWARDED_HOST',
199                        'HTTP_MAX_FORWARDS',
200                        'HTTP_X_FORWARDED_SERVER',
201                        'REDIRECT_STATUS',
202                        'SERVER_PORT',
203                        'PATH',
204                        'DOCUMENT_ROOT',
205                        'SERVER_ADMIN',
206                        'QUERY_STRING',
207                        'PHP_SELF',
208                        'argv'
209                );
210       
211        var $blogUrl = "";
212        var $apiKey  = "";
213        var $comment = array();
214       
215       
216        /**
217         * Constructor
218         *
219         * Set instance variables, connect to Akismet, and check API key
220         *
221         * @param       String  $blogUrl        The URL to your own blog
222         * @param       String  $apiKey         Your wordpress API key
223         * @param       String[]        $comment        A formatted comment array to be examined by the Akismet service
224         * @return      Akismet
225         */
226        function Akismet($blogUrl, $apiKey, $comment = array()) {
227                $this->blogUrl = $blogUrl;
228                $this->apiKey  = $apiKey;
229                $this->setComment($comment);
230               
231                // Connect to the Akismet server and populate errors if they exist
232                $this->http = new AkismetHttpClient($this->akismetServer, $blogUrl, $apiKey);
233                if($this->http->errorsExist()) {
234                        $this->errors = array_merge($this->errors, $this->http->getErrors());
235                }
236               
237                // Check if the API key is valid
238                if(!$this->_isValidApiKey($apiKey)) {
239                        $this->setError(AKISMET_INVALID_KEY, "Your Akismet API key is not valid.");
240                }
241        }
242       
243       
244        /**
245         * Query the Akismet and determine if the comment is spam or not
246         *
247         * @return      boolean
248         */
249        function isSpam() {
250                $response = $this->http->getResponse($this->_getQueryString(), 'comment-check');
251               
252                return ($response == "true");
253        }
254       
255       
256        /**
257         * Submit this comment as an unchecked spam to the Akismet server
258         *
259         * @return      void
260         */
261        function submitSpam() {
262                $this->http->getResponse($this->_getQueryString(), 'submit-spam');
263        }
264       
265       
266        /**
267         * Submit a false-positive comment as "ham" to the Akismet server
268         *
269         * @return      void
270         */
271        function submitHam() {
272                $this->http->getResponse($this->_getQueryString(), 'submit-ham');
273        }
274       
275       
276        /**
277         * Manually set the comment value of the instantiated object.
278         *
279         * @param       Array   $comment
280         * @return      void
281         */
282        function setComment($comment) {
283                $this->comment = $comment;
284                if(!empty($comment)) {
285                        $this->_formatCommentArray();
286                        $this->_fillCommentValues();
287                }
288        }
289       
290       
291        /**
292         * Returns the current value of the object's comment array.
293         *
294         * @return      Array
295         */
296        function getComment() {
297                return $this->comment;
298        }
299       
300       
301        /**
302         * Check with the Akismet server to determine if the API key is valid
303         *
304         * @access      Protected
305         * @param       String  $key    The Wordpress API key passed from the constructor argument
306         * @return      boolean
307         */
308        function _isValidApiKey($key) {
309                $keyCheck = $this->http->getResponse("key=".$this->apiKey."&blog=".$this->blogUrl, 'verify-key');
310                       
311                return ($keyCheck == "valid");
312        }
313       
314       
315        /**
316         * Format the comment array in accordance to the Akismet API
317         *
318         * @access      Protected
319         * @return      void
320         */
321        function _formatCommentArray() {
322                $format = array(
323                                'type' => 'comment_type',
324                                'author' => 'comment_author',
325                                'email' => 'comment_author_email',
326                                'website' => 'comment_author_url',
327                                'body' => 'comment_content'
328                        );
329               
330                foreach($format as $short => $long) {
331                        if(isset($this->comment[$short])) {
332                                $this->comment[$long] = $this->comment[$short];
333                                unset($this->comment[$short]);
334                        }
335                }
336        }
337       
338       
339        /**
340         * Fill any values not provided by the developer with available values.
341         *
342         * @return      void
343         */
344        function _fillCommentValues() {
345                if(!isset($this->comment['user_ip'])) {
346                        $this->comment['user_ip'] = ($_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR')) ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR');
347                }
348                if(!isset($this->comment['user_agent'])) {
349                        $this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
350                }
351                if(!isset($this->comment['referrer'])) {
352                        $this->comment['referrer'] = $_SERVER['HTTP_REFERER'];
353                }
354                if(!isset($this->comment['blog'])) {
355                        $this->comment['blog'] = $this->blogUrl;
356                }
357        }
358       
359       
360        /**
361         * Build a query string for use with HTTP requests
362         *
363         * @access      Protected
364         * @return      String
365         */
366        function _getQueryString() {
367                foreach($_SERVER as $key => $value) {
368                        if(!in_array($key, $this->ignore)) {
369                                if($key == 'REMOTE_ADDR') {
370                                        $this->comment[$key] = $this->comment['user_ip'];
371                                } else {
372                                        $this->comment[$key] = $value;
373                                }
374                        }
375                }
376
377                $query_string = '';
378
379                foreach($this->comment as $key => $data) {
380                        $query_string .= $key . '=' . urlencode(stripslashes($data)) . '&';
381                }
382
383                return $query_string;
384        }
385       
386       
387}
388?>
Note: See TracBrowser for help on using the browser.