PluginProbe ʕ •ᴥ•ʔ
Akismet Anti-spam: Spam Protection / 2.4.0
Akismet Anti-spam: Spam Protection v2.4.0
5.7 3.0.4 3.0.5 3.1 3.1.1 3.1.10 3.1.11 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2 3.3 3.3.1 3.3.2 3.3.3 3.3.4 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1 4.1.1 4.1.10 4.1.11 4.1.12 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 5.0 5.0.1 5.0.2 5.1 5.2 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4 5.5 5.6 trunk 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.4.0 2.4.1 2.5.0 2.5.1 2.5.10 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 3.0.0 3.0.0-RC1 3.0.1 3.0.2 3.0.3
akismet / akismet.php
akismet Last commit date
akismet.gif 15 years ago akismet.php 15 years ago legacy.php 15 years ago readme.txt 15 years ago
akismet.php
890 lines
1 <?php
2 /**
3 * @package Akismet
4 */
5 /*
6 Plugin Name: Akismet
7 Plugin URI: http://akismet.com/
8 Description: Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need an <a href="http://akismet.com/get/">API key</a> to use it. You can review the spam it catches under "Comments." To show off your Akismet stats just put <code>&lt;?php akismet_counter(); ?&gt;</code> in your template. See also: <a href="http://wordpress.org/extend/plugins/stats/">WP Stats plugin</a>.
9 Version: 2.4.0
10 Author: Automattic
11 Author URI: http://automattic.com/wordpress-plugins/
12 License: GPLv2
13 */
14
15 /*
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; version 2 of the License.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30 define('AKISMET_VERSION', '2.4.0');
31
32 /** If you hardcode a WP.com API key here, all key config screens will be hidden */
33 if ( defined('WPCOM_API_KEY') )
34 $wpcom_api_key = constant('WPCOM_API_KEY');
35 else
36 $wpcom_api_key = '';
37
38 // Make sure we don't expose any info if called directly
39 if ( !function_exists( 'add_action' ) ) {
40 echo "Hi there! I'm just a plugin, not much I can do when called directly.";
41 exit;
42 }
43
44 if ( $wp_db_version <= 9872 )
45 include_once( dirname(__FILE__) . '/legacy.php' );
46
47 function akismet_init() {
48 global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
49
50 if ( $wpcom_api_key )
51 $akismet_api_host = $wpcom_api_key . '.rest.akismet.com';
52 else
53 $akismet_api_host = get_option('wordpress_api_key') . '.rest.akismet.com';
54
55 $akismet_api_port = 80;
56 add_action('admin_menu', 'akismet_config_page');
57 add_action('admin_menu', 'akismet_stats_page');
58 akismet_admin_warnings();
59 }
60 add_action('init', 'akismet_init');
61
62 function akismet_admin_init() {
63 if ( function_exists( 'get_plugin_page_hook' ) )
64 $hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' );
65 else
66 $hook = 'dashboard_page_akismet-stats-display';
67 add_action('admin_head-'.$hook, 'akismet_stats_script');
68 }
69 add_action('admin_init', 'akismet_admin_init');
70
71 if ( !function_exists('wp_nonce_field') ) {
72 function akismet_nonce_field($action = -1) { return; }
73 $akismet_nonce = -1;
74 } else {
75 function akismet_nonce_field($action = -1) { return wp_nonce_field($action); }
76 $akismet_nonce = 'akismet-update-key';
77 }
78
79 if ( !function_exists('number_format_i18n') ) {
80 function number_format_i18n( $number, $decimals = null ) { return number_format( $number, $decimals ); }
81 }
82
83 function akismet_config_page() {
84 if ( function_exists('add_submenu_page') )
85 add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
86
87 }
88
89 function akismet_conf() {
90 global $akismet_nonce, $wpcom_api_key;
91
92 if ( isset($_POST['submit']) ) {
93 if ( function_exists('current_user_can') && !current_user_can('manage_options') )
94 die(__('Cheatin&#8217; uh?'));
95
96 check_admin_referer( $akismet_nonce );
97 $key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] );
98
99 if ( empty($key) ) {
100 $key_status = 'empty';
101 $ms[] = 'new_key_empty';
102 delete_option('wordpress_api_key');
103 } else {
104 $key_status = akismet_verify_key( $key );
105 }
106
107 if ( $key_status == 'valid' ) {
108 update_option('wordpress_api_key', $key);
109 $ms[] = 'new_key_valid';
110 } else if ( $key_status == 'invalid' ) {
111 $ms[] = 'new_key_invalid';
112 } else if ( $key_status == 'failed' ) {
113 $ms[] = 'new_key_failed';
114 }
115
116 if ( isset( $_POST['akismet_discard_month'] ) )
117 update_option( 'akismet_discard_month', 'true' );
118 else
119 update_option( 'akismet_discard_month', 'false' );
120 } elseif ( isset($_POST['check']) ) {
121 akismet_get_server_connectivity(0);
122 }
123
124 if ( empty( $key_status) || $key_status != 'valid' ) {
125 $key = get_option('wordpress_api_key');
126 if ( empty( $key ) ) {
127 if ( empty( $key_status ) || $key_status != 'failed' ) {
128 if ( akismet_verify_key( '1234567890ab' ) == 'failed' )
129 $ms[] = 'no_connection';
130 else
131 $ms[] = 'key_empty';
132 }
133 $key_status = 'empty';
134 } else {
135 $key_status = akismet_verify_key( $key );
136 }
137 if ( $key_status == 'valid' ) {
138 $ms[] = 'key_valid';
139 } else if ( $key_status == 'invalid' ) {
140 delete_option('wordpress_api_key');
141 $ms[] = 'key_empty';
142 } else if ( !empty($key) && $key_status == 'failed' ) {
143 $ms[] = 'key_failed';
144 }
145 }
146
147 $messages = array(
148 'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')),
149 'new_key_valid' => array('color' => '2d2', 'text' => __('Your key has been verified. Happy blogging!')),
150 'new_key_invalid' => array('color' => 'd22', 'text' => __('The key you entered is invalid. Please double-check it.')),
151 '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.')),
152 'no_connection' => array('color' => 'd22', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')),
153 'key_empty' => array('color' => 'aa0', 'text' => sprintf(__('Please enter an API key. (<a href="%s" style="color:#fff">Get your key.</a>)'), 'http://akismet.com/get/')),
154 'key_valid' => array('color' => '2d2', 'text' => __('This key is valid.')),
155 '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.')));
156 ?>
157 <?php if ( !empty($_POST['submit'] ) ) : ?>
158 <div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
159 <?php endif; ?>
160 <div class="wrap">
161 <h2><?php _e('Akismet Configuration'); ?></h2>
162 <div class="narrow">
163 <form action="" method="post" id="akismet-conf" style="margin: auto; width: 400px; ">
164 <?php if ( !$wpcom_api_key ) { ?>
165 <p><?php printf(__('For many people, <a href="%1$s">Akismet</a> will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as "spam" on the moderation screen and Akismet will learn from the mistakes. If you don\'t have an API key yet, you can get one at <a href="%2$s">Akismet.com</a>.'), 'http://akismet.com/', 'http://akismet.com/get/'); ?></p>
166
167 <h3><label for="key"><?php _e('Akismet API Key'); ?></label></h3>
168 <?php foreach ( $ms as $m ) : ?>
169 <p style="padding: .5em; background-color: #<?php echo $messages[$m]['color']; ?>; color: #fff; font-weight: bold;"><?php echo $messages[$m]['text']; ?></p>
170 <?php endforeach; ?>
171 <p><input id="key" name="key" type="text" size="15" maxlength="12" value="<?php echo get_option('wordpress_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="http://akismet.com/get/">What is this?</a>'); ?>)</p>
172 <?php if ( isset( $invalid_key) && $invalid_key ) { ?>
173 <h3><?php _e('Why might my key be invalid?'); ?></h3>
174 <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>
175 <?php } ?>
176 <?php } ?>
177 <?php akismet_nonce_field($akismet_nonce) ?>
178 <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>
179 <p class="submit"><input type="submit" name="submit" value="<?php _e('Update options &raquo;'); ?>" /></p>
180 </form>
181
182 <form action="" method="post" id="akismet-connectivity" style="margin: auto; width: 400px; ">
183
184 <h3><?php _e('Server Connectivity'); ?></h3>
185 <?php
186 if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') ) {
187 ?>
188 <p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Network functions are disabled.'); ?></p>
189 <p><?php echo sprintf( __('Your web host or server administrator has disabled PHP\'s <code>fsockopen</code> or <code>gethostbynamel</code> functions. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet\'s system requirements</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
190 <?php
191 } else {
192 $servers = akismet_get_server_connectivity();
193 $fail_count = count($servers) - count( array_filter($servers) );
194 if ( is_array($servers) && count($servers) > 0 ) {
195 // some connections work, some fail
196 if ( $fail_count > 0 && $fail_count < count($servers) ) { ?>
197 <p style="padding: .5em; background-color: #aa0; color: #fff; font-weight:bold;"><?php _e('Unable to reach some Akismet servers.'); ?></p>
198 <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>
199 <?php
200 // all connections fail
201 } elseif ( $fail_count > 0 ) { ?>
202 <p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Unable to reach any Akismet servers.'); ?></p>
203 <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>
204 <?php
205 // all connections work
206 } else { ?>
207 <p style="padding: .5em; background-color: #2d2; color: #fff; font-weight:bold;"><?php _e('All Akismet servers are available.'); ?></p>
208 <p><?php _e('Akismet is working correctly. All servers are accessible.'); ?></p>
209 <?php
210 }
211 } else {
212 ?>
213 <p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Unable to find Akismet servers.'); ?></p>
214 <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>
215 <?php
216 }
217 }
218
219 if ( !empty($servers) ) {
220 ?>
221 <table style="width: 100%;">
222 <thead><th><?php _e('Akismet server'); ?></th><th><?php _e('Network Status'); ?></th></thead>
223 <tbody>
224 <?php
225 asort($servers);
226 foreach ( $servers as $ip => $status ) {
227 $color = ( $status ? '#2d2' : '#d22');
228 ?>
229 <tr>
230 <td><?php echo htmlspecialchars($ip); ?></td>
231 <td style="padding: 0 .5em; font-weight:bold; color: #fff; background-color: <?php echo $color; ?>"><?php echo ($status ? __('No problems') : __('Obstructed') ); ?></td>
232
233 <?php
234 }
235 }
236 ?>
237 </tbody>
238 </table>
239 <p><?php if ( get_option('akismet_connectivity_time') ) echo sprintf( __('Last checked %s ago.'), human_time_diff( get_option('akismet_connectivity_time') ) ); ?></p>
240 <p class="submit"><input type="submit" name="check" value="<?php _e('Check network status &raquo;'); ?>" /></p>
241 </form>
242
243 </div>
244 </div>
245 <?php
246 }
247
248 function akismet_stats_page() {
249 if ( function_exists('add_submenu_page') )
250 add_submenu_page('index.php', __('Akismet Stats'), __('Akismet Stats'), 'manage_options', 'akismet-stats-display', 'akismet_stats_display');
251
252 }
253
254 function akismet_stats_script() {
255 ?>
256 <script type="text/javascript">
257 function resizeIframe() {
258 var height = document.documentElement.clientHeight;
259 height -= document.getElementById('akismet-stats-frame').offsetTop;
260 height += 100; // magic padding
261
262 document.getElementById('akismet-stats-frame').style.height = height +"px";
263
264 };
265 function resizeIframeInit() {
266 document.getElementById('akismet-stats-frame').onload = resizeIframe;
267 window.onresize = resizeIframe;
268 }
269 addLoadEvent(resizeIframeInit);
270 </script><?php
271 }
272
273
274 function akismet_stats_display() {
275 global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
276 $blog = urlencode( get_option('home') );
277 $url = "http://".akismet_get_key().".web.akismet.com/1.0/user-stats.php?blog={$blog}";
278 ?>
279 <div class="wrap">
280 <iframe src="<?php echo $url; ?>" width="100%" height="100%" frameborder="0" id="akismet-stats-frame"></iframe>
281 </div>
282 <?php
283 }
284
285 function akismet_stats() {
286 if ( !function_exists('did_action') || did_action( 'rightnow_end' ) ) // We already displayed this info in the "Right Now" section
287 return;
288 if ( !$count = get_option('akismet_spam_count') )
289 return;
290 $path = plugin_basename(__FILE__);
291 echo '<h3>'.__('Spam').'</h3>';
292 global $submenu;
293 if ( isset( $submenu['edit-comments.php'] ) )
294 $link = 'edit-comments.php';
295 else
296 $link = 'edit.php';
297 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>';
298 }
299 add_action('activity_box_end', 'akismet_stats');
300
301 function akismet_get_key() {
302 global $wpcom_api_key;
303 if ( !empty($wpcom_api_key) )
304 return $wpcom_api_key;
305 return get_option('wordpress_api_key');
306 }
307
308 function akismet_verify_key( $key, $ip = null ) {
309 global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
310 $blog = urlencode( get_option('home') );
311 if ( $wpcom_api_key )
312 $key = $wpcom_api_key;
313 $response = akismet_http_post("key=$key&blog=$blog", 'rest.akismet.com', '/1.1/verify-key', $akismet_api_port, $ip);
314 if ( !is_array($response) || !isset($response[1]) || $response[1] != 'valid' && $response[1] != 'invalid' )
315 return 'failed';
316 return $response[1];
317 }
318
319 // Check connectivity between the WordPress blog and Akismet's servers.
320 // 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).
321 function akismet_check_server_connectivity() {
322 global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
323
324 $test_host = 'rest.akismet.com';
325
326 // Some web hosts may disable one or both functions
327 if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') )
328 return array();
329
330 $ips = gethostbynamel($test_host);
331 if ( !$ips || !is_array($ips) || !count($ips) )
332 return array();
333
334 $servers = array();
335 foreach ( $ips as $ip ) {
336 $response = akismet_verify_key( akismet_get_key(), $ip );
337 // even if the key is invalid, at least we know we have connectivity
338 if ( $response == 'valid' || $response == 'invalid' )
339 $servers[$ip] = true;
340 else
341 $servers[$ip] = false;
342 }
343
344 return $servers;
345 }
346
347 // Check the server connectivity and store the results in an option.
348 // Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update.
349 // Returns the same associative array as akismet_check_server_connectivity()
350 function akismet_get_server_connectivity( $cache_timeout = 86400 ) {
351 $servers = get_option('akismet_available_servers');
352 if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false )
353 return $servers;
354
355 // There's a race condition here but the effect is harmless.
356 $servers = akismet_check_server_connectivity();
357 update_option('akismet_available_servers', $servers);
358 update_option('akismet_connectivity_time', time());
359 return $servers;
360 }
361
362 // Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed.
363 function akismet_server_connectivity_ok() {
364 // skip the check on WPMU because the status page is hidden
365 global $wpcom_api_key;
366 if ( $wpcom_api_key )
367 return true;
368 $servers = akismet_get_server_connectivity();
369 return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) );
370 }
371
372 function akismet_admin_warnings() {
373 global $wpcom_api_key;
374 if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
375 function akismet_warning() {
376 echo "
377 <div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet is almost ready.')."</strong> ".sprintf(__('You must <a href="%1$s">enter your Akismet API key</a> for it to work.'), "plugins.php?page=akismet-key-config")."</p></div>
378 ";
379 }
380 add_action('admin_notices', 'akismet_warning');
381 return;
382 } elseif ( get_option('akismet_connectivity_time') && empty($_POST) && is_admin() && !akismet_server_connectivity_ok() ) {
383 function akismet_warning() {
384 echo "
385 <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>
386 ";
387 }
388 add_action('admin_notices', 'akismet_warning');
389 return;
390 }
391 }
392
393 function akismet_get_host($host) {
394 // if all servers are accessible, just return the host name.
395 // if not, return an IP that was known to be accessible at the last check.
396 if ( akismet_server_connectivity_ok() ) {
397 return $host;
398 } else {
399 $ips = akismet_get_server_connectivity();
400 // a firewall may be blocking access to some Akismet IPs
401 if ( count($ips) > 0 && count(array_filter($ips)) < count($ips) ) {
402 // use DNS to get current IPs, but exclude any known to be unreachable
403 $dns = (array)gethostbynamel( rtrim($host, '.') . '.' );
404 $dns = array_filter($dns);
405 foreach ( $dns as $ip ) {
406 if ( array_key_exists( $ip, $ips ) && empty( $ips[$ip] ) )
407 unset($dns[$ip]);
408 }
409 // return a random IP from those available
410 if ( count($dns) )
411 return $dns[ array_rand($dns) ];
412
413 }
414 }
415 // if all else fails try the host name
416 return $host;
417 }
418
419 // return a comma-separated list of role names for the given user
420 function akismet_get_user_roles($user_id ) {
421 $roles = false;
422
423 if ( !class_exists('WP_User') )
424 return false;
425
426 if ( $user_id > 0 ) {
427 $comment_user = new WP_User($user_id);
428 if ( isset($comment_user->roles) )
429 $roles = join(',', $comment_user->roles);
430 }
431
432 return $roles;
433 }
434
435 // Returns array with headers in $response[0] and body in $response[1]
436 function akismet_http_post($request, $host, $path, $port = 80, $ip=null) {
437 global $wp_version;
438
439 $akismet_version = constant('AKISMET_VERSION');
440
441 $http_request = "POST $path HTTP/1.0\r\n";
442 $http_request .= "Host: $host\r\n";
443 $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=" . get_option('blog_charset') . "\r\n";
444 $http_request .= "Content-Length: " . strlen($request) . "\r\n";
445 $http_request .= "User-Agent: WordPress/$wp_version | Akismet/$akismet_version\r\n";
446 $http_request .= "\r\n";
447 $http_request .= $request;
448
449 $http_host = $host;
450 // use a specific IP if provided - needed by akismet_check_server_connectivity()
451 if ( $ip && long2ip(ip2long($ip)) ) {
452 $http_host = $ip;
453 } else {
454 $http_host = akismet_get_host($host);
455 }
456
457 $response = '';
458 if( false != ( $fs = @fsockopen($http_host, $port, $errno, $errstr, 10) ) ) {
459 fwrite($fs, $http_request);
460
461 while ( !feof($fs) )
462 $response .= fgets($fs, 1160); // One TCP-IP packet
463 fclose($fs);
464 $response = explode("\r\n\r\n", $response, 2);
465 }
466 return $response;
467 }
468
469 // filter handler used to return a spam result to pre_comment_approved
470 function akismet_result_spam( $approved ) {
471 // bump the counter here instead of when the filter is added to reduce the possibility of overcounting
472 if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
473 update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
474 return 'spam';
475 }
476
477 function akismet_auto_check_comment( $commentdata ) {
478 global $akismet_api_host, $akismet_api_port;
479
480 $comment = $commentdata;
481 $comment['user_ip'] = $_SERVER['REMOTE_ADDR'];
482 $comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
483 $comment['referrer'] = $_SERVER['HTTP_REFERER'];
484 $comment['blog'] = get_option('home');
485 $comment['blog_lang'] = get_locale();
486 $comment['blog_charset'] = get_option('blog_charset');
487 $comment['permalink'] = get_permalink($comment['comment_post_ID']);
488
489 $comment['user_role'] = akismet_get_user_roles($comment['user_ID']);
490
491 $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
492
493 foreach ( $_SERVER as $key => $value )
494 if ( !in_array( $key, $ignore ) && is_string($value) )
495 $comment["$key"] = $value;
496 else
497 $comment["$key"] = '';
498
499 $query_string = '';
500 foreach ( $comment as $key => $data )
501 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
502
503 $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
504 $commentdata['akismet_result'] = $response[1];
505 if ( 'true' == $response[1] ) {
506 // akismet_spam_count will be incremented later by akismet_result_spam()
507 add_filter('pre_comment_approved', 'akismet_result_spam');
508
509 do_action( 'akismet_spam_caught' );
510
511 $post = get_post( $comment['comment_post_ID'] );
512 $last_updated = strtotime( $post->post_modified_gmt );
513 $diff = time() - $last_updated;
514 $diff = $diff / 86400;
515
516 if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' && empty($comment['user_ID']) ) {
517 // akismet_result_spam() won't be called so bump the counter here
518 if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
519 update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
520 die;
521 }
522 }
523
524 if ( function_exists('wp_next_scheduled') && function_exists('wp_schedule_event') ) {
525 // WP 2.1+: delete old comments daily
526 if ( !wp_next_scheduled('akismet_scheduled_delete') )
527 wp_schedule_event(time(), 'daily', 'akismet_scheduled_delete');
528 } elseif ( (mt_rand(1, 10) == 3) ) {
529 // WP 2.0: run this one time in ten
530 akismet_delete_old();
531 }
532 return $commentdata;
533 }
534
535 function akismet_delete_old() {
536 global $wpdb;
537 $now_gmt = current_time('mysql', 1);
538 $comment_ids = $wpdb->get_col("SELECT comment_id FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'");
539 if ( empty( $comment_ids ) )
540 return;
541
542 do_action( 'delete_comment', $comment_ids );
543 $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_id IN ( " . implode( ', ', $comment_ids ) . " )");
544 $n = mt_rand(1, 5000);
545 if ( apply_filters('akismet_optimize_table', ($n == 11)) ) // lucky number
546 $wpdb->query("OPTIMIZE TABLE $wpdb->comments");
547
548 }
549
550 add_action('akismet_scheduled_delete', 'akismet_delete_old');
551
552 function akismet_submit_nonspam_comment ( $comment_id ) {
553 global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
554 $comment_id = (int) $comment_id;
555
556 $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
557 if ( !$comment ) // it was deleted
558 return;
559 $comment->blog = get_option('home');
560 $comment->blog_lang = get_locale();
561 $comment->blog_charset = get_option('blog_charset');
562 $comment->permalink = get_permalink($comment->comment_post_ID);
563 if ( is_object($current_user) ) {
564 $comment->reporter = $current_user->user_login;
565 }
566 if ( is_object($current_site) ) {
567 $comment->site_domain = $current_site->domain;
568 }
569
570 $comment->user_role = '';
571 if ( isset( $comment->user_ID ) )
572 $comment->user_role = akismet_get_user_roles($comment->user_ID);
573
574 $query_string = '';
575 foreach ( $comment as $key => $data )
576 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
577
578 $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
579 do_action('akismet_submit_nonspam_comment', $comment_id, $response[1]);
580 }
581
582 function akismet_submit_spam_comment ( $comment_id ) {
583 global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
584 $comment_id = (int) $comment_id;
585
586 $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
587 if ( !$comment ) // it was deleted
588 return;
589 if ( 'spam' != $comment->comment_approved )
590 return;
591 $comment->blog = get_option('home');
592 $comment->blog_lang = get_locale();
593 $comment->blog_charset = get_option('blog_charset');
594 $comment->permalink = get_permalink($comment->comment_post_ID);
595 if ( is_object($current_user) ) {
596 $comment->reporter = $current_user->user_login;
597 }
598 if ( is_object($current_site) ) {
599 $comment->site_domain = $current_site->domain;
600 }
601
602 $comment->user_role = '';
603 if ( !isset( $comment->user_id ) )
604 $comment->user_role = akismet_get_user_roles($comment->user_ID);
605
606 $query_string = '';
607 foreach ( $comment as $key => $data )
608 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
609
610 $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
611 do_action('akismet_submit_spam_comment', $comment_id, $response[1]);
612 }
613
614 add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
615
616 // For old versions of WP only
617 function akismet_set_comment_status( $comment_id, $status ) {
618 if ( $status == 'spam' ) {
619 akismet_submit_spam_comment( $comment_id );
620 } elseif ( $status == 'approve' ) {
621 akismet_submit_nonspam_comment( $comment_id );
622 }
623 }
624
625 // For WP 2.7+
626 function akismet_transition_comment_status( $new_status, $old_status, $comment ) {
627 if ( $new_status == $old_status )
628 return;
629
630 if ( $new_status == 'spam' ) {
631 akismet_submit_spam_comment( $comment->comment_ID );
632 } elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) {
633 akismet_submit_nonspam_comment( $comment->comment_ID );
634 }
635 }
636
637 function akismet_spamtoham( $comment ) { akismet_submit_nonspam_comment( $comment->comment_ID ); }
638
639 if ( function_exists( 'wp_transition_comment_status' ) ) {
640 add_action( 'transition_comment_status', 'akismet_transition_comment_status', 10, 3 );
641 } else {
642 add_action('wp_set_comment_status', 'akismet_set_comment_status', 10, 2);
643 add_action('edit_comment', 'akismet_submit_spam_comment');
644 add_filter( 'comment_spam_to_approved', 'akismet_spamtoham' );
645 add_filter( 'comment_spam_to_unapproved', 'akismet_spamtoham' );
646 }
647 // Total spam in queue
648 // get_option( 'akismet_spam_count' ) is the total caught ever
649 function akismet_spam_count( $type = false ) {
650 global $wpdb;
651
652 if ( !$type ) { // total
653 $count = wp_cache_get( 'akismet_spam_count', 'widget' );
654 if ( false === $count ) {
655 if ( function_exists('wp_count_comments') ) {
656 $count = wp_count_comments();
657 $count = $count->spam;
658 } else {
659 $count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
660 }
661 wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
662 }
663 return $count;
664 } elseif ( 'comments' == $type || 'comment' == $type ) { // comments
665 $type = '';
666 } else { // pingback, trackback, ...
667 $type = $wpdb->escape( $type );
668 }
669
670 return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
671 }
672
673
674 // WP 2.5+
675 function akismet_rightnow() {
676 global $submenu, $wp_db_version;
677
678 // clean_url was deprecated in WP 3.0
679 $esc_url = 'clean_url';
680 if ( function_exists( 'esc_url' ) )
681 $esc_url = 'esc_url';
682
683 if ( 8645 < $wp_db_version ) // 2.7
684 $link = 'edit-comments.php?comment_status=spam';
685 elseif ( isset( $submenu['edit-comments.php'] ) )
686 $link = 'edit-comments.php?page=akismet-admin';
687 else
688 $link = 'edit.php?page=akismet-admin';
689
690 if ( $count = get_option('akismet_spam_count') ) {
691 $intro = sprintf( __ngettext(
692 '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comment already,',
693 '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comments already,',
694 $count
695 ), 'http://akismet.com/', number_format_i18n( $count ) );
696 } else {
697 $intro = sprintf( __('<a href="%1$s">Akismet</a> blocks spam from getting to your blog,'), 'http://akismet.com/' );
698 }
699
700 if ( $queue_count = akismet_spam_count() ) {
701 $queue_text = sprintf( __ngettext(
702 'and there\'s <a href="%2$s">%1$s comment</a> in your spam queue right now.',
703 'and there are <a href="%2$s">%1$s comments</a> in your spam queue right now.',
704 $queue_count
705 ), number_format_i18n( $queue_count ), clean_url($link) );
706 } else {
707 $queue_text = sprintf( __( "but there's nothing in your <a href='%1\$s'>spam queue</a> at the moment." ), $esc_url($link) );
708 }
709
710 // _c was deprecated in WP 2.9.0
711 if ( function_exists( '_x' ) )
712 $text = sprintf( _x( '%1$s %2$s', 'akismet_rightnow' ), $intro, $queue_text );
713 else
714 $text = sprintf( _c( '%1$s %2$s|akismet_rightnow' ), $intro, $queue_text );
715
716 echo "<p class='akismet-right-now'>$text</p>\n";
717 }
718
719 add_action('rightnow_end', 'akismet_rightnow');
720
721
722 // For WP >= 2.5
723 function akismet_check_for_spam_button($comment_status) {
724 if ( 'approved' == $comment_status )
725 return;
726 if ( function_exists('plugins_url') )
727 $link = 'admin.php?action=akismet_recheck_queue';
728 else
729 $link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
730 echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
731 }
732 add_action('manage_comments_nav', 'akismet_check_for_spam_button');
733
734 function akismet_recheck_queue() {
735 global $wpdb, $akismet_api_host, $akismet_api_port;
736
737 if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
738 return;
739
740 $moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
741 foreach ( (array) $moderation as $c ) {
742 $c['user_ip'] = $c['comment_author_IP'];
743 $c['user_agent'] = $c['comment_agent'];
744 $c['referrer'] = '';
745 $c['blog'] = get_option('home');
746 $c['blog_lang'] = get_locale();
747 $c['blog_charset'] = get_option('blog_charset');
748 $c['permalink'] = get_permalink($c['comment_post_ID']);
749
750 $c['user_role'] = '';
751 if ( isset( $c['user_ID'] ) )
752 $c['user_role'] = akismet_get_user_roles($c['user_ID']);
753
754 $id = (int) $c['comment_ID'];
755
756 $query_string = '';
757 foreach ( $c as $key => $data )
758 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
759
760 $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
761 if ( 'true' == $response[1] ) {
762 if ( function_exists('wp_set_comment_status') )
763 wp_set_comment_status($id, 'spam');
764 else
765 $wpdb->query("UPDATE $wpdb->comments SET comment_approved = 'spam' WHERE comment_ID = $id");
766
767 }
768 }
769 wp_redirect( $_SERVER['HTTP_REFERER'] );
770 exit;
771 }
772
773 add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
774
775 function akismet_check_db_comment( $id ) {
776 global $wpdb, $akismet_api_host, $akismet_api_port;
777
778 $id = (int) $id;
779 $c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
780 if ( !$c )
781 return;
782
783 $c['user_ip'] = $c['comment_author_IP'];
784 $c['user_agent'] = $c['comment_agent'];
785 $c['referrer'] = '';
786 $c['blog'] = get_option('home');
787 $c['blog_lang'] = get_locale();
788 $c['blog_charset'] = get_option('blog_charset');
789 $c['permalink'] = get_permalink($c['comment_post_ID']);
790 $id = $c['comment_ID'];
791
792 $query_string = '';
793 foreach ( $c as $key => $data )
794 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
795
796 $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
797 return $response[1];
798 }
799
800 // Widget stuff
801 function widget_akismet_register() {
802 if ( function_exists('register_sidebar_widget') ) :
803 function widget_akismet($args) {
804 extract($args);
805 $options = get_option('widget_akismet');
806 $count = number_format_i18n(get_option('akismet_spam_count'));
807 ?>
808 <?php echo $before_widget; ?>
809 <?php echo $before_title . $options['title'] . $after_title; ?>
810 <div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><?php printf( __( '%1$s %2$sspam comments%3$s %4$sblocked by%5$s<br />%6$sAkismet%7$s' ), '<span id="akismet1"><span id="akismetcount">' . $count . '</span>', '<span id="akismetsc">', '</span></span>', '<span id="akismet2"><span id="akismetbb">', '</span>', '<span id="akismeta">', '</span></span>' ); ?></a></div></div>
811 <?php echo $after_widget; ?>
812 <?php
813 }
814
815 function widget_akismet_style() {
816 $plugin_dir = '/wp-content/plugins';
817 if ( defined( 'PLUGINDIR' ) )
818 $plugin_dir = '/' . PLUGINDIR;
819
820 ?>
821 <style type="text/css">
822 #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
823 #aka:hover{border:none;text-decoration:none}
824 #aka:hover #akismet1{display:none}
825 #aka:hover #akismet2,#akismet1{display:block}
826 #akismet2{display:none;padding-top:2px}
827 #akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
828 #akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
829 #akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'), $plugin_dir; ?>/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}
830 </style>
831 <?php
832 }
833
834 function widget_akismet_control() {
835 $options = $newoptions = get_option('widget_akismet');
836 if ( isset( $_POST['akismet-submit'] ) && $_POST["akismet-submit"] ) {
837 $newoptions['title'] = strip_tags(stripslashes($_POST["akismet-title"]));
838 if ( empty($newoptions['title']) ) $newoptions['title'] = __('Spam Blocked');
839 }
840 if ( $options != $newoptions ) {
841 $options = $newoptions;
842 update_option('widget_akismet', $options);
843 }
844 $title = htmlspecialchars($options['title'], ENT_QUOTES);
845 ?>
846 <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>
847 <input type="hidden" id="akismet-submit" name="akismet-submit" value="1" />
848 <?php
849 }
850
851 if ( function_exists( 'wp_register_sidebar_widget' ) ) {
852 wp_register_sidebar_widget( 'akismet', 'Akismet', 'widget_akismet', null, 'akismet');
853 wp_register_widget_control( 'akismet', 'Akismet', 'widget_akismet_control', null, 75, 'akismet');
854 } else {
855 register_sidebar_widget('Akismet', 'widget_akismet', null, 'akismet');
856 register_widget_control('Akismet', 'widget_akismet_control', null, 75, 'akismet');
857 }
858 if ( is_active_widget('widget_akismet') )
859 add_action('wp_head', 'widget_akismet_style');
860 endif;
861 }
862
863 add_action('init', 'widget_akismet_register');
864
865 // Counter for non-widget users
866 function akismet_counter() {
867 $plugin_dir = '/wp-content/plugins';
868 if ( defined( 'PLUGINDIR' ) )
869 $plugin_dir = '/' . PLUGINDIR;
870
871 ?>
872 <style type="text/css">
873 #akismetwrap #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
874 #aka:hover{border:none;text-decoration:none}
875 #aka:hover #akismet1{display:none}
876 #aka:hover #akismet2,#akismet1{display:block}
877 #akismet2{display:none;padding-top:2px}
878 #akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
879 #akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
880 #akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'), $plugin_dir; ?>/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}
881 </style>
882 <?php
883 $count = number_format_i18n(get_option('akismet_spam_count'));
884 ?>
885 <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>
886 <?php
887 }
888
889 ?>
890