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