web/wp-content/plugins/akismet/akismet.php
branchwordpress
changeset 109 03b0d1493584
child 132 4d4862461b8d
equal deleted inserted replaced
-1:000000000000 109:03b0d1493584
       
     1 <?php
       
     2 /*
       
     3 Plugin Name: Akismet
       
     4 Plugin URI: http://akismet.com/
       
     5 Description: Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need a <a href="http://wordpress.com/api-keys/">WordPress.com API key</a> to use it. You can review the spam it catches under "Comments." To show off your Akismet stats just put <code>&lt;?php akismet_counter(); ?&gt;</code> in your template. See also: <a href="http://wordpress.org/extend/plugins/stats/">WP Stats plugin</a>.
       
     6 Version: 2.2.6
       
     7 Author: Matt Mullenweg
       
     8 Author URI: http://ma.tt/
       
     9 */
       
    10 
       
    11 define('AKISMET_VERSION', '2.2.6');
       
    12 
       
    13 // If you hardcode a WP.com API key here, all key config screens will be hidden
       
    14 if ( defined('WPCOM_API_KEY') )
       
    15 	$wpcom_api_key = constant('WPCOM_API_KEY');
       
    16 else
       
    17 	$wpcom_api_key = '';
       
    18 
       
    19 function akismet_init() {
       
    20 	global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
       
    21 
       
    22 	if ( $wpcom_api_key )
       
    23 		$akismet_api_host = $wpcom_api_key . '.rest.akismet.com';
       
    24 	else
       
    25 		$akismet_api_host = get_option('wordpress_api_key') . '.rest.akismet.com';
       
    26 
       
    27 	$akismet_api_port = 80;
       
    28 	add_action('admin_menu', 'akismet_config_page');
       
    29 	add_action('admin_menu', 'akismet_stats_page');
       
    30 	akismet_admin_warnings();
       
    31 }
       
    32 add_action('init', 'akismet_init');
       
    33 
       
    34 function akismet_admin_init() {
       
    35 	if ( function_exists( 'get_plugin_page_hook' ) )
       
    36 		$hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' );
       
    37 	else
       
    38 		$hook = 'dashboard_page_akismet-stats-display';
       
    39 	add_action('admin_head-'.$hook, 'akismet_stats_script');
       
    40 }
       
    41 add_action('admin_init', 'akismet_admin_init');
       
    42 
       
    43 if ( !function_exists('wp_nonce_field') ) {
       
    44 	function akismet_nonce_field($action = -1) { return; }
       
    45 	$akismet_nonce = -1;
       
    46 } else {
       
    47 	function akismet_nonce_field($action = -1) { return wp_nonce_field($action); }
       
    48 	$akismet_nonce = 'akismet-update-key';
       
    49 }
       
    50 
       
    51 if ( !function_exists('number_format_i18n') ) {
       
    52 	function number_format_i18n( $number, $decimals = null ) { return number_format( $number, $decimals ); }
       
    53 }
       
    54 
       
    55 function akismet_config_page() {
       
    56 	if ( function_exists('add_submenu_page') )
       
    57 		add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
       
    58 
       
    59 }
       
    60 
       
    61 function akismet_conf() {
       
    62 	global $akismet_nonce, $wpcom_api_key;
       
    63 
       
    64 	if ( isset($_POST['submit']) ) {
       
    65 		if ( function_exists('current_user_can') && !current_user_can('manage_options') )
       
    66 			die(__('Cheatin&#8217; uh?'));
       
    67 
       
    68 		check_admin_referer( $akismet_nonce );
       
    69 		$key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] );
       
    70 
       
    71 		if ( empty($key) ) {
       
    72 			$key_status = 'empty';
       
    73 			$ms[] = 'new_key_empty';
       
    74 			delete_option('wordpress_api_key');
       
    75 		} else {
       
    76 			$key_status = akismet_verify_key( $key );
       
    77 		}
       
    78 
       
    79 		if ( $key_status == 'valid' ) {
       
    80 			update_option('wordpress_api_key', $key);
       
    81 			$ms[] = 'new_key_valid';
       
    82 		} else if ( $key_status == 'invalid' ) {
       
    83 			$ms[] = 'new_key_invalid';
       
    84 		} else if ( $key_status == 'failed' ) {
       
    85 			$ms[] = 'new_key_failed';
       
    86 		}
       
    87 
       
    88 		if ( isset( $_POST['akismet_discard_month'] ) )
       
    89 			update_option( 'akismet_discard_month', 'true' );
       
    90 		else
       
    91 			update_option( 'akismet_discard_month', 'false' );
       
    92 	} elseif ( isset($_POST['check']) ) {
       
    93 		akismet_get_server_connectivity(0);
       
    94 	}
       
    95 
       
    96 	if ( $key_status != 'valid' ) {
       
    97 		$key = get_option('wordpress_api_key');
       
    98 		if ( empty( $key ) ) {
       
    99 			if ( $key_status != 'failed' ) {
       
   100 				if ( akismet_verify_key( '1234567890ab' ) == 'failed' )
       
   101 					$ms[] = 'no_connection';
       
   102 				else
       
   103 					$ms[] = 'key_empty';
       
   104 			}
       
   105 			$key_status = 'empty';
       
   106 		} else {
       
   107 			$key_status = akismet_verify_key( $key );
       
   108 		}
       
   109 		if ( $key_status == 'valid' ) {
       
   110 			$ms[] = 'key_valid';
       
   111 		} else if ( $key_status == 'invalid' ) {
       
   112 			delete_option('wordpress_api_key');
       
   113 			$ms[] = 'key_empty';
       
   114 		} else if ( !empty($key) && $key_status == 'failed' ) {
       
   115 			$ms[] = 'key_failed';
       
   116 		}
       
   117 	}
       
   118 
       
   119 	$messages = array(
       
   120 		'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')),
       
   121 		'new_key_valid' => array('color' => '2d2', 'text' => __('Your key has been verified. Happy blogging!')),
       
   122 		'new_key_invalid' => array('color' => 'd22', 'text' => __('The key you entered is invalid. Please double-check it.')),
       
   123 		'new_key_failed' => array('color' => 'd22', 'text' => __('The key you entered could not be verified because a connection to akismet.com could not be established. Please check your server configuration.')),
       
   124 		'no_connection' => array('color' => 'd22', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')),
       
   125 		'key_empty' => array('color' => 'aa0', 'text' => sprintf(__('Please enter an API key. (<a href="%s" style="color:#fff">Get your key.</a>)'), 'http://wordpress.com/profile/')),
       
   126 		'key_valid' => array('color' => '2d2', 'text' => __('This key is valid.')),
       
   127 		'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.')));
       
   128 ?>
       
   129 <?php if ( !empty($_POST['submit'] ) ) : ?>
       
   130 <div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
       
   131 <?php endif; ?>
       
   132 <div class="wrap">
       
   133 <h2><?php _e('Akismet Configuration'); ?></h2>
       
   134 <div class="narrow">
       
   135 <form action="" method="post" id="akismet-conf" style="margin: auto; width: 400px; ">
       
   136 <?php if ( !$wpcom_api_key ) { ?>
       
   137 	<p><?php printf(__('For many people, <a href="%1$s">Akismet</a> will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as "spam" on the moderation screen and Akismet will learn from the mistakes. If you don\'t have a WordPress.com account yet, you can get one at <a href="%2$s">WordPress.com</a>.'), 'http://akismet.com/', 'http://wordpress.com/api-keys/'); ?></p>
       
   138 
       
   139 <?php akismet_nonce_field($akismet_nonce) ?>
       
   140 <h3><label for="key"><?php _e('WordPress.com API Key'); ?></label></h3>
       
   141 <?php foreach ( $ms as $m ) : ?>
       
   142 	<p style="padding: .5em; background-color: #<?php echo $messages[$m]['color']; ?>; color: #fff; font-weight: bold;"><?php echo $messages[$m]['text']; ?></p>
       
   143 <?php endforeach; ?>
       
   144 <p><input id="key" name="key" type="text" size="15" maxlength="12" value="<?php echo get_option('wordpress_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="http://faq.wordpress.com/2005/10/19/api-key/">What is this?</a>'); ?>)</p>
       
   145 <?php if ( $invalid_key ) { ?>
       
   146 <h3><?php _e('Why might my key be invalid?'); ?></h3>
       
   147 <p><?php _e('This can mean one of two things, either you copied the key wrong or that the plugin is unable to reach the Akismet servers, which is most often caused by an issue with your web host around firewalls or similar.'); ?></p>
       
   148 <?php } ?>
       
   149 <?php } ?>
       
   150 <p><label><input name="akismet_discard_month" id="akismet_discard_month" value="true" type="checkbox" <?php if ( get_option('akismet_discard_month') == 'true' ) echo ' checked="checked" '; ?> /> <?php _e('Automatically discard spam comments on posts older than a month.'); ?></label></p>
       
   151 	<p class="submit"><input type="submit" name="submit" value="<?php _e('Update options &raquo;'); ?>" /></p>
       
   152 </form>
       
   153 
       
   154 <form action="" method="post" id="akismet-connectivity" style="margin: auto; width: 400px; ">
       
   155 
       
   156 <h3><?php _e('Server Connectivity'); ?></h3>
       
   157 <?php
       
   158 	$servers = akismet_get_server_connectivity();
       
   159 	$fail_count = count($servers) - count( array_filter($servers) );
       
   160 	if ( is_array($servers) && count($servers) > 0 ) {
       
   161 		// some connections work, some fail
       
   162 		if ( $fail_count > 0 && $fail_count < count($servers) ) { ?>
       
   163 			<p style="padding: .5em; background-color: #aa0; color: #fff; font-weight:bold;"><?php _e('Unable to reach some Akismet servers.'); ?></p>
       
   164 			<p><?php echo sprintf( __('A network problem or firewall is blocking some connections from your web server to Akismet.com.  Akismet is working but this may cause problems during times of network congestion.  Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
       
   165 		<?php
       
   166 		// all connections fail
       
   167 		} elseif ( $fail_count > 0 ) { ?>
       
   168 			<p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Unable to reach any Akismet servers.'); ?></p>
       
   169 			<p><?php echo sprintf( __('A network problem or firewall is blocking all connections from your web server to Akismet.com.  <strong>Akismet cannot work correctly until this is fixed.</strong>  Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
       
   170 		<?php
       
   171 		// all connections work
       
   172 		} else { ?>
       
   173 			<p style="padding: .5em; background-color: #2d2; color: #fff; font-weight:bold;"><?php  _e('All Akismet servers are available.'); ?></p>
       
   174 			<p><?php _e('Akismet is working correctly.  All servers are accessible.'); ?></p>
       
   175 		<?php
       
   176 		}
       
   177 	} elseif ( !is_callable('fsockopen') ) {
       
   178 		?>
       
   179 			<p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Network functions are disabled.'); ?></p>
       
   180 			<p><?php echo sprintf( __('Your web host or server administrator has disabled PHP\'s <code>fsockopen</code> function.  <strong>Akismet cannot work correctly until this is fixed.</strong>  Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet\'s system requirements</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
       
   181 		<?php
       
   182 	} else {
       
   183 		?>
       
   184 			<p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Unable to find Akismet servers.'); ?></p>
       
   185 			<p><?php echo sprintf( __('A DNS problem or firewall is preventing all access from your web server to Akismet.com.  <strong>Akismet cannot work correctly until this is fixed.</strong>  Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
       
   186 		<?php
       
   187 	}
       
   188 	
       
   189 	if ( !empty($servers) ) {
       
   190 ?>
       
   191 <table style="width: 100%;">
       
   192 <thead><th><?php _e('Akismet server'); ?></th><th><?php _e('Network Status'); ?></th></thead>
       
   193 <tbody>
       
   194 <?php
       
   195 		asort($servers);
       
   196 		foreach ( $servers as $ip => $status ) {
       
   197 			$color = ( $status ? '#2d2' : '#d22');
       
   198 	?>
       
   199 		<tr>
       
   200 		<td><?php echo htmlspecialchars($ip); ?></td>
       
   201 		<td style="padding: 0 .5em; font-weight:bold; color: #fff; background-color: <?php echo $color; ?>"><?php echo ($status ? __('No problems') : __('Obstructed') ); ?></td>
       
   202 		
       
   203 	<?php
       
   204 		}
       
   205 	}
       
   206 ?>
       
   207 </tbody>
       
   208 </table>
       
   209 	<p><?php if ( get_option('akismet_connectivity_time') ) echo sprintf( __('Last checked %s ago.'), human_time_diff( get_option('akismet_connectivity_time') ) ); ?></p>
       
   210 	<p class="submit"><input type="submit" name="check" value="<?php _e('Check network status &raquo;'); ?>" /></p>
       
   211 </form>
       
   212 
       
   213 </div>
       
   214 </div>
       
   215 <?php
       
   216 }
       
   217 
       
   218 function akismet_stats_page() {
       
   219 	if ( function_exists('add_submenu_page') )
       
   220 		add_submenu_page('index.php', __('Akismet Stats'), __('Akismet Stats'), 'manage_options', 'akismet-stats-display', 'akismet_stats_display');
       
   221 
       
   222 }
       
   223 
       
   224 function akismet_stats_script() {
       
   225 	?>
       
   226 <script type="text/javascript">
       
   227 function resizeIframe() {
       
   228     var height = document.documentElement.clientHeight;
       
   229     height -= document.getElementById('akismet-stats-frame').offsetTop;
       
   230     height += 100; // magic padding
       
   231     
       
   232     document.getElementById('akismet-stats-frame').style.height = height +"px";
       
   233     
       
   234 };
       
   235 function resizeIframeInit() {
       
   236 	document.getElementById('akismet-stats-frame').onload = resizeIframe;
       
   237 	window.onresize = resizeIframe;
       
   238 }
       
   239 addLoadEvent(resizeIframeInit);
       
   240 </script><?php
       
   241 }
       
   242 
       
   243 
       
   244 function akismet_stats_display() {
       
   245 	global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
       
   246 	$blog = urlencode( get_option('home') );
       
   247 	$url = "http://".akismet_get_key().".web.akismet.com/1.0/user-stats.php?blog={$blog}";
       
   248 	?>
       
   249 	<div class="wrap">
       
   250 	<iframe src="<?php echo $url; ?>" width="100%" height="100%" frameborder="0" id="akismet-stats-frame"></iframe>
       
   251 	</div>
       
   252 	<?php
       
   253 }
       
   254 
       
   255 function akismet_get_key() {
       
   256 	global $wpcom_api_key;
       
   257 	if ( !empty($wpcom_api_key) )
       
   258 		return $wpcom_api_key;
       
   259 	return get_option('wordpress_api_key');
       
   260 }
       
   261 
       
   262 function akismet_verify_key( $key, $ip = null ) {
       
   263 	global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
       
   264 	$blog = urlencode( get_option('home') );
       
   265 	if ( $wpcom_api_key )
       
   266 		$key = $wpcom_api_key;
       
   267 	$response = akismet_http_post("key=$key&blog=$blog", 'rest.akismet.com', '/1.1/verify-key', $akismet_api_port, $ip);
       
   268 	if ( !is_array($response) || !isset($response[1]) || $response[1] != 'valid' && $response[1] != 'invalid' )
       
   269 		return 'failed';
       
   270 	return $response[1];
       
   271 }
       
   272 
       
   273 // Check connectivity between the WordPress blog and Akismet's servers.
       
   274 // 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).
       
   275 function akismet_check_server_connectivity() {
       
   276 	global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
       
   277 	
       
   278 	$test_host = 'rest.akismet.com';
       
   279 	
       
   280 	// Some web hosts may disable one or both functions
       
   281 	if ( !is_callable('fsockopen') || !is_callable('gethostbynamel') )
       
   282 		return array();
       
   283 	
       
   284 	$ips = gethostbynamel($test_host);
       
   285 	if ( !$ips || !is_array($ips) || !count($ips) )
       
   286 		return array();
       
   287 		
       
   288 	$servers = array();
       
   289 	foreach ( $ips as $ip ) {
       
   290 		$response = akismet_verify_key( akismet_get_key(), $ip );
       
   291 		// even if the key is invalid, at least we know we have connectivity
       
   292 		if ( $response == 'valid' || $response == 'invalid' )
       
   293 			$servers[$ip] = true;
       
   294 		else
       
   295 			$servers[$ip] = false;
       
   296 	}
       
   297 
       
   298 	return $servers;
       
   299 }
       
   300 
       
   301 // Check the server connectivity and store the results in an option.
       
   302 // Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update.
       
   303 // Returns the same associative array as akismet_check_server_connectivity()
       
   304 function akismet_get_server_connectivity( $cache_timeout = 86400 ) {
       
   305 	$servers = get_option('akismet_available_servers');
       
   306 	if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false )
       
   307 		return $servers;
       
   308 	
       
   309 	// There's a race condition here but the effect is harmless.
       
   310 	$servers = akismet_check_server_connectivity();
       
   311 	update_option('akismet_available_servers', $servers);
       
   312 	update_option('akismet_connectivity_time', time());
       
   313 	return $servers;
       
   314 }
       
   315 
       
   316 // Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed.
       
   317 function akismet_server_connectivity_ok() {
       
   318 	// skip the check on WPMU because the status page is hidden
       
   319 	global $wpcom_api_key;
       
   320 	if ( $wpcom_api_key )
       
   321 		return true;
       
   322 	$servers = akismet_get_server_connectivity();
       
   323 	return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) );
       
   324 }
       
   325 
       
   326 function akismet_admin_warnings() {
       
   327 	global $wpcom_api_key;
       
   328 	if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
       
   329 		function akismet_warning() {
       
   330 			echo "
       
   331 			<div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet is almost ready.')."</strong> ".sprintf(__('You must <a href="%1$s">enter your WordPress.com API key</a> for it to work.'), "plugins.php?page=akismet-key-config")."</p></div>
       
   332 			";
       
   333 		}
       
   334 		add_action('admin_notices', 'akismet_warning');
       
   335 		return;
       
   336 	} elseif ( get_option('akismet_connectivity_time') && empty($_POST) && is_admin() && !akismet_server_connectivity_ok() ) {
       
   337 		function akismet_warning() {
       
   338 			echo "
       
   339 			<div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet has detected a problem.')."</strong> ".sprintf(__('A server or network problem is preventing Akismet from working correctly.  <a href="%1$s">Click here for more information</a> about how to fix the problem.'), "plugins.php?page=akismet-key-config")."</p></div>
       
   340 			";
       
   341 		}
       
   342 		add_action('admin_notices', 'akismet_warning');
       
   343 		return;
       
   344 	}
       
   345 }
       
   346 
       
   347 function akismet_get_host($host) {
       
   348 	// if all servers are accessible, just return the host name.
       
   349 	// if not, return an IP that was known to be accessible at the last check.
       
   350 	if ( akismet_server_connectivity_ok() ) {
       
   351 		return $host;
       
   352 	} else {
       
   353 		$ips = akismet_get_server_connectivity();
       
   354 		// a firewall may be blocking access to some Akismet IPs
       
   355 		if ( count($ips) > 0 && count(array_filter($ips)) < count($ips) ) {
       
   356 			// use DNS to get current IPs, but exclude any known to be unreachable
       
   357 			$dns = (array)gethostbynamel( rtrim($host, '.') . '.' );
       
   358 			$dns = array_filter($dns);
       
   359 			foreach ( $dns as $ip ) {
       
   360 				if ( array_key_exists( $ip, $ips ) && empty( $ips[$ip] ) )
       
   361 					unset($dns[$ip]);
       
   362 			}
       
   363 			// return a random IP from those available
       
   364 			if ( count($dns) )
       
   365 				return $dns[ array_rand($dns) ];
       
   366 			
       
   367 		}
       
   368 	}
       
   369 	// if all else fails try the host name
       
   370 	return $host;
       
   371 }
       
   372 
       
   373 // Returns array with headers in $response[0] and body in $response[1]
       
   374 function akismet_http_post($request, $host, $path, $port = 80, $ip=null) {
       
   375 	global $wp_version;
       
   376 	
       
   377 	$akismet_version = constant('AKISMET_VERSION');
       
   378 
       
   379 	$http_request  = "POST $path HTTP/1.0\r\n";
       
   380 	$http_request .= "Host: $host\r\n";
       
   381 	$http_request .= "Content-Type: application/x-www-form-urlencoded; charset=" . get_option('blog_charset') . "\r\n";
       
   382 	$http_request .= "Content-Length: " . strlen($request) . "\r\n";
       
   383 	$http_request .= "User-Agent: WordPress/$wp_version | Akismet/$akismet_version\r\n";
       
   384 	$http_request .= "\r\n";
       
   385 	$http_request .= $request;
       
   386 	
       
   387 	$http_host = $host;
       
   388 	// use a specific IP if provided - needed by akismet_check_server_connectivity()
       
   389 	if ( $ip && long2ip(ip2long($ip)) ) {
       
   390 		$http_host = $ip;
       
   391 	} else {
       
   392 		$http_host = akismet_get_host($host);
       
   393 	}
       
   394 
       
   395 	$response = '';
       
   396 	if( false != ( $fs = @fsockopen($http_host, $port, $errno, $errstr, 10) ) ) {
       
   397 		fwrite($fs, $http_request);
       
   398 
       
   399 		while ( !feof($fs) )
       
   400 			$response .= fgets($fs, 1160); // One TCP-IP packet
       
   401 		fclose($fs);
       
   402 		$response = explode("\r\n\r\n", $response, 2);
       
   403 	}
       
   404 	return $response;
       
   405 }
       
   406 
       
   407 // filter handler used to return a spam result to pre_comment_approved
       
   408 function akismet_result_spam( $approved ) {
       
   409 	// bump the counter here instead of when the filter is added to reduce the possibility of overcounting
       
   410 	if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
       
   411 		update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
       
   412 	return 'spam';
       
   413 }
       
   414 
       
   415 function akismet_auto_check_comment( $comment ) {
       
   416 	global $akismet_api_host, $akismet_api_port;
       
   417 
       
   418 	$comment['user_ip']    = preg_replace( '/[^0-9., ]/', '', $_SERVER['REMOTE_ADDR'] );
       
   419 	$comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
       
   420 	$comment['referrer']   = $_SERVER['HTTP_REFERER'];
       
   421 	$comment['blog']       = get_option('home');
       
   422 	$comment['blog_lang']  = get_locale();
       
   423 	$comment['blog_charset'] = get_option('blog_charset');
       
   424 	$comment['permalink']  = get_permalink($comment['comment_post_ID']);
       
   425 
       
   426 	$ignore = array( 'HTTP_COOKIE' );
       
   427 
       
   428 	foreach ( $_SERVER as $key => $value )
       
   429 		if ( !in_array( $key, $ignore ) && is_string($value) )
       
   430 			$comment["$key"] = $value;
       
   431 
       
   432 	$query_string = '';
       
   433 	foreach ( $comment as $key => $data )
       
   434 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
       
   435 
       
   436 	$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
       
   437 	if ( 'true' == $response[1] ) {
       
   438 		// akismet_spam_count will be incremented later by akismet_result_spam()
       
   439 		add_filter('pre_comment_approved', 'akismet_result_spam');
       
   440 
       
   441 		do_action( 'akismet_spam_caught' );
       
   442 
       
   443 		$post = get_post( $comment['comment_post_ID'] );
       
   444 		$last_updated = strtotime( $post->post_modified_gmt );
       
   445 		$diff = time() - $last_updated;
       
   446 		$diff = $diff / 86400;
       
   447 		
       
   448 		if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' ) {
       
   449 			// akismet_result_spam() won't be called so bump the counter here
       
   450 			if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
       
   451 				update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
       
   452 			die;
       
   453 		}
       
   454 	}
       
   455 	akismet_delete_old();
       
   456 	return $comment;
       
   457 }
       
   458 
       
   459 function akismet_delete_old() {
       
   460 	global $wpdb;
       
   461 	$now_gmt = current_time('mysql', 1);
       
   462 	$wpdb->query("DELETE FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'");
       
   463 	$n = mt_rand(1, 5000);
       
   464 	if ( $n == 11 ) // lucky number
       
   465 		$wpdb->query("OPTIMIZE TABLE $wpdb->comments");
       
   466 }
       
   467 
       
   468 function akismet_submit_nonspam_comment ( $comment_id ) {
       
   469 	global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
       
   470 	$comment_id = (int) $comment_id;
       
   471 	
       
   472 	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
       
   473 	if ( !$comment ) // it was deleted
       
   474 		return;
       
   475 	$comment->blog = get_option('home');
       
   476 	$comment->blog_lang = get_locale();
       
   477 	$comment->blog_charset = get_option('blog_charset');
       
   478 	$comment->permalink = get_permalink($comment->comment_post_ID);
       
   479 	if ( is_object($current_user) ) {
       
   480 	    $comment->reporter = $current_user->user_login;
       
   481 	}
       
   482 	if ( is_object($current_site) ) {
       
   483 		$comment->site_domain = $current_site->domain;
       
   484 	}
       
   485 	$query_string = '';
       
   486 	foreach ( $comment as $key => $data )
       
   487 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
       
   488 
       
   489 	$response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
       
   490 }
       
   491 
       
   492 function akismet_submit_spam_comment ( $comment_id ) {
       
   493 	global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
       
   494 	$comment_id = (int) $comment_id;
       
   495 
       
   496 	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
       
   497 	if ( !$comment ) // it was deleted
       
   498 		return;
       
   499 	if ( 'spam' != $comment->comment_approved )
       
   500 		return;
       
   501 	$comment->blog = get_option('home');
       
   502 	$comment->blog_lang = get_locale();
       
   503 	$comment->blog_charset = get_option('blog_charset');
       
   504 	$comment->permalink = get_permalink($comment->comment_post_ID);
       
   505 	if ( is_object($current_user) ) {
       
   506 	    $comment->reporter = $current_user->user_login;
       
   507 	}
       
   508 	if ( is_object($current_site) ) {
       
   509 		$comment->site_domain = $current_site->domain;
       
   510 	}
       
   511 	$query_string = '';
       
   512 	foreach ( $comment as $key => $data )
       
   513 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
       
   514 
       
   515 	$response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
       
   516 }
       
   517 
       
   518 add_action('wp_set_comment_status', 'akismet_submit_spam_comment');
       
   519 add_action('edit_comment', 'akismet_submit_spam_comment');
       
   520 add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
       
   521 
       
   522 function akismet_spamtoham( $comment ) { akismet_submit_nonspam_comment( $comment->comment_ID ); }
       
   523 add_filter( 'comment_spam_to_approved', 'akismet_spamtoham' );
       
   524 
       
   525 // Total spam in queue
       
   526 // get_option( 'akismet_spam_count' ) is the total caught ever
       
   527 function akismet_spam_count( $type = false ) {
       
   528 	global $wpdb;
       
   529 
       
   530 	if ( !$type ) { // total
       
   531 		$count = wp_cache_get( 'akismet_spam_count', 'widget' );
       
   532 		if ( false === $count ) {
       
   533 			if ( function_exists('wp_count_comments') ) {
       
   534 				$count = wp_count_comments();
       
   535 				$count = $count->spam;
       
   536 			} else {
       
   537 				$count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
       
   538 			}
       
   539 			wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
       
   540 		}
       
   541 		return $count;
       
   542 	} elseif ( 'comments' == $type || 'comment' == $type ) { // comments
       
   543 		$type = '';
       
   544 	} else { // pingback, trackback, ...
       
   545 		$type  = $wpdb->escape( $type );
       
   546 	}
       
   547 
       
   548 	return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
       
   549 }
       
   550 
       
   551 function akismet_spam_comments( $type = false, $page = 1, $per_page = 50 ) {
       
   552 	global $wpdb;
       
   553 
       
   554 	$page = (int) $page;
       
   555 	if ( $page < 2 )
       
   556 		$page = 1;
       
   557 
       
   558 	$per_page = (int) $per_page;
       
   559 	if ( $per_page < 1 )
       
   560 		$per_page = 50;
       
   561 
       
   562 	$start = ( $page - 1 ) * $per_page;
       
   563 	$end = $start + $per_page;
       
   564 
       
   565 	if ( $type ) {
       
   566 		if ( 'comments' == $type || 'comment' == $type )
       
   567 			$type = '';
       
   568 		else
       
   569 			$type = $wpdb->escape( $type );
       
   570 		return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type' ORDER BY comment_date DESC LIMIT $start, $end");
       
   571 	}
       
   572 
       
   573 	// All
       
   574 	return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end");
       
   575 }
       
   576 
       
   577 // Totals for each comment type
       
   578 // returns array( type => count, ... )
       
   579 function akismet_spam_totals() {
       
   580 	global $wpdb;
       
   581 	$totals = $wpdb->get_results( "SELECT comment_type, COUNT(*) AS cc FROM $wpdb->comments WHERE comment_approved = 'spam' GROUP BY comment_type" );
       
   582 	$return = array();
       
   583 	foreach ( $totals as $total )
       
   584 		$return[$total->comment_type ? $total->comment_type : 'comment'] = $total->cc;
       
   585 	return $return;
       
   586 }
       
   587 
       
   588 function akismet_manage_page() {
       
   589 	global $wpdb, $submenu, $wp_db_version;
       
   590 
       
   591 	// WP 2.7 has its own spam management page
       
   592 	if ( 8645 <= $wp_db_version )
       
   593 		return;
       
   594 
       
   595 	$count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count());
       
   596 	if ( isset( $submenu['edit-comments.php'] ) )
       
   597 		add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' );
       
   598 	elseif ( function_exists('add_management_page') )
       
   599 		add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught');
       
   600 }
       
   601 
       
   602 function akismet_caught() {
       
   603 	global $wpdb, $comment, $akismet_caught, $akismet_nonce;
       
   604 
       
   605 	akismet_recheck_queue();
       
   606 	if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) {
       
   607 		check_admin_referer( $akismet_nonce );
       
   608 		if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
       
   609 			die(__('You do not have sufficient permission to moderate comments.'));
       
   610 
       
   611 		$i = 0;
       
   612 		foreach ($_POST['not_spam'] as $comment):
       
   613 			$comment = (int) $comment;
       
   614 			if ( function_exists('wp_set_comment_status') )
       
   615 				wp_set_comment_status($comment, 'approve');
       
   616 			else
       
   617 				$wpdb->query("UPDATE $wpdb->comments SET comment_approved = '1' WHERE comment_ID = '$comment'");
       
   618 			akismet_submit_nonspam_comment($comment);
       
   619 			++$i;
       
   620 		endforeach;
       
   621 		$to = add_query_arg( 'recovered', $i, $_SERVER['HTTP_REFERER'] );
       
   622 		wp_redirect( $to );
       
   623 		exit;
       
   624 	}
       
   625 	if ('delete' == $_POST['action']) {
       
   626 		check_admin_referer( $akismet_nonce );
       
   627 		if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
       
   628 			die(__('You do not have sufficient permission to moderate comments.'));
       
   629 
       
   630 		$delete_time = $wpdb->escape( $_POST['display_time'] );
       
   631 		$nuked = $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" );
       
   632 		wp_cache_delete( 'akismet_spam_count', 'widget' );
       
   633 		$to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] );
       
   634 		wp_redirect( $to );
       
   635 		exit;
       
   636 	}
       
   637 
       
   638 if ( isset( $_GET['recovered'] ) ) {
       
   639 	$i = (int) $_GET['recovered'];
       
   640 	echo '<div class="updated"><p>' . sprintf(__('%1$s comments recovered.'), $i) . "</p></div>";
       
   641 }
       
   642 
       
   643 if (isset( $_GET['deleted'] ) )
       
   644 	echo '<div class="updated"><p>' . __('All spam deleted.') . '</p></div>';
       
   645 
       
   646 if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) )
       
   647 	$link = 'edit-comments.php';
       
   648 else
       
   649 	$link = 'edit.php';
       
   650 ?>
       
   651 <style type="text/css">
       
   652 .akismet-tabs {
       
   653 	list-style: none;
       
   654 	margin: 0;
       
   655 	padding: 0;
       
   656 	clear: both;
       
   657 	border-bottom: 1px solid #ccc;
       
   658 	height: 31px;
       
   659 	margin-bottom: 20px;
       
   660 	background: #ddd;
       
   661 	border-top: 1px solid #bdbdbd;
       
   662 }
       
   663 .akismet-tabs li {
       
   664 	float: left;
       
   665 	margin: 5px 0 0 20px;
       
   666 }
       
   667 .akismet-tabs a {
       
   668 	display: block;
       
   669 	padding: 4px .5em 3px;
       
   670 	border-bottom: none;
       
   671 	color: #036;
       
   672 }
       
   673 .akismet-tabs .active a {
       
   674 	background: #fff;
       
   675 	border: 1px solid #ccc;
       
   676 	border-bottom: none;
       
   677 	color: #000;
       
   678 	font-weight: bold;
       
   679 	padding-bottom: 4px;
       
   680 }
       
   681 #akismetsearch {
       
   682 	float: right;
       
   683 	margin-top: -.5em;
       
   684 }
       
   685 
       
   686 #akismetsearch p {
       
   687 	margin: 0;
       
   688 	padding: 0;
       
   689 }
       
   690 </style>
       
   691 <div class="wrap">
       
   692 <h2><?php _e('Caught Spam') ?></h2>
       
   693 <?php
       
   694 $count = get_option( 'akismet_spam_count' );
       
   695 if ( $count ) {
       
   696 ?>
       
   697 <p><?php printf(__('Akismet has caught <strong>%1$s spam</strong> for you since you first installed it.'), number_format_i18n($count) ); ?></p>
       
   698 <?php
       
   699 }
       
   700 
       
   701 $spam_count = akismet_spam_count();
       
   702 
       
   703 if ( 0 == $spam_count ) {
       
   704 	echo '<p>'.__('You have no spam currently in the queue. Must be your lucky day. :)').'</p>';
       
   705 	echo '</div>';
       
   706 } else {
       
   707 	echo '<p>'.__('You can delete all of the spam from your database with a single click. This operation cannot be undone, so you may wish to check to ensure that no legitimate comments got through first. Spam is automatically deleted after 15 days, so don&#8217;t sweat it.').'</p>';
       
   708 ?>
       
   709 <?php if ( !isset( $_POST['s'] ) ) { ?>
       
   710 <form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
       
   711 <?php akismet_nonce_field($akismet_nonce) ?>
       
   712 <input type="hidden" name="action" value="delete" />
       
   713 <?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" class="button delete" name="Submit" value="<?php _e('Delete all'); ?>" />
       
   714 <input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" />
       
   715 </form>
       
   716 <?php } ?>
       
   717 </div>
       
   718 <div class="wrap">
       
   719 <?php if ( isset( $_POST['s'] ) ) { ?>
       
   720 <h2><?php _e('Search'); ?></h2>
       
   721 <?php } else { ?>
       
   722 <?php echo '<p>'.__('These are the latest comments identified as spam by Akismet. If you see any mistakes, simply mark the comment as "not spam" and Akismet will learn from the submission. If you wish to recover a comment from spam, simply select the comment, and click Not Spam. After 15 days we clean out the junk for you.').'</p>'; ?>
       
   723 <?php } ?>
       
   724 <?php
       
   725 if ( isset( $_POST['s'] ) ) {
       
   726 	$s = $wpdb->escape($_POST['s']);
       
   727 	$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments  WHERE
       
   728 		(comment_author LIKE '%$s%' OR
       
   729 		comment_author_email LIKE '%$s%' OR
       
   730 		comment_author_url LIKE ('%$s%') OR
       
   731 		comment_author_IP LIKE ('%$s%') OR
       
   732 		comment_content LIKE ('%$s%') ) AND
       
   733 		comment_approved = 'spam'
       
   734 		ORDER BY comment_date DESC");
       
   735 } else {
       
   736 	if ( isset( $_GET['apage'] ) )
       
   737 		$page = (int) $_GET['apage'];
       
   738 	else
       
   739 		$page = 1;
       
   740 
       
   741 	if ( $page < 2 )
       
   742 		$page = 1;
       
   743 
       
   744 	$current_type = false;
       
   745 	if ( isset( $_GET['ctype'] ) )
       
   746 		$current_type = preg_replace( '|[^a-z]|', '', $_GET['ctype'] );
       
   747 
       
   748 	$comments = akismet_spam_comments( $current_type, $page );
       
   749 	$total = akismet_spam_count( $current_type );
       
   750 	$totals = akismet_spam_totals();
       
   751 ?>
       
   752 <ul class="akismet-tabs">
       
   753 <li <?php if ( !isset( $_GET['ctype'] ) ) echo ' class="active"'; ?>><a href="edit-comments.php?page=akismet-admin"><?php _e('All'); ?></a></li>
       
   754 <?php
       
   755 foreach ( $totals as $type => $type_count ) {
       
   756 	if ( 'comment' == $type ) {
       
   757 		$type = 'comments';
       
   758 		$show = __('Comments');
       
   759 	} else {
       
   760 		$show = ucwords( $type );
       
   761 	}
       
   762 	$type_count = number_format_i18n( $type_count );
       
   763 	$extra = $current_type === $type ? ' class="active"' : '';
       
   764 	echo "<li $extra><a href='edit-comments.php?page=akismet-admin&amp;ctype=$type'>$show ($type_count)</a></li>";
       
   765 }
       
   766 do_action( 'akismet_tabs' ); // so plugins can add more tabs easily
       
   767 ?>
       
   768 </ul>
       
   769 <?php
       
   770 }
       
   771 
       
   772 if ($comments) {
       
   773 ?>
       
   774 <form method="post" action="<?php echo attribute_escape("$link?page=akismet-admin"); ?>" id="akismetsearch">
       
   775 <p>  <input type="text" name="s" value="<?php if (isset($_POST['s'])) echo attribute_escape($_POST['s']); ?>" size="17" />
       
   776   <input type="submit" class="button" name="submit" value="<?php echo attribute_escape(__('Search Spam &raquo;')) ?>"  />  </p>
       
   777 </form>
       
   778 <?php if ( $total > 50 ) {
       
   779 $total_pages = ceil( $total / 50 );
       
   780 $r = '';
       
   781 if ( 1 < $page ) {
       
   782 	$args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
       
   783 	$r .=  '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
       
   784 }
       
   785 if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
       
   786 	for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
       
   787 		if ( $page == $page_num ) :
       
   788 			$r .=  "<strong>$page_num</strong>\n";
       
   789 		else :
       
   790 			$p = false;
       
   791 			if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
       
   792 				$args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
       
   793 				$r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
       
   794 				$in = true;
       
   795 			elseif ( $in == true ) :
       
   796 				$r .= "...\n";
       
   797 				$in = false;
       
   798 			endif;
       
   799 		endif;
       
   800 	endfor;
       
   801 }
       
   802 if ( ( $page ) * 50 < $total || -1 == $total ) {
       
   803 	$args['apage'] = $page + 1;
       
   804 	$r .=  '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
       
   805 }
       
   806 echo "<p>$r</p>";
       
   807 ?>
       
   808 
       
   809 <?php } ?>
       
   810 <form style="clear: both;" method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
       
   811 <?php akismet_nonce_field($akismet_nonce) ?>
       
   812 <input type="hidden" name="action" value="recover" />
       
   813 <ul id="spam-list" class="commentlist" style="list-style: none; margin: 0; padding: 0;">
       
   814 <?php
       
   815 $i = 0;
       
   816 foreach($comments as $comment) {
       
   817 	$i++;
       
   818 	$comment_date = mysql2date(get_option("date_format") . " @ " . get_option("time_format"), $comment->comment_date);
       
   819 	$post = get_post($comment->comment_post_ID);
       
   820 	$post_title = $post->post_title;
       
   821 	if ($i % 2) $class = 'class="alternate"';
       
   822 	else $class = '';
       
   823 	echo "\n\t<li id='comment-$comment->comment_ID' $class>";
       
   824 	?>
       
   825 
       
   826 <p><strong><?php comment_author() ?></strong> <?php if ($comment->comment_author_email) { ?>| <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <?php comment_author_url_link() ?> <?php } ?>| <?php _e('IP:') ?> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
       
   827 
       
   828 <?php comment_text() ?>
       
   829 
       
   830 <p><label for="spam-<?php echo $comment->comment_ID; ?>">
       
   831 <input type="checkbox" id="spam-<?php echo $comment->comment_ID; ?>" name="not_spam[]" value="<?php echo $comment->comment_ID; ?>" />
       
   832 <?php _e('Not Spam') ?></label> &#8212; <?php comment_date('M j, g:i A');  ?> &#8212; [
       
   833 <?php
       
   834 $post = get_post($comment->comment_post_ID);
       
   835 $post_title = wp_specialchars( $post->post_title, 'double' );
       
   836 $post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
       
   837 ?>
       
   838  <a href="<?php echo get_permalink($comment->comment_post_ID); ?>" title="<?php echo $post_title; ?>"><?php _e('View Post') ?></a> ] </p>
       
   839 
       
   840 
       
   841 <?php
       
   842 }
       
   843 ?>
       
   844 </ul>
       
   845 <?php if ( $total > 50 ) {
       
   846 $total_pages = ceil( $total / 50 );
       
   847 $r = '';
       
   848 if ( 1 < $page ) {
       
   849 	$args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
       
   850 	$r .=  '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
       
   851 }
       
   852 if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
       
   853 	for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
       
   854 		if ( $page == $page_num ) :
       
   855 			$r .=  "<strong>$page_num</strong>\n";
       
   856 		else :
       
   857 			$p = false;
       
   858 			if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
       
   859 				$args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
       
   860 				$r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
       
   861 				$in = true;
       
   862 			elseif ( $in == true ) :
       
   863 				$r .= "...\n";
       
   864 				$in = false;
       
   865 			endif;
       
   866 		endif;
       
   867 	endfor;
       
   868 }
       
   869 if ( ( $page ) * 50 < $total || -1 == $total ) {
       
   870 	$args['apage'] = $page + 1;
       
   871 	$r .=  '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
       
   872 }
       
   873 echo "<p>$r</p>";
       
   874 }
       
   875 ?>
       
   876 <p class="submit">
       
   877 <input type="submit" name="submit" value="<?php echo attribute_escape(__('De-spam marked comments &raquo;')); ?>" />
       
   878 </p>
       
   879 <p><?php _e('Comments you de-spam will be submitted to Akismet as mistakes so it can learn and get better.'); ?></p>
       
   880 </form>
       
   881 <?php
       
   882 } else {
       
   883 ?>
       
   884 <p><?php _e('No results found.'); ?></p>
       
   885 <?php } ?>
       
   886 
       
   887 <?php if ( !isset( $_POST['s'] ) ) { ?>
       
   888 <form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
       
   889 <?php akismet_nonce_field($akismet_nonce) ?>
       
   890 <p><input type="hidden" name="action" value="delete" />
       
   891 <?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" name="Submit" class="button" value="<?php echo attribute_escape(__('Delete all')); ?>" />
       
   892 <input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" /></p>
       
   893 </form>
       
   894 <?php } ?>
       
   895 </div>
       
   896 <?php
       
   897 	}
       
   898 }
       
   899 
       
   900 add_action('admin_menu', 'akismet_manage_page');
       
   901 
       
   902 // WP < 2.5
       
   903 function akismet_stats() {
       
   904 	if ( !function_exists('did_action') || did_action( 'rightnow_end' ) ) // We already displayed this info in the "Right Now" section
       
   905 		return;
       
   906 	if ( !$count = get_option('akismet_spam_count') )
       
   907 		return;
       
   908 	$path = plugin_basename(__FILE__);
       
   909 	echo '<h3>'.__('Spam').'</h3>';
       
   910 	global $submenu;
       
   911 	if ( isset( $submenu['edit-comments.php'] ) )
       
   912 		$link = 'edit-comments.php';
       
   913 	else
       
   914 		$link = 'edit.php';
       
   915 	echo '<p>'.sprintf(__('<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.'), 'http://akismet.com/', clean_url("$link?page=akismet-admin"), number_format_i18n($count) ).'</p>';
       
   916 }
       
   917 
       
   918 add_action('activity_box_end', 'akismet_stats');
       
   919 
       
   920 // WP 2.5+
       
   921 function akismet_rightnow() {
       
   922 	global $submenu, $wp_db_version;
       
   923 
       
   924 	if ( 8645 < $wp_db_version  ) // 2.7
       
   925 		$link = 'edit-comments.php?comment_status=spam';
       
   926 	elseif ( isset( $submenu['edit-comments.php'] ) )
       
   927 		$link = 'edit-comments.php?page=akismet-admin';
       
   928 	else
       
   929 		$link = 'edit.php?page=akismet-admin';
       
   930 
       
   931 	if ( $count = get_option('akismet_spam_count') ) {
       
   932 		$intro = sprintf( __ngettext(
       
   933 			'<a href="%1$s">Akismet</a> has protected your site from %2$s spam comment already,',
       
   934 			'<a href="%1$s">Akismet</a> has protected your site from %2$s spam comments already,',
       
   935 			$count
       
   936 		), 'http://akismet.com/', number_format_i18n( $count ) );
       
   937 	} else {
       
   938 		$intro = sprintf( __('<a href="%1$s">Akismet</a> blocks spam from getting to your blog,'), 'http://akismet.com/' );
       
   939 	}
       
   940 
       
   941 	if ( $queue_count = akismet_spam_count() ) {
       
   942 		$queue_text = sprintf( __ngettext(
       
   943 			'and there\'s <a href="%2$s">%1$s comment</a> in your spam queue right now.',
       
   944 			'and there are <a href="%2$s">%1$s comments</a> in your spam queue right now.',
       
   945 			$queue_count
       
   946 		), number_format_i18n( $queue_count ), clean_url($link) );
       
   947 	} else {
       
   948 		$queue_text = sprintf( __( "but there's nothing in your <a href='%1\$s'>spam queue</a> at the moment." ), clean_url($link) );
       
   949 	}
       
   950 
       
   951 	$text = sprintf( _c( '%1$s %2$s|akismet_rightnow' ), $intro, $queue_text );
       
   952 
       
   953 	echo "<p class='akismet-right-now'>$text</p>\n";
       
   954 }
       
   955 	
       
   956 add_action('rightnow_end', 'akismet_rightnow');
       
   957 
       
   958 // For WP <= 2.3.x
       
   959 if ( 'moderation.php' == $pagenow ) {
       
   960 	function akismet_recheck_button( $page ) {
       
   961 		global $submenu;
       
   962 		if ( isset( $submenu['edit-comments.php'] ) )
       
   963 			$link = 'edit-comments.php';
       
   964 		else
       
   965 			$link = 'edit.php';
       
   966 		$button = "<a href='$link?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true' style='display: block; width: 100px; position: absolute; right: 7%; padding: 5px; font-size: 14px; text-decoration: underline; background: #fff; border: 1px solid #ccc;'>" . __('Recheck Queue for Spam') . "</a>";
       
   967 		$page = str_replace( '<div class="wrap">', '<div class="wrap">' . $button, $page );
       
   968 		return $page;
       
   969 	}
       
   970 
       
   971 	if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) )
       
   972 		ob_start( 'akismet_recheck_button' );
       
   973 }
       
   974 
       
   975 // For WP >= 2.5
       
   976 function akismet_check_for_spam_button($comment_status) {
       
   977 	if ( 'approved' == $comment_status )
       
   978 		return;
       
   979 	if ( function_exists('plugins_url') )
       
   980 		$link = 'admin.php?action=akismet_recheck_queue';
       
   981 	else
       
   982 		$link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
       
   983 	echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
       
   984 }
       
   985 add_action('manage_comments_nav', 'akismet_check_for_spam_button');
       
   986 
       
   987 function akismet_recheck_queue() {
       
   988 	global $wpdb, $akismet_api_host, $akismet_api_port;
       
   989 
       
   990 	if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
       
   991 		return;
       
   992 
       
   993 	$moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
       
   994 	foreach ( (array) $moderation as $c ) {
       
   995 		$c['user_ip']    = $c['comment_author_IP'];
       
   996 		$c['user_agent'] = $c['comment_agent'];
       
   997 		$c['referrer']   = '';
       
   998 		$c['blog']       = get_option('home');
       
   999 		$c['blog_lang']  = get_locale();
       
  1000 		$c['blog_charset'] = get_option('blog_charset');
       
  1001 		$c['permalink']  = get_permalink($c['comment_post_ID']);
       
  1002 		$id = (int) $c['comment_ID'];
       
  1003 
       
  1004 		$query_string = '';
       
  1005 		foreach ( $c as $key => $data )
       
  1006 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
       
  1007 
       
  1008 		$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
       
  1009 		if ( 'true' == $response[1] ) {
       
  1010 			$wpdb->query( "UPDATE $wpdb->comments SET comment_approved = 'spam' WHERE comment_ID = $id" );
       
  1011 		}
       
  1012 	}
       
  1013 	wp_redirect( $_SERVER['HTTP_REFERER'] );
       
  1014 	exit;
       
  1015 }
       
  1016 
       
  1017 add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
       
  1018 
       
  1019 function akismet_check_db_comment( $id ) {
       
  1020 	global $wpdb, $akismet_api_host, $akismet_api_port;
       
  1021 
       
  1022 	$id = (int) $id;
       
  1023 	$c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
       
  1024 	if ( !$c )
       
  1025 		return;
       
  1026 
       
  1027 	$c['user_ip']    = $c['comment_author_IP'];
       
  1028 	$c['user_agent'] = $c['comment_agent'];
       
  1029 	$c['referrer']   = '';
       
  1030 	$c['blog']       = get_option('home');
       
  1031 	$c['blog_lang']  = get_locale();
       
  1032 	$c['blog_charset'] = get_option('blog_charset');
       
  1033 	$c['permalink']  = get_permalink($c['comment_post_ID']);
       
  1034 	$id = $c['comment_ID'];
       
  1035 
       
  1036 	$query_string = '';
       
  1037 	foreach ( $c as $key => $data )
       
  1038 	$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
       
  1039 
       
  1040 	$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
       
  1041 	return $response[1];
       
  1042 }
       
  1043 
       
  1044 // This option causes tons of FPs, was removed in 2.1
       
  1045 function akismet_kill_proxy_check( $option ) { return 0; }
       
  1046 add_filter('option_open_proxy_check', 'akismet_kill_proxy_check');
       
  1047 
       
  1048 // Widget stuff
       
  1049 function widget_akismet_register() {
       
  1050 	if ( function_exists('register_sidebar_widget') ) :
       
  1051 	function widget_akismet($args) {
       
  1052 		extract($args);
       
  1053 		$options = get_option('widget_akismet');
       
  1054 		$count = number_format_i18n(get_option('akismet_spam_count'));
       
  1055 		?>
       
  1056 			<?php echo $before_widget; ?>
       
  1057 				<?php echo $before_title . $options['title'] . $after_title; ?>
       
  1058 				<div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><?php printf( __( '%1$s %2$sspam comments%3$s %4$sblocked by%5$s<br />%6$sAkismet%7$s' ), '<div id="akismet1"><span id="akismetcount">' . $count . '</span>', '<span id="akismetsc">', '</span></div>', '<div id="akismet2"><span id="akismetbb">', '</span>', '<span id="akismeta">', '</span></div>' ); ?></a></div></div>
       
  1059 			<?php echo $after_widget; ?>
       
  1060 	<?php
       
  1061 	}
       
  1062 
       
  1063 	function widget_akismet_style() {
       
  1064 		?>
       
  1065 <style type="text/css">
       
  1066 #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
       
  1067 #aka:hover{border:none;text-decoration:none}
       
  1068 #aka:hover #akismet1{display:none}
       
  1069 #aka:hover #akismet2,#akismet1{display:block}
       
  1070 #akismet2{display:none;padding-top:2px}
       
  1071 #akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
       
  1072 #akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
       
  1073 #akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'); ?>/wp-content/plugins/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
       
  1074 </style>
       
  1075 		<?php
       
  1076 	}
       
  1077 
       
  1078 	function widget_akismet_control() {
       
  1079 		$options = $newoptions = get_option('widget_akismet');
       
  1080 		if ( $_POST["akismet-submit"] ) {
       
  1081 			$newoptions['title'] = strip_tags(stripslashes($_POST["akismet-title"]));
       
  1082 			if ( empty($newoptions['title']) ) $newoptions['title'] = 'Spam Blocked';
       
  1083 		}
       
  1084 		if ( $options != $newoptions ) {
       
  1085 			$options = $newoptions;
       
  1086 			update_option('widget_akismet', $options);
       
  1087 		}
       
  1088 		$title = htmlspecialchars($options['title'], ENT_QUOTES);
       
  1089 	?>
       
  1090 				<p><label for="akismet-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="akismet-title" name="akismet-title" type="text" value="<?php echo $title; ?>" /></label></p>
       
  1091 				<input type="hidden" id="akismet-submit" name="akismet-submit" value="1" />
       
  1092 	<?php
       
  1093 	}
       
  1094 
       
  1095 	register_sidebar_widget('Akismet', 'widget_akismet', null, 'akismet');
       
  1096 	register_widget_control('Akismet', 'widget_akismet_control', null, 75, 'akismet');
       
  1097 	if ( is_active_widget('widget_akismet') )
       
  1098 		add_action('wp_head', 'widget_akismet_style');
       
  1099 	endif;
       
  1100 }
       
  1101 
       
  1102 add_action('init', 'widget_akismet_register');
       
  1103 
       
  1104 // Counter for non-widget users
       
  1105 function akismet_counter() {
       
  1106 ?>
       
  1107 <style type="text/css">
       
  1108 #akismetwrap #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
       
  1109 #aka:hover{border:none;text-decoration:none}
       
  1110 #aka:hover #akismet1{display:none}
       
  1111 #aka:hover #akismet2,#akismet1{display:block}
       
  1112 #akismet2{display:none;padding-top:2px}
       
  1113 #akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
       
  1114 #akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
       
  1115 #akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'); ?>/wp-content/plugins/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
       
  1116 </style>
       
  1117 <?php
       
  1118 $count = number_format_i18n(get_option('akismet_spam_count'));
       
  1119 ?>
       
  1120 <div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><div id="akismet1"><span id="akismetcount"><?php echo $count; ?></span> <span id="akismetsc"><?php _e('spam comments') ?></span></div> <div id="akismet2"><span id="akismetbb"><?php _e('blocked by') ?></span><br /><span id="akismeta">Akismet</span></div></a></div></div>
       
  1121 <?php
       
  1122 }
       
  1123 
       
  1124 ?>