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