webmaster@64: Usage webmaster@64: * webmaster@64: * $comment = array( webmaster@64: * 'author' => 'viagra-test-123', webmaster@64: * 'email' => 'test@example.com', webmaster@64: * 'website' => 'http://www.example.com/', webmaster@64: * 'body' => 'This is a test comment', webmaster@64: * 'permalink' => 'http://yourdomain.com/yourblogpost.url', webmaster@64: * ); webmaster@64: * webmaster@64: * $akismet = new Akismet('http://www.yourdomain.com/', 'YOUR_WORDPRESS_API_KEY', $comment); webmaster@64: * webmaster@64: * if($akismet->errorsExist()) { webmaster@64: * echo"Couldn't connected to Akismet server!"; webmaster@64: * } else { webmaster@64: * if($akismet->isSpam()) { webmaster@64: * echo"Spam detected"; webmaster@64: * } else { webmaster@64: * echo"yay, no spam!"; webmaster@64: * } webmaster@64: * } webmaster@64: * webmaster@64: * webmaster@64: * @author Bret Kuhns {@link www.miphp.net} webmaster@64: * @link http://www.miphp.net/blog/view/new_akismet_class/ webmaster@64: * @version 0.3.4 webmaster@64: * @license http://www.opensource.org/licenses/mit-license.php MIT License webmaster@64: */ webmaster@64: webmaster@64: webmaster@64: webmaster@64: // Error constants webmaster@64: define("AKISMET_SERVER_NOT_FOUND", 0); webmaster@64: define("AKISMET_RESPONSE_FAILED", 1); webmaster@64: define("AKISMET_INVALID_KEY", 2); webmaster@64: webmaster@64: webmaster@64: webmaster@64: // Base class to assist in error handling between Akismet classes webmaster@64: class AkismetObject { webmaster@64: var $errors = array(); webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Add a new error to the errors array in the object webmaster@64: * webmaster@64: * @param String $name A name (array key) for the error webmaster@64: * @param String $string The error message webmaster@64: * @return void webmaster@64: */ webmaster@64: // Set an error in the object webmaster@64: function setError($name, $message) { webmaster@64: $this->errors[$name] = $message; webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Return a specific error message from the errors array webmaster@64: * webmaster@64: * @param String $name The name of the error you want webmaster@64: * @return mixed Returns a String if the error exists, a false boolean if it does not exist webmaster@64: */ webmaster@64: function getError($name) { webmaster@64: if($this->isError($name)) { webmaster@64: return $this->errors[$name]; webmaster@64: } else { webmaster@64: return false; webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Return all errors in the object webmaster@64: * webmaster@64: * @return String[] webmaster@64: */ webmaster@64: function getErrors() { webmaster@64: return (array)$this->errors; webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Check if a certain error exists webmaster@64: * webmaster@64: * @param String $name The name of the error you want webmaster@64: * @return boolean webmaster@64: */ webmaster@64: function isError($name) { webmaster@64: return isset($this->errors[$name]); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Check if any errors exist webmaster@64: * webmaster@64: * @return boolean webmaster@64: */ webmaster@64: function errorsExist() { webmaster@64: return (count($this->errors) > 0); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: } webmaster@64: webmaster@64: webmaster@64: webmaster@64: webmaster@64: webmaster@64: // Used by the Akismet class to communicate with the Akismet service webmaster@64: class AkismetHttpClient extends AkismetObject { webmaster@64: var $akismetVersion = '1.1'; webmaster@64: var $con; webmaster@64: var $host; webmaster@64: var $port; webmaster@64: var $apiKey; webmaster@64: var $blogUrl; webmaster@64: var $errors = array(); webmaster@64: webmaster@64: webmaster@64: // Constructor webmaster@64: function AkismetHttpClient($host, $blogUrl, $apiKey, $port = 80) { webmaster@64: $this->host = $host; webmaster@64: $this->port = $port; webmaster@64: $this->blogUrl = $blogUrl; webmaster@64: $this->apiKey = $apiKey; webmaster@64: } webmaster@64: webmaster@64: webmaster@64: // Use the connection active in $con to get a response from the server and return that response webmaster@64: function getResponse($request, $path, $type = "post", $responseLength = 1160) { webmaster@64: $this->_connect(); webmaster@64: webmaster@64: if($this->con && !$this->isError(AKISMET_SERVER_NOT_FOUND)) { webmaster@64: $request = webmaster@64: strToUpper($type)." /{$this->akismetVersion}/$path HTTP/1.1\r\n" . webmaster@64: "Host: ".((!empty($this->apiKey)) ? $this->apiKey."." : null)."{$this->host}\r\n" . webmaster@64: "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" . webmaster@64: "Content-Length: ".strlen($request)."\r\n" . webmaster@64: "User-Agent: Akismet PHP4 Class\r\n" . webmaster@64: "\r\n" . webmaster@64: $request webmaster@64: ; webmaster@64: $response = ""; webmaster@64: webmaster@64: @fwrite($this->con, $request); webmaster@64: webmaster@64: while(!feof($this->con)) { webmaster@64: $response .= @fgets($this->con, $responseLength); webmaster@64: } webmaster@64: webmaster@64: $response = explode("\r\n\r\n", $response, 2); webmaster@64: return $response[1]; webmaster@64: } else { webmaster@64: $this->setError(AKISMET_RESPONSE_FAILED, "The response could not be retrieved."); webmaster@64: } webmaster@64: webmaster@64: $this->_disconnect(); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: // Connect to the Akismet server and store that connection in the instance variable $con webmaster@64: function _connect() { webmaster@64: if(!($this->con = @fsockopen($this->host, $this->port))) { webmaster@64: $this->setError(AKISMET_SERVER_NOT_FOUND, "Could not connect to akismet server."); webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: webmaster@64: // Close the connection to the Akismet server webmaster@64: function _disconnect() { webmaster@64: @fclose($this->con); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: } webmaster@64: webmaster@64: webmaster@64: webmaster@64: webmaster@64: webmaster@64: // The controlling class. This is the ONLY class the user should instantiate in webmaster@64: // order to use the Akismet service! webmaster@64: class Akismet extends AkismetObject { webmaster@64: var $apiPort = 80; webmaster@64: var $akismetServer = 'rest.akismet.com'; webmaster@64: var $akismetVersion = '1.1'; webmaster@64: var $http; webmaster@64: webmaster@64: var $ignore = array( webmaster@64: 'HTTP_COOKIE', webmaster@64: 'HTTP_X_FORWARDED_FOR', webmaster@64: 'HTTP_X_FORWARDED_HOST', webmaster@64: 'HTTP_MAX_FORWARDS', webmaster@64: 'HTTP_X_FORWARDED_SERVER', webmaster@64: 'REDIRECT_STATUS', webmaster@64: 'SERVER_PORT', webmaster@64: 'PATH', webmaster@64: 'DOCUMENT_ROOT', webmaster@64: 'SERVER_ADMIN', webmaster@64: 'QUERY_STRING', webmaster@64: 'PHP_SELF', webmaster@64: 'argv' webmaster@64: ); webmaster@64: webmaster@64: var $blogUrl = ""; webmaster@64: var $apiKey = ""; webmaster@64: var $comment = array(); webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Constructor webmaster@64: * webmaster@64: * Set instance variables, connect to Akismet, and check API key webmaster@64: * webmaster@64: * @param String $blogUrl The URL to your own blog webmaster@64: * @param String $apiKey Your wordpress API key webmaster@64: * @param String[] $comment A formatted comment array to be examined by the Akismet service webmaster@64: * @return Akismet webmaster@64: */ webmaster@64: function Akismet($blogUrl, $apiKey, $comment = array()) { webmaster@64: $this->blogUrl = $blogUrl; webmaster@64: $this->apiKey = $apiKey; webmaster@64: $this->setComment($comment); webmaster@64: webmaster@64: // Connect to the Akismet server and populate errors if they exist webmaster@64: $this->http = new AkismetHttpClient($this->akismetServer, $blogUrl, $apiKey); webmaster@64: if($this->http->errorsExist()) { webmaster@64: $this->errors = array_merge($this->errors, $this->http->getErrors()); webmaster@64: } webmaster@64: webmaster@64: // Check if the API key is valid webmaster@64: if(!$this->_isValidApiKey($apiKey)) { webmaster@64: $this->setError(AKISMET_INVALID_KEY, "Your Akismet API key is not valid."); webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Query the Akismet and determine if the comment is spam or not webmaster@64: * webmaster@64: * @return boolean webmaster@64: */ webmaster@64: function isSpam() { webmaster@64: $response = $this->http->getResponse($this->_getQueryString(), 'comment-check'); webmaster@64: webmaster@64: return ($response == "true"); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Submit this comment as an unchecked spam to the Akismet server webmaster@64: * webmaster@64: * @return void webmaster@64: */ webmaster@64: function submitSpam() { webmaster@64: $this->http->getResponse($this->_getQueryString(), 'submit-spam'); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Submit a false-positive comment as "ham" to the Akismet server webmaster@64: * webmaster@64: * @return void webmaster@64: */ webmaster@64: function submitHam() { webmaster@64: $this->http->getResponse($this->_getQueryString(), 'submit-ham'); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Manually set the comment value of the instantiated object. webmaster@64: * webmaster@64: * @param Array $comment webmaster@64: * @return void webmaster@64: */ webmaster@64: function setComment($comment) { webmaster@64: $this->comment = $comment; webmaster@64: if(!empty($comment)) { webmaster@64: $this->_formatCommentArray(); webmaster@64: $this->_fillCommentValues(); webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Returns the current value of the object's comment array. webmaster@64: * webmaster@64: * @return Array webmaster@64: */ webmaster@64: function getComment() { webmaster@64: return $this->comment; webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Check with the Akismet server to determine if the API key is valid webmaster@64: * webmaster@64: * @access Protected webmaster@64: * @param String $key The Wordpress API key passed from the constructor argument webmaster@64: * @return boolean webmaster@64: */ webmaster@64: function _isValidApiKey($key) { webmaster@64: $keyCheck = $this->http->getResponse("key=".$this->apiKey."&blog=".$this->blogUrl, 'verify-key'); webmaster@64: webmaster@64: return ($keyCheck == "valid"); webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Format the comment array in accordance to the Akismet API webmaster@64: * webmaster@64: * @access Protected webmaster@64: * @return void webmaster@64: */ webmaster@64: function _formatCommentArray() { webmaster@64: $format = array( webmaster@64: 'type' => 'comment_type', webmaster@64: 'author' => 'comment_author', webmaster@64: 'email' => 'comment_author_email', webmaster@64: 'website' => 'comment_author_url', webmaster@64: 'body' => 'comment_content' webmaster@64: ); webmaster@64: webmaster@64: foreach($format as $short => $long) { webmaster@64: if(isset($this->comment[$short])) { webmaster@64: $this->comment[$long] = $this->comment[$short]; webmaster@64: unset($this->comment[$short]); webmaster@64: } webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Fill any values not provided by the developer with available values. webmaster@64: * webmaster@64: * @return void webmaster@64: */ webmaster@64: function _fillCommentValues() { webmaster@64: if(!isset($this->comment['user_ip'])) { webmaster@64: $this->comment['user_ip'] = ($_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR')) ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR'); webmaster@64: } webmaster@64: if(!isset($this->comment['user_agent'])) { webmaster@64: $this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT']; webmaster@64: } webmaster@64: if(!isset($this->comment['referrer'])) { webmaster@64: $this->comment['referrer'] = $_SERVER['HTTP_REFERER']; webmaster@64: } webmaster@64: if(!isset($this->comment['blog'])) { webmaster@64: $this->comment['blog'] = $this->blogUrl; webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: webmaster@64: /** webmaster@64: * Build a query string for use with HTTP requests webmaster@64: * webmaster@64: * @access Protected webmaster@64: * @return String webmaster@64: */ webmaster@64: function _getQueryString() { webmaster@64: foreach($_SERVER as $key => $value) { webmaster@64: if(!in_array($key, $this->ignore)) { webmaster@64: if($key == 'REMOTE_ADDR') { webmaster@64: $this->comment[$key] = $this->comment['user_ip']; webmaster@64: } else { webmaster@64: $this->comment[$key] = $value; webmaster@64: } webmaster@64: } webmaster@64: } webmaster@64: webmaster@64: $query_string = ''; webmaster@64: webmaster@64: foreach($this->comment as $key => $data) { webmaster@64: $query_string .= $key . '=' . urlencode(stripslashes($data)) . '&'; webmaster@64: } webmaster@64: webmaster@64: return $query_string; webmaster@64: } webmaster@64: webmaster@64: webmaster@64: } webmaster@64: ?>