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