www/adiumxtras.com 53:125992583755: Implement Akismet for spam f...
commits at adium.im
commits at adium.im
Fri Feb 27 08:21:27 UTC 2015
details: http://hg.adium.im/www/adiumxtras.com/rev/125992583755
revision: 53:125992583755
branch: adiumxtras.com
author: Thijs Alkemade <me at thijsalkema.de>
date: Fri Feb 27 09:21:17 2015 +0100
Implement Akismet for spam filtering for adiumxtras comments.
diffs (529 lines):
diff -r 60cf3f31019c -r 125992583755 akismet.class.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/akismet.class.php Fri Feb 27 09:21:17 2015 +0100
@@ -0,0 +1,388 @@
+<?php
+/**
+ * 08.11.2010 22:25:17est
+ *
+ * Akismet PHP4 class
+ *
+ * <b>Usage</b>
+ * <code>
+ * $comment = array(
+ * 'author' => 'viagra-test-123',
+ * 'email' => 'test at example.com',
+ * 'website' => 'http://www.example.com/',
+ * 'body' => 'This is a test comment',
+ * 'permalink' => 'http://yourdomain.com/yourblogpost.url',
+ * );
+ *
+ * $akismet = new Akismet('http://www.yourdomain.com/', 'YOUR_WORDPRESS_API_KEY', $comment);
+ *
+ * if($akismet->errorsExist()) {
+ * echo"Couldn't connected to Akismet server!";
+ * } else {
+ * if($akismet->isSpam()) {
+ * echo"Spam detected";
+ * } else {
+ * echo"yay, no spam!";
+ * }
+ * }
+ * </code>
+ *
+ * @author Bret Kuhns {@link www.bretkuhns.com}
+ * @link http://code.google.com/p/akismet-php4
+ * @version 0.3.5
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+
+
+
+// Error constants
+define("AKISMET_SERVER_NOT_FOUND", 0);
+define("AKISMET_RESPONSE_FAILED", 1);
+define("AKISMET_INVALID_KEY", 2);
+
+
+
+// Base class to assist in error handling between Akismet classes
+class AkismetObject {
+ var $errors = array();
+
+
+ /**
+ * Add a new error to the errors array in the object
+ *
+ * @param String $name A name (array key) for the error
+ * @param String $string The error message
+ * @return void
+ */
+ // Set an error in the object
+ function setError($name, $message) {
+ $this->errors[$name] = $message;
+ }
+
+
+ /**
+ * Return a specific error message from the errors array
+ *
+ * @param String $name The name of the error you want
+ * @return mixed Returns a String if the error exists, a false boolean if it does not exist
+ */
+ function getError($name) {
+ if($this->isError($name)) {
+ return $this->errors[$name];
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Return all errors in the object
+ *
+ * @return String[]
+ */
+ function getErrors() {
+ return (array)$this->errors;
+ }
+
+
+ /**
+ * Check if a certain error exists
+ *
+ * @param String $name The name of the error you want
+ * @return boolean
+ */
+ function isError($name) {
+ return isset($this->errors[$name]);
+ }
+
+
+ /**
+ * Check if any errors exist
+ *
+ * @return boolean
+ */
+ function errorsExist() {
+ return (count($this->errors) > 0);
+ }
+
+
+}
+
+
+
+
+
+// Used by the Akismet class to communicate with the Akismet service
+class AkismetHttpClient extends AkismetObject {
+ var $akismetVersion = '1.1';
+ var $con;
+ var $host;
+ var $port;
+ var $apiKey;
+ var $blogUrl;
+ var $errors = array();
+
+
+ // Constructor
+ function AkismetHttpClient($host, $blogUrl, $apiKey, $port = 80) {
+ $this->host = $host;
+ $this->port = $port;
+ $this->blogUrl = $blogUrl;
+ $this->apiKey = $apiKey;
+ }
+
+
+ // Use the connection active in $con to get a response from the server and return that response
+ function getResponse($request, $path, $type = "post", $responseLength = 1160) {
+ $this->_connect();
+
+ if($this->con && !$this->isError(AKISMET_SERVER_NOT_FOUND)) {
+ $request =
+ strToUpper($type)." /{$this->akismetVersion}/$path HTTP/1.0\r\n" .
+ "Host: ".((!empty($this->apiKey)) ? $this->apiKey."." : null)."{$this->host}\r\n" .
+ "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" .
+ "Content-Length: ".strlen($request)."\r\n" .
+ "User-Agent: Akismet PHP4 Class\r\n" .
+ "\r\n" .
+ $request
+ ;
+ $response = "";
+
+ @fwrite($this->con, $request);
+
+ while(!feof($this->con)) {
+ $response .= @fgets($this->con, $responseLength);
+ }
+
+ $response = explode("\r\n\r\n", $response, 2);
+ return $response[1];
+ } else {
+ $this->setError(AKISMET_RESPONSE_FAILED, "The response could not be retrieved.");
+ }
+
+ $this->_disconnect();
+ }
+
+
+ // Connect to the Akismet server and store that connection in the instance variable $con
+ function _connect() {
+ if(!($this->con = @fsockopen($this->host, $this->port))) {
+ $this->setError(AKISMET_SERVER_NOT_FOUND, "Could not connect to akismet server.");
+ }
+ }
+
+
+ // Close the connection to the Akismet server
+ function _disconnect() {
+ @fclose($this->con);
+ }
+
+
+}
+
+
+
+
+
+// The controlling class. This is the ONLY class the user should instantiate in
+// order to use the Akismet service!
+class Akismet extends AkismetObject {
+ var $apiPort = 80;
+ var $akismetServer = 'rest.akismet.com';
+ var $akismetVersion = '1.1';
+ var $http;
+
+ var $ignore = array(
+ 'HTTP_COOKIE',
+ 'HTTP_X_FORWARDED_FOR',
+ 'HTTP_X_FORWARDED_HOST',
+ 'HTTP_MAX_FORWARDS',
+ 'HTTP_X_FORWARDED_SERVER',
+ 'REDIRECT_STATUS',
+ 'SERVER_PORT',
+ 'PATH',
+ 'DOCUMENT_ROOT',
+ 'SERVER_ADMIN',
+ 'QUERY_STRING',
+ 'PHP_SELF',
+ 'argv'
+ );
+
+ var $blogUrl = "";
+ var $apiKey = "";
+ var $comment = array();
+
+
+ /**
+ * Constructor
+ *
+ * Set instance variables, connect to Akismet, and check API key
+ *
+ * @param String $blogUrl The URL to your own blog
+ * @param String $apiKey Your wordpress API key
+ * @param String[] $comment A formatted comment array to be examined by the Akismet service
+ * @return Akismet
+ */
+ function Akismet($blogUrl, $apiKey, $comment = array()) {
+ $this->blogUrl = $blogUrl;
+ $this->apiKey = $apiKey;
+ $this->setComment($comment);
+
+ // Connect to the Akismet server and populate errors if they exist
+ $this->http = new AkismetHttpClient($this->akismetServer, $blogUrl, $apiKey);
+ if($this->http->errorsExist()) {
+ $this->errors = array_merge($this->errors, $this->http->getErrors());
+ }
+
+ // Check if the API key is valid
+ if(!$this->_isValidApiKey($apiKey)) {
+ $this->setError(AKISMET_INVALID_KEY, "Your Akismet API key is not valid.");
+ }
+ }
+
+
+ /**
+ * Query the Akismet and determine if the comment is spam or not
+ *
+ * @return boolean
+ */
+ function isSpam() {
+ $response = $this->http->getResponse($this->_getQueryString(), 'comment-check');
+
+ return ($response == "true");
+ }
+
+
+ /**
+ * Submit this comment as an unchecked spam to the Akismet server
+ *
+ * @return void
+ */
+ function submitSpam() {
+ $this->http->getResponse($this->_getQueryString(), 'submit-spam');
+ }
+
+
+ /**
+ * Submit a false-positive comment as "ham" to the Akismet server
+ *
+ * @return void
+ */
+ function submitHam() {
+ $this->http->getResponse($this->_getQueryString(), 'submit-ham');
+ }
+
+
+ /**
+ * Manually set the comment value of the instantiated object.
+ *
+ * @param Array $comment
+ * @return void
+ */
+ function setComment($comment) {
+ $this->comment = $comment;
+ if(!empty($comment)) {
+ $this->_formatCommentArray();
+ $this->_fillCommentValues();
+ }
+ }
+
+
+ /**
+ * Returns the current value of the object's comment array.
+ *
+ * @return Array
+ */
+ function getComment() {
+ return $this->comment;
+ }
+
+
+ /**
+ * Check with the Akismet server to determine if the API key is valid
+ *
+ * @access Protected
+ * @param String $key The Wordpress API key passed from the constructor argument
+ * @return boolean
+ */
+ function _isValidApiKey($key) {
+ $keyCheck = $this->http->getResponse("key=".$this->apiKey."&blog=".$this->blogUrl, 'verify-key');
+
+ return ($keyCheck == "valid");
+ }
+
+
+ /**
+ * Format the comment array in accordance to the Akismet API
+ *
+ * @access Protected
+ * @return void
+ */
+ function _formatCommentArray() {
+ $format = array(
+ 'type' => 'comment_type',
+ 'author' => 'comment_author',
+ 'email' => 'comment_author_email',
+ 'website' => 'comment_author_url',
+ 'body' => 'comment_content'
+ );
+
+ foreach($format as $short => $long) {
+ if(isset($this->comment[$short])) {
+ $this->comment[$long] = $this->comment[$short];
+ unset($this->comment[$short]);
+ }
+ }
+ }
+
+
+ /**
+ * Fill any values not provided by the developer with available values.
+ *
+ * @return void
+ */
+ function _fillCommentValues() {
+ if(!isset($this->comment['user_ip'])) {
+ $this->comment['user_ip'] = ($_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR')) ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR');
+ }
+ if(!isset($this->comment['user_agent'])) {
+ $this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
+ }
+ if(!isset($this->comment['referrer'])) {
+ $this->comment['referrer'] = $_SERVER['HTTP_REFERER'];
+ }
+ if(!isset($this->comment['blog'])) {
+ $this->comment['blog'] = $this->blogUrl;
+ }
+ }
+
+
+ /**
+ * Build a query string for use with HTTP requests
+ *
+ * @access Protected
+ * @return String
+ */
+ function _getQueryString() {
+ foreach($_SERVER as $key => $value) {
+ if(!in_array($key, $this->ignore)) {
+ if($key == 'REMOTE_ADDR') {
+ $this->comment[$key] = $this->comment['user_ip'];
+ } else {
+ $this->comment[$key] = $value;
+ }
+ }
+ }
+
+ $query_string = '';
+
+ foreach($this->comment as $key => $data) {
+ $query_string .= $key . '=' . urlencode(stripslashes($data)) . '&';
+ }
+
+ return $query_string;
+ }
+
+
+}
+?>
\ No newline at end of file
diff -r 60cf3f31019c -r 125992583755 xtras.php
--- a/xtras.php Thu Feb 26 08:26:52 2015 +0100
+++ b/xtras.php Fri Feb 27 09:21:17 2015 +0100
@@ -61,58 +61,82 @@
break;
case "add_comment":
- require_once('../recaptcha_keys.php');
+ require_once('../recaptcha_keys.php');
require_once('recaptchalib.php');
+ require_once('akismet.class.php');
$resp = recaptcha_check_answer (RECAPTCHA_PRIV_KEY,
$_SERVER["REMOTE_ADDR"],
NULL,
$_POST["g-recaptcha-response"]);
if ($resp->is_valid) {
- if ($_POST['comment'] && $_POST['xtra_id']) {
- if (currentUID()) {
- $sql->query("INSERT INTO comments (xtra_id, parent_id, comment, user_id, posted) VALUES ('%d', '%d', '%s', '%d', NOW())", intval($_POST['xtra_id']), intval($_POST['parent_id']), strip_tags($_POST['comment']), currentUID());
- $newCommentID = $sql->insert_id();
+
+ $akismet = NULL;
+
+ if ($currentUID && $_POST['xtra_id'] && $_POST['comment']) {
+ $sql->query("SELECT users.username, users.email, users.website FROM users WHERE users.user_id = '%d'", currentUID());
+
+ $user = $sql->fetch_assoc();
+
+ $comment = array(
+ 'author' => $user['username'],
+ 'email' => $user['email'],
+ 'website' => $user['website'],
+ 'body' => $_POST['comment'],
+ 'permalink' => sprintf("http://www.adiumxtras.com/index.php?a=xtras&xtra_id=%d", $_POST['xtra_id'])
+ );
- // Email the author about the new comment.
- $sql->query("SELECT xtras.title, users.username, users.email FROM xtras, users WHERE xtras.user_id=users.user_id AND xtras.xtra_id='%d'", intval($_POST['xtra_id']));
- $emailInfo = $sql->fetch_assoc();
- $message = sprintf("%s\n\nA new comment has been added to one of your xtras.\n\n", $emailInfo['username']);
- $message .= sprintf("*******************\n%s\n<http://adiumxtras.com/index.php?a=xtras&xtra_id=%d#c%d>\n*******************\n\n", $emailInfo['title'], $_POST['xtra_id'], $newCommentID);
- $message .= sprintf("Comment by: %s\n\nComment:\n\n%s", $_COOKIE['xtras_user'], $_POST['comment']);
+ $akismet = new Akismet('http://www.adiumxtras.com/', AKISMET_API_KEY, $comment);
+ }
- mail($emailInfo['email'], "New Comment on Xtras", $message, "From: xtras at adiumxtras.com");
-
- if ($_POST['parent_id']) {
- $emails = array();
- $sql->query("SELECT comments.*, users.* FROM comments, users WHERE comments.comment_id IN (%s) AND users.user_id = comments.user_id", implode(",", commentsWithParent(intval($_POST['parent_id']))));
- while ($row = $sql->fetch_assoc()) {
- if ($row['email'] == $emailInfo['email'] || $row['comment_id'] == $newCommentID)
- continue;
- $emails[] = $row['email'];
+ if($akismet && ($akismet->errorsExist() || !$akismet->isSpam())) {
+
+ if ($_POST['comment'] && $_POST['xtra_id']) {
+ if (currentUID()) {
+
+ $sql->query("INSERT INTO comments (xtra_id, parent_id, comment, user_id, posted) VALUES ('%d', '%d', '%s', '%d', NOW())", intval($_POST['xtra_id']), intval($_POST['parent_id']), strip_tags($_POST['comment']), currentUID());
+ $newCommentID = $sql->insert_id();
+
+ // Email the author about the new comment.
+ $sql->query("SELECT xtras.title, users.username, users.email FROM xtras, users WHERE xtras.user_id=users.user_id AND xtras.xtra_id='%d'", intval($_POST['xtra_id']));
+ $emailInfo = $sql->fetch_assoc();
+ $message = sprintf("%s\n\nA new comment has been added to one of your xtras.\n\n", $emailInfo['username']);
+ $message .= sprintf("*******************\n%s\n<http://adiumxtras.com/index.php?a=xtras&xtra_id=%d#c%d>\n*******************\n\n", $emailInfo['title'], $_POST['xtra_id'], $newCommentID);
+ $message .= sprintf("Comment by: %s\n\nComment:\n\n%s", $_COOKIE['xtras_user'], $_POST['comment']);
+
+ mail($emailInfo['email'], "New Comment on Xtras", $message, "From: xtras at adiumxtras.com");
+
+ if ($_POST['parent_id']) {
+ $emails = array();
+ $sql->query("SELECT comments.*, users.* FROM comments, users WHERE comments.comment_id IN (%s) AND users.user_id = comments.user_id", implode(",", commentsWithParent(intval($_POST['parent_id']))));
+ while ($row = $sql->fetch_assoc()) {
+ if ($row['email'] == $emailInfo['email'] || $row['comment_id'] == $newCommentID)
+ continue;
+ $emails[] = $row['email'];
+ }
+
+ $emails = array_unique($emails);
+
+ foreach ($emails as $email) {
+ $message = sprintf("Hello:\n\nA new comment has been added to a comment thread that you are participating in:\n\n");
+ $message .= sprintf("*******************\n%s\n<http://adiumxtras.com/index.php?a=xtras&xtra_id=%d#c%d>\n*******************\n\n", $emailInfo['title'], $_POST['xtra_id'], $newCommentID);
+ $message .= sprintf("Comment by: %s\n\nComment:\n\n%s", $_COOKIE['xtrauser'], $_POST['comment']);
+ mail($email, "New Comment on Xtras Thread", $message, "From: xtras at adiumxtras.com");
+ }
}
-
- $emails = array_unique($emails);
-
- foreach ($emails as $email) {
- $message = sprintf("Hello:\n\nA new comment has been added to a comment thread that you are participating in:\n\n");
- $message .= sprintf("*******************\n%s\n<http://adiumxtras.com/index.php?a=xtras&xtra_id=%d#c%d>\n*******************\n\n", $emailInfo['title'], $_POST['xtra_id'], $newCommentID);
- $message .= sprintf("Comment by: %s\n\nComment:\n\n%s", $_COOKIE['xtrauser'], $_POST['comment']);
- mail($email, "New Comment on Xtras Thread", $message, "From: xtras at adiumxtras.com");
- }
+
+ // Send the person back to whence-forth they came.
+ header(sprintf("Location: index.php?a=xtras&xtra_id=%d", $_POST['xtra_id']));
+ } else {
+ // There was code in the old version for anonymous posting.
+ // I'm totally not replicating it.
+ $smarty->assign("message", "Somehow you submitted the form without logging in. That's neat. But, first, you must login.");
+ $smarty->display("loginForm.tpl");
}
-
- // Send the person back to whence-forth they came.
+ } else
header(sprintf("Location: index.php?a=xtras&xtra_id=%d", $_POST['xtra_id']));
- } else {
- // There was code in the old version for anonymous posting.
- // I'm totally not replicating it.
- $smarty->assign("message", "Somehow you submitted the form without logging in. That's neat. But, first, you must login.");
- $smarty->display("loginForm.tpl");
- }
- } else
- header(sprintf("Location: index.php?a=xtras&xtra_id=%d", $_POST['xtra_id']));
- break;
- } // intentional fallthrough, they failed the captcha, but let's be nice and allow them to try again
+ break;
+ }
+ } // intentional fallthrough, they failed the captcha or the akismet test, but let's be nice and allow them to try again
default:
$sql->query("SELECT xtras.*, cats.*, users.*, UNIX_TIMESTAMP(xtras.date_added) AS date_added, UNIX_TIMESTAMP(xtras.bin_updated) AS bin_updated, xtras.status as status FROM xtras, cats, users, assoc WHERE xtras.xtra_id=assoc.xtra_id AND xtras.user_id=users.user_id AND cats.cat_id = assoc.cat_id AND xtras.xtra_id='%d'", intval($_GET['xtra_id']));
@@ -188,7 +212,7 @@
$smarty->assign("old_comment", '');
$smarty->assign("error", '');
}
- require_once('../recaptcha_keys.php');
+ require_once('../recaptcha_keys.php');
require_once('recaptchalib.php');
$smarty->assign("recaptcha_html", recaptcha_get_html(RECAPTCHA_PUB_KEY));
$smarty->display("xtras.tpl");
More information about the commits
mailing list