X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/022dfbbbe3215917d84708eb09acca93b21ae9e0..refs/tags/wordpress-2.9:/wp-content/plugins/akismet/akismet.php
diff --git a/wp-content/plugins/akismet/akismet.php b/wp-content/plugins/akismet/akismet.php
index 53e9a9ff..2460b707 100644
--- a/wp-content/plugins/akismet/akismet.php
+++ b/wp-content/plugins/akismet/akismet.php
@@ -2,14 +2,19 @@
/*
Plugin Name: Akismet
Plugin URI: http://akismet.com/
-Description: Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need a WordPress.com API key to use it. You can review the spam it catches under "Comments." To show off your Akismet stats just put <?php akismet_counter(); ?>
in your template.
-Version: 2.0.2
+Description: Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need a WordPress.com API key to use it. You can review the spam it catches under "Comments." To show off your Akismet stats just put <?php akismet_counter(); ?>
in your template. See also: WP Stats plugin.
+Version: 2.2.7
Author: Matt Mullenweg
-Author URI: http://photomatt.net/
+Author URI: http://ma.tt/
*/
+define('AKISMET_VERSION', '2.2.7');
+
// If you hardcode a WP.com API key here, all key config screens will be hidden
-$wpcom_api_key = '';
+if ( defined('WPCOM_API_KEY') )
+ $wpcom_api_key = constant('WPCOM_API_KEY');
+else
+ $wpcom_api_key = '';
function akismet_init() {
global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
@@ -21,9 +26,20 @@ function akismet_init() {
$akismet_api_port = 80;
add_action('admin_menu', 'akismet_config_page');
+ add_action('admin_menu', 'akismet_stats_page');
+ akismet_admin_warnings();
}
add_action('init', 'akismet_init');
+function akismet_admin_init() {
+ if ( function_exists( 'get_plugin_page_hook' ) )
+ $hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' );
+ else
+ $hook = 'dashboard_page_akismet-stats-display';
+ add_action('admin_head-'.$hook, 'akismet_stats_script');
+}
+add_action('admin_init', 'akismet_admin_init');
+
if ( !function_exists('wp_nonce_field') ) {
function akismet_nonce_field($action = -1) { return; }
$akismet_nonce = -1;
@@ -32,9 +48,14 @@ if ( !function_exists('wp_nonce_field') ) {
$akismet_nonce = 'akismet-update-key';
}
+if ( !function_exists('number_format_i18n') ) {
+ function number_format_i18n( $number, $decimals = null ) { return number_format( $number, $decimals ); }
+}
+
function akismet_config_page() {
if ( function_exists('add_submenu_page') )
add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
+
}
function akismet_conf() {
@@ -68,6 +89,8 @@ function akismet_conf() {
update_option( 'akismet_discard_month', 'true' );
else
update_option( 'akismet_discard_month', 'false' );
+ } elseif ( isset($_POST['check']) ) {
+ akismet_get_server_connectivity(0);
}
if ( $key_status != 'valid' ) {
@@ -103,7 +126,7 @@ function akismet_conf() {
'key_valid' => array('color' => '2d2', 'text' => __('This key is valid.')),
'key_failed' => array('color' => 'aa0', 'text' => __('The key below was previously validated but a connection to akismet.com can not be established at this time. Please check your server configuration.')));
?>
-
+
".__('Akismet is not active.')." ".sprintf(__('You must enter your WordPress.com API key for it to work.'), "plugins.php?page=akismet-key-config")."
- - "; +// Check connectivity between the WordPress blog and Akismet's servers. +// Returns an associative array of server IP addresses, where the key is the IP address, and value is true (available) or false (unable to connect). +function akismet_check_server_connectivity() { + global $akismet_api_host, $akismet_api_port, $wpcom_api_key; + + $test_host = 'rest.akismet.com'; + + // Some web hosts may disable one or both functions + if ( !is_callable('fsockopen') || !is_callable('gethostbynamel') ) + return array(); + + $ips = gethostbynamel($test_host); + if ( !$ips || !is_array($ips) || !count($ips) ) + return array(); + + $servers = array(); + foreach ( $ips as $ip ) { + $response = akismet_verify_key( akismet_get_key(), $ip ); + // even if the key is invalid, at least we know we have connectivity + if ( $response == 'valid' || $response == 'invalid' ) + $servers[$ip] = true; + else + $servers[$ip] = false; + } + + return $servers; +} + +// Check the server connectivity and store the results in an option. +// Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update. +// Returns the same associative array as akismet_check_server_connectivity() +function akismet_get_server_connectivity( $cache_timeout = 86400 ) { + $servers = get_option('akismet_available_servers'); + if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false ) + return $servers; + + // There's a race condition here but the effect is harmless. + $servers = akismet_check_server_connectivity(); + update_option('akismet_available_servers', $servers); + update_option('akismet_connectivity_time', time()); + return $servers; +} + +// Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed. +function akismet_server_connectivity_ok() { + // skip the check on WPMU because the status page is hidden + global $wpcom_api_key; + if ( $wpcom_api_key ) + return true; + $servers = akismet_get_server_connectivity(); + return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) ); +} + +function akismet_admin_warnings() { + global $wpcom_api_key; + if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) { + function akismet_warning() { + echo " + + "; + } + add_action('admin_notices', 'akismet_warning'); + return; + } elseif ( get_option('akismet_connectivity_time') && empty($_POST) && is_admin() && !akismet_server_connectivity_ok() ) { + function akismet_warning() { + echo " + + "; + } + add_action('admin_notices', 'akismet_warning'); + return; } - add_action('admin_footer', 'akismet_warning'); - return; +} + +function akismet_get_host($host) { + // if all servers are accessible, just return the host name. + // if not, return an IP that was known to be accessible at the last check. + if ( akismet_server_connectivity_ok() ) { + return $host; + } else { + $ips = akismet_get_server_connectivity(); + // a firewall may be blocking access to some Akismet IPs + if ( count($ips) > 0 && count(array_filter($ips)) < count($ips) ) { + // use DNS to get current IPs, but exclude any known to be unreachable + $dns = (array)gethostbynamel( rtrim($host, '.') . '.' ); + $dns = array_filter($dns); + foreach ( $dns as $ip ) { + if ( array_key_exists( $ip, $ips ) && empty( $ips[$ip] ) ) + unset($dns[$ip]); + } + // return a random IP from those available + if ( count($dns) ) + return $dns[ array_rand($dns) ]; + + } + } + // if all else fails try the host name + return $host; } // Returns array with headers in $response[0] and body in $response[1] -function akismet_http_post($request, $host, $path, $port = 80) { +function akismet_http_post($request, $host, $path, $port = 80, $ip=null) { global $wp_version; + + $akismet_version = constant('AKISMET_VERSION'); $http_request = "POST $path HTTP/1.0\r\n"; $http_request .= "Host: $host\r\n"; $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=" . get_option('blog_charset') . "\r\n"; $http_request .= "Content-Length: " . strlen($request) . "\r\n"; - $http_request .= "User-Agent: WordPress/$wp_version | Akismet/2.0\r\n"; + $http_request .= "User-Agent: WordPress/$wp_version | Akismet/$akismet_version\r\n"; $http_request .= "\r\n"; $http_request .= $request; + + $http_host = $host; + // use a specific IP if provided - needed by akismet_check_server_connectivity() + if ( $ip && long2ip(ip2long($ip)) ) { + $http_host = $ip; + } else { + $http_host = akismet_get_host($host); + } $response = ''; - if( false != ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { + if( false != ( $fs = @fsockopen($http_host, $port, $errno, $errstr, 10) ) ) { fwrite($fs, $http_request); while ( !feof($fs) ) @@ -181,6 +404,14 @@ function akismet_http_post($request, $host, $path, $port = 80) { return $response; } +// filter handler used to return a spam result to pre_comment_approved +function akismet_result_spam( $approved ) { + // bump the counter here instead of when the filter is added to reduce the possibility of overcounting + if ( $incr = apply_filters('akismet_spam_count_incr', 1) ) + update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr ); + return 'spam'; +} + function akismet_auto_check_comment( $comment ) { global $akismet_api_host, $akismet_api_port; @@ -188,11 +419,14 @@ function akismet_auto_check_comment( $comment ) { $comment['user_agent'] = $_SERVER['HTTP_USER_AGENT']; $comment['referrer'] = $_SERVER['HTTP_REFERER']; $comment['blog'] = get_option('home'); + $comment['blog_lang'] = get_locale(); + $comment['blog_charset'] = get_option('blog_charset'); + $comment['permalink'] = get_permalink($comment['comment_post_ID']); $ignore = array( 'HTTP_COOKIE' ); foreach ( $_SERVER as $key => $value ) - if ( !in_array( $key, $ignore ) ) + if ( !in_array( $key, $ignore ) && is_string($value) ) $comment["$key"] = $value; $query_string = ''; @@ -201,16 +435,22 @@ function akismet_auto_check_comment( $comment ) { $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port); if ( 'true' == $response[1] ) { - add_filter('pre_comment_approved', create_function('$a', 'return \'spam\';')); - update_option( 'akismet_spam_count', get_option('akismet_spam_count') + 1 ); + // akismet_spam_count will be incremented later by akismet_result_spam() + add_filter('pre_comment_approved', 'akismet_result_spam'); + + do_action( 'akismet_spam_caught' ); $post = get_post( $comment['comment_post_ID'] ); $last_updated = strtotime( $post->post_modified_gmt ); $diff = time() - $last_updated; $diff = $diff / 86400; - - if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' ) + + if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' ) { + // akismet_result_spam() won't be called so bump the counter here + if ( $incr = apply_filters('akismet_spam_count_incr', 1) ) + update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr ); die; + } } akismet_delete_old(); return $comment; @@ -226,20 +466,32 @@ function akismet_delete_old() { } function akismet_submit_nonspam_comment ( $comment_id ) { - global $wpdb, $akismet_api_host, $akismet_api_port; - + global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site; + $comment_id = (int) $comment_id; + $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'"); if ( !$comment ) // it was deleted return; $comment->blog = get_option('home'); + $comment->blog_lang = get_locale(); + $comment->blog_charset = get_option('blog_charset'); + $comment->permalink = get_permalink($comment->comment_post_ID); + if ( is_object($current_user) ) { + $comment->reporter = $current_user->user_login; + } + if ( is_object($current_site) ) { + $comment->site_domain = $current_site->domain; + } $query_string = ''; foreach ( $comment as $key => $data ) $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; + $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port); } function akismet_submit_spam_comment ( $comment_id ) { - global $wpdb, $akismet_api_host, $akismet_api_port; + global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site; + $comment_id = (int) $comment_id; $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'"); if ( !$comment ) // it was deleted @@ -247,6 +499,15 @@ function akismet_submit_spam_comment ( $comment_id ) { if ( 'spam' != $comment->comment_approved ) return; $comment->blog = get_option('home'); + $comment->blog_lang = get_locale(); + $comment->blog_charset = get_option('blog_charset'); + $comment->permalink = get_permalink($comment->comment_post_ID); + if ( is_object($current_user) ) { + $comment->reporter = $current_user->user_login; + } + if ( is_object($current_site) ) { + $comment->site_domain = $current_site->domain; + } $query_string = ''; foreach ( $comment as $key => $data ) $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; @@ -258,18 +519,79 @@ add_action('wp_set_comment_status', 'akismet_submit_spam_comment'); add_action('edit_comment', 'akismet_submit_spam_comment'); add_action('preprocess_comment', 'akismet_auto_check_comment', 1); -function akismet_spam_count() { - global $wpdb, $comments; - $count = wp_cache_get( 'akismet_spam_count', 'widget' ); - if ( false === $count ) { - $count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'"); - wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 ); +function akismet_spamtoham( $comment ) { akismet_submit_nonspam_comment( $comment->comment_ID ); } +add_filter( 'comment_spam_to_approved', 'akismet_spamtoham' ); + +// Total spam in queue +// get_option( 'akismet_spam_count' ) is the total caught ever +function akismet_spam_count( $type = false ) { + global $wpdb; + + if ( !$type ) { // total + $count = wp_cache_get( 'akismet_spam_count', 'widget' ); + if ( false === $count ) { + if ( function_exists('wp_count_comments') ) { + $count = wp_count_comments(); + $count = $count->spam; + } else { + $count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'"); + } + wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 ); + } + return $count; + } elseif ( 'comments' == $type || 'comment' == $type ) { // comments + $type = ''; + } else { // pingback, trackback, ... + $type = $wpdb->escape( $type ); + } + + return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'"); +} + +function akismet_spam_comments( $type = false, $page = 1, $per_page = 50 ) { + global $wpdb; + + $page = (int) $page; + if ( $page < 2 ) + $page = 1; + + $per_page = (int) $per_page; + if ( $per_page < 1 ) + $per_page = 50; + + $start = ( $page - 1 ) * $per_page; + $end = $start + $per_page; + + if ( $type ) { + if ( 'comments' == $type || 'comment' == $type ) + $type = ''; + else + $type = $wpdb->escape( $type ); + return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type' ORDER BY comment_date DESC LIMIT $start, $end"); } - return $count; + + // All + return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end"); +} + +// Totals for each comment type +// returns array( type => count, ... ) +function akismet_spam_totals() { + global $wpdb; + $totals = $wpdb->get_results( "SELECT comment_type, COUNT(*) AS cc FROM $wpdb->comments WHERE comment_approved = 'spam' GROUP BY comment_type" ); + $return = array(); + foreach ( $totals as $total ) + $return[$total->comment_type ? $total->comment_type : 'comment'] = $total->cc; + return $return; } function akismet_manage_page() { - global $wpdb, $submenu; + global $wpdb, $submenu, $wp_db_version; + + // WP 2.7 has its own spam management page + if ( 8645 <= $wp_db_version ) + return; + $count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count()); if ( isset( $submenu['edit-comments.php'] ) ) add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' ); @@ -279,12 +601,13 @@ function akismet_manage_page() { function akismet_caught() { global $wpdb, $comment, $akismet_caught, $akismet_nonce; + akismet_recheck_queue(); if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) { check_admin_referer( $akismet_nonce ); if ( function_exists('current_user_can') && !current_user_can('moderate_comments') ) die(__('You do not have sufficient permission to moderate comments.')); - + $i = 0; foreach ($_POST['not_spam'] as $comment): $comment = (int) $comment; @@ -304,7 +627,7 @@ function akismet_caught() { if ( function_exists('current_user_can') && !current_user_can('moderate_comments') ) die(__('You do not have sufficient permission to moderate comments.')); - $delete_time = addslashes( $_POST['display_time'] ); + $delete_time = $wpdb->escape( $_POST['display_time'] ); $nuked = $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" ); wp_cache_delete( 'akismet_spam_count', 'widget' ); $to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] ); @@ -325,17 +648,59 @@ if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) ) else $link = 'edit.php'; ?> +%1$s spam for you since you first installed it.'), number_format($count) ); ?>
+%1$s spam for you since you first installed it.'), number_format_i18n($count) ); ?>
'.__('You have no spam currently in the queue. Must be your lucky day. :)').''; echo '$r
"; ?> - -