]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-content/plugins/akismet/akismet.php
Wordpress 2.8.5
[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 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         $servers = akismet_get_server_connectivity();
319         return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) );
320 }
321
322 function akismet_admin_warnings() {
323         global $wpcom_api_key;
324         if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
325                 function akismet_warning() {
326                         echo "
327                         <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>
328                         ";
329                 }
330                 add_action('admin_notices', 'akismet_warning');
331                 return;
332         } elseif ( get_option('akismet_connectivity_time') && empty($_POST) && is_admin() && !akismet_server_connectivity_ok() ) {
333                 function akismet_warning() {
334                         echo "
335                         <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>
336                         ";
337                 }
338                 add_action('admin_notices', 'akismet_warning');
339                 return;
340         }
341 }
342
343 function akismet_get_host($host) {
344         // if all servers are accessible, just return the host name.
345         // if not, return an IP that was known to be accessible at the last check.
346         if ( akismet_server_connectivity_ok() ) {
347                 return $host;
348         } else {
349                 $ips = akismet_get_server_connectivity();
350                 // a firewall may be blocking access to some Akismet IPs
351                 if ( count($ips) > 0 && count(array_filter($ips)) < count($ips) ) {
352                         // use DNS to get current IPs, but exclude any known to be unreachable
353                         $dns = (array)gethostbynamel( rtrim($host, '.') . '.' );
354                         $dns = array_filter($dns);
355                         foreach ( $dns as $ip ) {
356                                 if ( array_key_exists( $ip, $ips ) && empty( $ips[$ip] ) )
357                                         unset($dns[$ip]);
358                         }
359                         // return a random IP from those available
360                         if ( count($dns) )
361                                 return $dns[ array_rand($dns) ];
362                         
363                 }
364         }
365         // if all else fails try the host name
366         return $host;
367 }
368
369 // Returns array with headers in $response[0] and body in $response[1]
370 function akismet_http_post($request, $host, $path, $port = 80, $ip=null) {
371         global $wp_version;
372         
373         $akismet_version = constant('AKISMET_VERSION');
374
375         $http_request  = "POST $path HTTP/1.0\r\n";
376         $http_request .= "Host: $host\r\n";
377         $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=" . get_option('blog_charset') . "\r\n";
378         $http_request .= "Content-Length: " . strlen($request) . "\r\n";
379         $http_request .= "User-Agent: WordPress/$wp_version | Akismet/$akismet_version\r\n";
380         $http_request .= "\r\n";
381         $http_request .= $request;
382         
383         $http_host = $host;
384         // use a specific IP if provided - needed by akismet_check_server_connectivity()
385         if ( $ip && long2ip(ip2long($ip)) ) {
386                 $http_host = $ip;
387         } else {
388                 $http_host = akismet_get_host($host);
389         }
390
391         $response = '';
392         if( false != ( $fs = @fsockopen($http_host, $port, $errno, $errstr, 10) ) ) {
393                 fwrite($fs, $http_request);
394
395                 while ( !feof($fs) )
396                         $response .= fgets($fs, 1160); // One TCP-IP packet
397                 fclose($fs);
398                 $response = explode("\r\n\r\n", $response, 2);
399         }
400         return $response;
401 }
402
403 // filter handler used to return a spam result to pre_comment_approved
404 function akismet_result_spam( $approved ) {
405         // bump the counter here instead of when the filter is added to reduce the possibility of overcounting
406         update_option( 'akismet_spam_count', get_option('akismet_spam_count') + 1 );
407         return 'spam';
408 }
409
410 function akismet_auto_check_comment( $comment ) {
411         global $akismet_api_host, $akismet_api_port;
412
413         $comment['user_ip']    = preg_replace( '/[^0-9., ]/', '', $_SERVER['REMOTE_ADDR'] );
414         $comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
415         $comment['referrer']   = $_SERVER['HTTP_REFERER'];
416         $comment['blog']       = get_option('home');
417         $comment['blog_lang']  = get_locale();
418         $comment['blog_charset'] = get_option('blog_charset');
419         $comment['permalink']  = get_permalink($comment['comment_post_ID']);
420
421         $ignore = array( 'HTTP_COOKIE' );
422
423         foreach ( $_SERVER as $key => $value )
424                 if ( !in_array( $key, $ignore ) && is_string($value) )
425                         $comment["$key"] = $value;
426
427         $query_string = '';
428         foreach ( $comment as $key => $data )
429                 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
430
431         $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
432         if ( 'true' == $response[1] ) {
433                 // akismet_spam_count will be incremented later by akismet_result_spam()
434                 add_filter('pre_comment_approved', 'akismet_result_spam');
435
436                 do_action( 'akismet_spam_caught' );
437
438                 $post = get_post( $comment['comment_post_ID'] );
439                 $last_updated = strtotime( $post->post_modified_gmt );
440                 $diff = time() - $last_updated;
441                 $diff = $diff / 86400;
442                 
443                 if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' ) {
444                         // akismet_result_spam() won't be called so bump the counter here
445                         update_option( 'akismet_spam_count', get_option('akismet_spam_count') + 1 );
446                         die;
447                 }
448         }
449         akismet_delete_old();
450         return $comment;
451 }
452
453 function akismet_delete_old() {
454         global $wpdb;
455         $now_gmt = current_time('mysql', 1);
456         $wpdb->query("DELETE FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'");
457         $n = mt_rand(1, 5000);
458         if ( $n == 11 ) // lucky number
459                 $wpdb->query("OPTIMIZE TABLE $wpdb->comments");
460 }
461
462 function akismet_submit_nonspam_comment ( $comment_id ) {
463         global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
464         $comment_id = (int) $comment_id;
465         
466         $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
467         if ( !$comment ) // it was deleted
468                 return;
469         $comment->blog = get_option('home');
470         $comment->blog_lang = get_locale();
471         $comment->blog_charset = get_option('blog_charset');
472         $comment->permalink = get_permalink($comment->comment_post_ID);
473         if ( is_object($current_user) ) {
474             $comment->reporter = $current_user->user_login;
475         }
476         if ( is_object($current_site) ) {
477                 $comment->site_domain = $current_site->domain;
478         }
479         $query_string = '';
480         foreach ( $comment as $key => $data )
481                 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
482
483         $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
484 }
485
486 function akismet_submit_spam_comment ( $comment_id ) {
487         global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
488         $comment_id = (int) $comment_id;
489
490         $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
491         if ( !$comment ) // it was deleted
492                 return;
493         if ( 'spam' != $comment->comment_approved )
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         $query_string = '';
506         foreach ( $comment as $key => $data )
507                 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
508
509         $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
510 }
511
512 add_action('wp_set_comment_status', 'akismet_submit_spam_comment');
513 add_action('edit_comment', 'akismet_submit_spam_comment');
514 add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
515
516 function akismet_spamtoham( $comment ) { akismet_submit_nonspam_comment( $comment->comment_ID ); }
517 add_filter( 'comment_spam_to_approved', 'akismet_spamtoham' );
518
519 // Total spam in queue
520 // get_option( 'akismet_spam_count' ) is the total caught ever
521 function akismet_spam_count( $type = false ) {
522         global $wpdb;
523
524         if ( !$type ) { // total
525                 $count = wp_cache_get( 'akismet_spam_count', 'widget' );
526                 if ( false === $count ) {
527                         if ( function_exists('wp_count_comments') ) {
528                                 $count = wp_count_comments();
529                                 $count = $count->spam;
530                         } else {
531                                 $count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
532                         }
533                         wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
534                 }
535                 return $count;
536         } elseif ( 'comments' == $type || 'comment' == $type ) { // comments
537                 $type = '';
538         } else { // pingback, trackback, ...
539                 $type  = $wpdb->escape( $type );
540         }
541
542         return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
543 }
544
545 function akismet_spam_comments( $type = false, $page = 1, $per_page = 50 ) {
546         global $wpdb;
547
548         $page = (int) $page;
549         if ( $page < 2 )
550                 $page = 1;
551
552         $per_page = (int) $per_page;
553         if ( $per_page < 1 )
554                 $per_page = 50;
555
556         $start = ( $page - 1 ) * $per_page;
557         $end = $start + $per_page;
558
559         if ( $type ) {
560                 if ( 'comments' == $type || 'comment' == $type )
561                         $type = '';
562                 else
563                         $type = $wpdb->escape( $type );
564                 return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type' ORDER BY comment_date DESC LIMIT $start, $end");
565         }
566
567         // All
568         return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end");
569 }
570
571 // Totals for each comment type
572 // returns array( type => count, ... )
573 function akismet_spam_totals() {
574         global $wpdb;
575         $totals = $wpdb->get_results( "SELECT comment_type, COUNT(*) AS cc FROM $wpdb->comments WHERE comment_approved = 'spam' GROUP BY comment_type" );
576         $return = array();
577         foreach ( $totals as $total )
578                 $return[$total->comment_type ? $total->comment_type : 'comment'] = $total->cc;
579         return $return;
580 }
581
582 function akismet_manage_page() {
583         global $wpdb, $submenu, $wp_db_version;
584
585         // WP 2.7 has its own spam management page
586         if ( 8645 <= $wp_db_version )
587                 return;
588
589         $count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count());
590         if ( isset( $submenu['edit-comments.php'] ) )
591                 add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' );
592         elseif ( function_exists('add_management_page') )
593                 add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught');
594 }
595
596 function akismet_caught() {
597         global $wpdb, $comment, $akismet_caught, $akismet_nonce;
598
599         akismet_recheck_queue();
600         if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) {
601                 check_admin_referer( $akismet_nonce );
602                 if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
603                         die(__('You do not have sufficient permission to moderate comments.'));
604
605                 $i = 0;
606                 foreach ($_POST['not_spam'] as $comment):
607                         $comment = (int) $comment;
608                         if ( function_exists('wp_set_comment_status') )
609                                 wp_set_comment_status($comment, 'approve');
610                         else
611                                 $wpdb->query("UPDATE $wpdb->comments SET comment_approved = '1' WHERE comment_ID = '$comment'");
612                         akismet_submit_nonspam_comment($comment);
613                         ++$i;
614                 endforeach;
615                 $to = add_query_arg( 'recovered', $i, $_SERVER['HTTP_REFERER'] );
616                 wp_redirect( $to );
617                 exit;
618         }
619         if ('delete' == $_POST['action']) {
620                 check_admin_referer( $akismet_nonce );
621                 if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
622                         die(__('You do not have sufficient permission to moderate comments.'));
623
624                 $delete_time = $wpdb->escape( $_POST['display_time'] );
625                 $nuked = $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" );
626                 wp_cache_delete( 'akismet_spam_count', 'widget' );
627                 $to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] );
628                 wp_redirect( $to );
629                 exit;
630         }
631
632 if ( isset( $_GET['recovered'] ) ) {
633         $i = (int) $_GET['recovered'];
634         echo '<div class="updated"><p>' . sprintf(__('%1$s comments recovered.'), $i) . "</p></div>";
635 }
636
637 if (isset( $_GET['deleted'] ) )
638         echo '<div class="updated"><p>' . __('All spam deleted.') . '</p></div>';
639
640 if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) )
641         $link = 'edit-comments.php';
642 else
643         $link = 'edit.php';
644 ?>
645 <style type="text/css">
646 .akismet-tabs {
647         list-style: none;
648         margin: 0;
649         padding: 0;
650         clear: both;
651         border-bottom: 1px solid #ccc;
652         height: 31px;
653         margin-bottom: 20px;
654         background: #ddd;
655         border-top: 1px solid #bdbdbd;
656 }
657 .akismet-tabs li {
658         float: left;
659         margin: 5px 0 0 20px;
660 }
661 .akismet-tabs a {
662         display: block;
663         padding: 4px .5em 3px;
664         border-bottom: none;
665         color: #036;
666 }
667 .akismet-tabs .active a {
668         background: #fff;
669         border: 1px solid #ccc;
670         border-bottom: none;
671         color: #000;
672         font-weight: bold;
673         padding-bottom: 4px;
674 }
675 #akismetsearch {
676         float: right;
677         margin-top: -.5em;
678 }
679
680 #akismetsearch p {
681         margin: 0;
682         padding: 0;
683 }
684 </style>
685 <div class="wrap">
686 <h2><?php _e('Caught Spam') ?></h2>
687 <?php
688 $count = get_option( 'akismet_spam_count' );
689 if ( $count ) {
690 ?>
691 <p><?php printf(__('Akismet has caught <strong>%1$s spam</strong> for you since you first installed it.'), number_format_i18n($count) ); ?></p>
692 <?php
693 }
694
695 $spam_count = akismet_spam_count();
696
697 if ( 0 == $spam_count ) {
698         echo '<p>'.__('You have no spam currently in the queue. Must be your lucky day. :)').'</p>';
699         echo '</div>';
700 } else {
701         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>';
702 ?>
703 <?php if ( !isset( $_POST['s'] ) ) { ?>
704 <form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
705 <?php akismet_nonce_field($akismet_nonce) ?>
706 <input type="hidden" name="action" value="delete" />
707 <?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'); ?>" />
708 <input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" />
709 </form>
710 <?php } ?>
711 </div>
712 <div class="wrap">
713 <?php if ( isset( $_POST['s'] ) ) { ?>
714 <h2><?php _e('Search'); ?></h2>
715 <?php } else { ?>
716 <?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>'; ?>
717 <?php } ?>
718 <?php
719 if ( isset( $_POST['s'] ) ) {
720         $s = $wpdb->escape($_POST['s']);
721         $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments  WHERE
722                 (comment_author LIKE '%$s%' OR
723                 comment_author_email LIKE '%$s%' OR
724                 comment_author_url LIKE ('%$s%') OR
725                 comment_author_IP LIKE ('%$s%') OR
726                 comment_content LIKE ('%$s%') ) AND
727                 comment_approved = 'spam'
728                 ORDER BY comment_date DESC");
729 } else {
730         if ( isset( $_GET['apage'] ) )
731                 $page = (int) $_GET['apage'];
732         else
733                 $page = 1;
734
735         if ( $page < 2 )
736                 $page = 1;
737
738         $current_type = false;
739         if ( isset( $_GET['ctype'] ) )
740                 $current_type = preg_replace( '|[^a-z]|', '', $_GET['ctype'] );
741
742         $comments = akismet_spam_comments( $current_type, $page );
743         $total = akismet_spam_count( $current_type );
744         $totals = akismet_spam_totals();
745 ?>
746 <ul class="akismet-tabs">
747 <li <?php if ( !isset( $_GET['ctype'] ) ) echo ' class="active"'; ?>><a href="edit-comments.php?page=akismet-admin"><?php _e('All'); ?></a></li>
748 <?php
749 foreach ( $totals as $type => $type_count ) {
750         if ( 'comment' == $type ) {
751                 $type = 'comments';
752                 $show = __('Comments');
753         } else {
754                 $show = ucwords( $type );
755         }
756         $type_count = number_format_i18n( $type_count );
757         $extra = $current_type === $type ? ' class="active"' : '';
758         echo "<li $extra><a href='edit-comments.php?page=akismet-admin&amp;ctype=$type'>$show ($type_count)</a></li>";
759 }
760 do_action( 'akismet_tabs' ); // so plugins can add more tabs easily
761 ?>
762 </ul>
763 <?php
764 }
765
766 if ($comments) {
767 ?>
768 <form method="post" action="<?php echo attribute_escape("$link?page=akismet-admin"); ?>" id="akismetsearch">
769 <p>  <input type="text" name="s" value="<?php if (isset($_POST['s'])) echo attribute_escape($_POST['s']); ?>" size="17" />
770   <input type="submit" class="button" name="submit" value="<?php echo attribute_escape(__('Search Spam &raquo;')) ?>"  />  </p>
771 </form>
772 <?php if ( $total > 50 ) {
773 $total_pages = ceil( $total / 50 );
774 $r = '';
775 if ( 1 < $page ) {
776         $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
777         $r .=  '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
778 }
779 if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
780         for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
781                 if ( $page == $page_num ) :
782                         $r .=  "<strong>$page_num</strong>\n";
783                 else :
784                         $p = false;
785                         if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
786                                 $args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
787                                 $r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
788                                 $in = true;
789                         elseif ( $in == true ) :
790                                 $r .= "...\n";
791                                 $in = false;
792                         endif;
793                 endif;
794         endfor;
795 }
796 if ( ( $page ) * 50 < $total || -1 == $total ) {
797         $args['apage'] = $page + 1;
798         $r .=  '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
799 }
800 echo "<p>$r</p>";
801 ?>
802
803 <?php } ?>
804 <form style="clear: both;" method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
805 <?php akismet_nonce_field($akismet_nonce) ?>
806 <input type="hidden" name="action" value="recover" />
807 <ul id="spam-list" class="commentlist" style="list-style: none; margin: 0; padding: 0;">
808 <?php
809 $i = 0;
810 foreach($comments as $comment) {
811         $i++;
812         $comment_date = mysql2date(get_option("date_format") . " @ " . get_option("time_format"), $comment->comment_date);
813         $post = get_post($comment->comment_post_ID);
814         $post_title = $post->post_title;
815         if ($i % 2) $class = 'class="alternate"';
816         else $class = '';
817         echo "\n\t<li id='comment-$comment->comment_ID' $class>";
818         ?>
819
820 <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>
821
822 <?php comment_text() ?>
823
824 <p><label for="spam-<?php echo $comment->comment_ID; ?>">
825 <input type="checkbox" id="spam-<?php echo $comment->comment_ID; ?>" name="not_spam[]" value="<?php echo $comment->comment_ID; ?>" />
826 <?php _e('Not Spam') ?></label> &#8212; <?php comment_date('M j, g:i A');  ?> &#8212; [
827 <?php
828 $post = get_post($comment->comment_post_ID);
829 $post_title = wp_specialchars( $post->post_title, 'double' );
830 $post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
831 ?>
832  <a href="<?php echo get_permalink($comment->comment_post_ID); ?>" title="<?php echo $post_title; ?>"><?php _e('View Post') ?></a> ] </p>
833
834
835 <?php
836 }
837 ?>
838 </ul>
839 <?php if ( $total > 50 ) {
840 $total_pages = ceil( $total / 50 );
841 $r = '';
842 if ( 1 < $page ) {
843         $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
844         $r .=  '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
845 }
846 if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
847         for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
848                 if ( $page == $page_num ) :
849                         $r .=  "<strong>$page_num</strong>\n";
850                 else :
851                         $p = false;
852                         if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
853                                 $args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
854                                 $r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
855                                 $in = true;
856                         elseif ( $in == true ) :
857                                 $r .= "...\n";
858                                 $in = false;
859                         endif;
860                 endif;
861         endfor;
862 }
863 if ( ( $page ) * 50 < $total || -1 == $total ) {
864         $args['apage'] = $page + 1;
865         $r .=  '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
866 }
867 echo "<p>$r</p>";
868 }
869 ?>
870 <p class="submit">
871 <input type="submit" name="submit" value="<?php echo attribute_escape(__('De-spam marked comments &raquo;')); ?>" />
872 </p>
873 <p><?php _e('Comments you de-spam will be submitted to Akismet as mistakes so it can learn and get better.'); ?></p>
874 </form>
875 <?php
876 } else {
877 ?>
878 <p><?php _e('No results found.'); ?></p>
879 <?php } ?>
880
881 <?php if ( !isset( $_POST['s'] ) ) { ?>
882 <form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
883 <?php akismet_nonce_field($akismet_nonce) ?>
884 <p><input type="hidden" name="action" value="delete" />
885 <?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')); ?>" />
886 <input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" /></p>
887 </form>
888 <?php } ?>
889 </div>
890 <?php
891         }
892 }
893
894 add_action('admin_menu', 'akismet_manage_page');
895
896 // WP < 2.5
897 function akismet_stats() {
898         if ( !function_exists('did_action') || did_action( 'rightnow_end' ) ) // We already displayed this info in the "Right Now" section
899                 return;
900         if ( !$count = get_option('akismet_spam_count') )
901                 return;
902         $path = plugin_basename(__FILE__);
903         echo '<h3>'.__('Spam').'</h3>';
904         global $submenu;
905         if ( isset( $submenu['edit-comments.php'] ) )
906                 $link = 'edit-comments.php';
907         else
908                 $link = 'edit.php';
909         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>';
910 }
911
912 add_action('activity_box_end', 'akismet_stats');
913
914 // WP 2.5+
915 function akismet_rightnow() {
916         global $submenu, $wp_db_version;
917
918         if ( 8645 < $wp_db_version  ) // 2.7
919                 $link = 'edit-comments.php?comment_status=spam';
920         elseif ( isset( $submenu['edit-comments.php'] ) )
921                 $link = 'edit-comments.php?page=akismet-admin';
922         else
923                 $link = 'edit.php?page=akismet-admin';
924
925         if ( $count = get_option('akismet_spam_count') ) {
926                 $intro = sprintf( __ngettext(
927                         '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comment already,',
928                         '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comments already,',
929                         $count
930                 ), 'http://akismet.com/', number_format_i18n( $count ) );
931         } else {
932                 $intro = sprintf( __('<a href="%1$s">Akismet</a> blocks spam from getting to your blog,'), 'http://akismet.com/' );
933         }
934
935         if ( $queue_count = akismet_spam_count() ) {
936                 $queue_text = sprintf( __ngettext(
937                         'and there\'s <a href="%2$s">%1$s comment</a> in your spam queue right now.',
938                         'and there are <a href="%2$s">%1$s comments</a> in your spam queue right now.',
939                         $queue_count
940                 ), number_format_i18n( $queue_count ), clean_url($link) );
941         } else {
942                 $queue_text = sprintf( __( "but there's nothing in your <a href='%1\$s'>spam queue</a> at the moment." ), clean_url($link) );
943         }
944
945         $text = sprintf( _c( '%1$s %2$s|akismet_rightnow' ), $intro, $queue_text );
946
947         echo "<p class='akismet-right-now'>$text</p>\n";
948 }
949         
950 add_action('rightnow_end', 'akismet_rightnow');
951
952 // For WP <= 2.3.x
953 if ( 'moderation.php' == $pagenow ) {
954         function akismet_recheck_button( $page ) {
955                 global $submenu;
956                 if ( isset( $submenu['edit-comments.php'] ) )
957                         $link = 'edit-comments.php';
958                 else
959                         $link = 'edit.php';
960                 $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>";
961                 $page = str_replace( '<div class="wrap">', '<div class="wrap">' . $button, $page );
962                 return $page;
963         }
964
965         if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) )
966                 ob_start( 'akismet_recheck_button' );
967 }
968
969 // For WP >= 2.5
970 function akismet_check_for_spam_button($comment_status) {
971         if ( 'approved' == $comment_status )
972                 return;
973         if ( function_exists('plugins_url') )
974                 $link = 'admin.php?action=akismet_recheck_queue';
975         else
976                 $link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
977         echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
978 }
979 add_action('manage_comments_nav', 'akismet_check_for_spam_button');
980
981 function akismet_recheck_queue() {
982         global $wpdb, $akismet_api_host, $akismet_api_port;
983
984         if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
985                 return;
986
987         $moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
988         foreach ( (array) $moderation as $c ) {
989                 $c['user_ip']    = $c['comment_author_IP'];
990                 $c['user_agent'] = $c['comment_agent'];
991                 $c['referrer']   = '';
992                 $c['blog']       = get_option('home');
993                 $c['blog_lang']  = get_locale();
994                 $c['blog_charset'] = get_option('blog_charset');
995                 $c['permalink']  = get_permalink($c['comment_post_ID']);
996                 $id = (int) $c['comment_ID'];
997
998                 $query_string = '';
999                 foreach ( $c as $key => $data )
1000                 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
1001
1002                 $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
1003                 if ( 'true' == $response[1] ) {
1004                         $wpdb->query( "UPDATE $wpdb->comments SET comment_approved = 'spam' WHERE comment_ID = $id" );
1005                 }
1006         }
1007         wp_redirect( $_SERVER['HTTP_REFERER'] );
1008         exit;
1009 }
1010
1011 add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
1012
1013 function akismet_check_db_comment( $id ) {
1014         global $wpdb, $akismet_api_host, $akismet_api_port;
1015
1016         $id = (int) $id;
1017         $c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
1018         if ( !$c )
1019                 return;
1020
1021         $c['user_ip']    = $c['comment_author_IP'];
1022         $c['user_agent'] = $c['comment_agent'];
1023         $c['referrer']   = '';
1024         $c['blog']       = get_option('home');
1025         $c['blog_lang']  = get_locale();
1026         $c['blog_charset'] = get_option('blog_charset');
1027         $c['permalink']  = get_permalink($c['comment_post_ID']);
1028         $id = $c['comment_ID'];
1029
1030         $query_string = '';
1031         foreach ( $c as $key => $data )
1032         $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
1033
1034         $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
1035         return $response[1];
1036 }
1037
1038 // This option causes tons of FPs, was removed in 2.1
1039 function akismet_kill_proxy_check( $option ) { return 0; }
1040 add_filter('option_open_proxy_check', 'akismet_kill_proxy_check');
1041
1042 // Widget stuff
1043 function widget_akismet_register() {
1044         if ( function_exists('register_sidebar_widget') ) :
1045         function widget_akismet($args) {
1046                 extract($args);
1047                 $options = get_option('widget_akismet');
1048                 $count = number_format_i18n(get_option('akismet_spam_count'));
1049                 ?>
1050                         <?php echo $before_widget; ?>
1051                                 <?php echo $before_title . $options['title'] . $after_title; ?>
1052                                 <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>
1053                         <?php echo $after_widget; ?>
1054         <?php
1055         }
1056
1057         function widget_akismet_style() {
1058                 ?>
1059 <style type="text/css">
1060 #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
1061 #aka:hover{border:none;text-decoration:none}
1062 #aka:hover #akismet1{display:none}
1063 #aka:hover #akismet2,#akismet1{display:block}
1064 #akismet2{display:none;padding-top:2px}
1065 #akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
1066 #akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
1067 #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}
1068 </style>
1069                 <?php
1070         }
1071
1072         function widget_akismet_control() {
1073                 $options = $newoptions = get_option('widget_akismet');
1074                 if ( $_POST["akismet-submit"] ) {
1075                         $newoptions['title'] = strip_tags(stripslashes($_POST["akismet-title"]));
1076                         if ( empty($newoptions['title']) ) $newoptions['title'] = 'Spam Blocked';
1077                 }
1078                 if ( $options != $newoptions ) {
1079                         $options = $newoptions;
1080                         update_option('widget_akismet', $options);
1081                 }
1082                 $title = htmlspecialchars($options['title'], ENT_QUOTES);
1083         ?>
1084                                 <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>
1085                                 <input type="hidden" id="akismet-submit" name="akismet-submit" value="1" />
1086         <?php
1087         }
1088
1089         register_sidebar_widget('Akismet', 'widget_akismet', null, 'akismet');
1090         register_widget_control('Akismet', 'widget_akismet_control', null, 75, 'akismet');
1091         if ( is_active_widget('widget_akismet') )
1092                 add_action('wp_head', 'widget_akismet_style');
1093         endif;
1094 }
1095
1096 add_action('init', 'widget_akismet_register');
1097
1098 // Counter for non-widget users
1099 function akismet_counter() {
1100 ?>
1101 <style type="text/css">
1102 #akismetwrap #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
1103 #aka:hover{border:none;text-decoration:none}
1104 #aka:hover #akismet1{display:none}
1105 #aka:hover #akismet2,#akismet1{display:block}
1106 #akismet2{display:none;padding-top:2px}
1107 #akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
1108 #akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
1109 #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}
1110 </style>
1111 <?php
1112 $count = number_format_i18n(get_option('akismet_spam_count'));
1113 ?>
1114 <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>
1115 <?php
1116 }
1117
1118 ?>