PageRenderTime 26ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_easyblog/classes/akismet.php

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