source: akismet/trunk/akismet.php @ 488425

Revision 488425, 20.6 KB checked in by josephscott, 3 weeks ago (diff)

Tag 2.5.5 release

  • Property svn:eol-style set to native
Line 
1<?php
2/**
3 * @package Akismet
4 */
5/*
6Plugin Name: Akismet
7Plugin URI: http://akismet.com/?return=true
8Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from comment and trackback spam</strong>. It keeps your site protected from spam even while you sleep. To get started: 1) Click the "Activate" link to the left of this description, 2) <a href="http://akismet.com/get/?return=true">Sign up for an Akismet API key</a>, and 3) Go to your <a href="admin.php?page=akismet-key-config">Akismet configuration</a> page, and save your API key.
9Version: 2.5.5
10Author: Automattic
11Author URI: http://automattic.com/wordpress-plugins/
12License: GPLv2 or later
13*/
14
15/*
16This program is free software; you can redistribute it and/or
17modify it under the terms of the GNU General Public License
18as published by the Free Software Foundation; either version 2
19of the License, or (at your option) any later version.
20
21This program is distributed in the hope that it will be useful,
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24GNU General Public License for more details.
25
26You should have received a copy of the GNU General Public License
27along with this program; if not, write to the Free Software
28Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
29*/
30
31define('AKISMET_VERSION', '2.5.5');
32define('AKISMET_PLUGIN_URL', plugin_dir_url( __FILE__ ));
33
34/** If you hardcode a WP.com API key here, all key config screens will be hidden */
35if ( defined('WPCOM_API_KEY') )
36        $wpcom_api_key = constant('WPCOM_API_KEY');
37else
38        $wpcom_api_key = '';
39
40// Make sure we don't expose any info if called directly
41if ( !function_exists( 'add_action' ) ) {
42        echo "Hi there!  I'm just a plugin, not much I can do when called directly.";
43        exit;
44}
45
46if ( isset($wp_db_version) && $wp_db_version <= 9872 )
47        include_once dirname( __FILE__ ) . '/legacy.php';
48
49include_once dirname( __FILE__ ) . '/widget.php';
50
51if ( is_admin() )
52        require_once dirname( __FILE__ ) . '/admin.php';
53
54function akismet_init() {
55        global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
56
57        if ( $wpcom_api_key )
58                $akismet_api_host = $wpcom_api_key . '.rest.akismet.com';
59        else
60                $akismet_api_host = get_option('wordpress_api_key') . '.rest.akismet.com';
61
62        $akismet_api_port = 80;
63}
64add_action('init', 'akismet_init');
65
66function akismet_get_key() {
67        global $wpcom_api_key;
68        if ( !empty($wpcom_api_key) )
69                return $wpcom_api_key;
70        return get_option('wordpress_api_key');
71}
72
73function akismet_verify_key( $key, $ip = null ) {
74        global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
75        $blog = urlencode( get_option('home') );
76        if ( $wpcom_api_key )
77                $key = $wpcom_api_key;
78        $response = akismet_http_post("key=$key&blog=$blog", 'rest.akismet.com', '/1.1/verify-key', $akismet_api_port, $ip);
79        if ( !is_array($response) || !isset($response[1]) || $response[1] != 'valid' && $response[1] != 'invalid' )
80                return 'failed';
81        return $response[1];
82}
83
84// if we're in debug or test modes, use a reduced service level so as not to polute training or stats data
85function akismet_test_mode() {
86        if ( defined('AKISMET_TEST_MODE') && AKISMET_TEST_MODE )
87                return true;
88        return false;
89}
90
91// return a comma-separated list of role names for the given user
92function akismet_get_user_roles($user_id ) {
93        $roles = false;
94       
95        if ( !class_exists('WP_User') )
96                return false;
97       
98        if ( $user_id > 0 ) {
99                $comment_user = new WP_User($user_id);
100                if ( isset($comment_user->roles) )
101                        $roles = join(',', $comment_user->roles);
102        }
103
104        if ( is_multisite() && is_super_admin( $user_id ) ) {
105                if ( empty( $roles ) ) {
106                        $roles = 'super_admin';
107                } else {
108                        $comment_user->roles[] = 'super_admin';
109                        $roles = join( ',', $comment_user->roles );
110                }
111        }
112
113        return $roles;
114}
115
116// Returns array with headers in $response[0] and body in $response[1]
117function akismet_http_post($request, $host, $path, $port = 80, $ip=null) {
118        global $wp_version;
119
120        $akismet_ua = "WordPress/{$wp_version} | ";
121        $akismet_ua .= 'Akismet/' . constant( 'AKISMET_VERSION' );
122
123        $akismet_ua = apply_filters( 'akismet_ua', $akismet_ua );
124
125        $content_length = strlen( $request );
126
127        $http_host = $host;
128        // use a specific IP if provided
129        // needed by akismet_check_server_connectivity()
130        if ( $ip && long2ip( ip2long( $ip ) ) ) {
131                $http_host = $ip;
132        } else {
133                $http_host = $host;
134        }
135       
136        // use the WP HTTP class if it is available
137        if ( function_exists( 'wp_remote_post' ) ) {
138                $http_args = array(
139                        'body'                  => $request,
140                        'headers'               => array(
141                                'Content-Type'  => 'application/x-www-form-urlencoded; ' .
142                                                                        'charset=' . get_option( 'blog_charset' ),
143                                'Host'                  => $host,
144                                'User-Agent'    => $akismet_ua
145                        ),
146                        'httpversion'   => '1.0',
147                        'timeout'               => 15
148                );
149                $akismet_url = "http://{$http_host}{$path}";
150                $response = wp_remote_post( $akismet_url, $http_args );
151                if ( is_wp_error( $response ) )
152                        return '';
153
154                return array( $response['headers'], $response['body'] );
155        } else {
156                $http_request  = "POST $path HTTP/1.0\r\n";
157                $http_request .= "Host: $host\r\n";
158                $http_request .= 'Content-Type: application/x-www-form-urlencoded; charset=' . get_option('blog_charset') . "\r\n";
159                $http_request .= "Content-Length: {$content_length}\r\n";
160                $http_request .= "User-Agent: {$akismet_ua}\r\n";
161                $http_request .= "\r\n";
162                $http_request .= $request;
163               
164                $response = '';
165                if( false != ( $fs = @fsockopen( $http_host, $port, $errno, $errstr, 10 ) ) ) {
166                        fwrite( $fs, $http_request );
167
168                        while ( !feof( $fs ) )
169                                $response .= fgets( $fs, 1160 ); // One TCP-IP packet
170                        fclose( $fs );
171                        $response = explode( "\r\n\r\n", $response, 2 );
172                }
173                return $response;
174        }
175}
176
177// filter handler used to return a spam result to pre_comment_approved
178function akismet_result_spam( $approved ) {
179        // bump the counter here instead of when the filter is added to reduce the possibility of overcounting
180        if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
181                update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
182        // this is a one-shot deal
183        remove_filter( 'pre_comment_approved', 'akismet_result_spam' );
184        return 'spam';
185}
186
187function akismet_result_hold( $approved ) {
188        // once only
189        remove_filter( 'pre_comment_approved', 'akismet_result_hold' );
190        return '0';
191}
192
193// how many approved comments does this author have?
194function akismet_get_user_comments_approved( $user_id, $comment_author_email, $comment_author, $comment_author_url ) {
195        global $wpdb;
196       
197        if ( !empty($user_id) )
198                return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE user_id = %d AND comment_approved = 1", $user_id ) );
199               
200        if ( !empty($comment_author_email) )
201                return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_author_email = %s AND comment_author = %s AND comment_author_url = %s AND comment_approved = 1", $comment_author_email, $comment_author, $comment_author_url ) );
202               
203        return 0;
204}
205
206function akismet_microtime() {
207        $mtime = explode( ' ', microtime() );
208        return $mtime[1] + $mtime[0];
209}
210
211// log an event for a given comment, storing it in comment_meta
212function akismet_update_comment_history( $comment_id, $message, $event=null ) {
213        global $current_user;
214
215        // failsafe for old WP versions
216        if ( !function_exists('add_comment_meta') )
217                return false;
218       
219        $user = '';
220        if ( is_object($current_user) && isset($current_user->user_login) )
221                $user = $current_user->user_login;
222
223        $event = array(
224                'time' => akismet_microtime(),
225                'message' => $message,
226                'event' => $event,
227                'user' => $user,
228        );
229
230        // $unique = false so as to allow multiple values per comment
231        $r = add_comment_meta( $comment_id, 'akismet_history', $event, false );
232}
233
234// get the full comment history for a given comment, as an array in reverse chronological order
235function akismet_get_comment_history( $comment_id ) {
236       
237        // failsafe for old WP versions
238        if ( !function_exists('add_comment_meta') )
239                return false;
240
241        $history = get_comment_meta( $comment_id, 'akismet_history', false );
242        usort( $history, 'akismet_cmp_time' );
243        return $history;
244}
245
246function akismet_cmp_time( $a, $b ) {
247        return $a['time'] > $b['time'] ? -1 : 1;
248}
249
250// this fires on wp_insert_comment.  we can't update comment_meta when akismet_auto_check_comment() runs
251// because we don't know the comment ID at that point.
252function akismet_auto_check_update_meta( $id, $comment ) {
253        global $akismet_last_comment;
254
255        // failsafe for old WP versions
256        if ( !function_exists('add_comment_meta') )
257                return false;
258
259        // wp_insert_comment() might be called in other contexts, so make sure this is the same comment
260        // as was checked by akismet_auto_check_comment
261        if ( is_object($comment) && !empty($akismet_last_comment) && is_array($akismet_last_comment) ) {
262                if ( intval($akismet_last_comment['comment_post_ID']) == intval($comment->comment_post_ID)
263                        && $akismet_last_comment['comment_author'] == $comment->comment_author
264                        && $akismet_last_comment['comment_author_email'] == $comment->comment_author_email ) {
265                                // normal result: true or false
266                                if ( $akismet_last_comment['akismet_result'] == 'true' ) {
267                                        update_comment_meta( $comment->comment_ID, 'akismet_result', 'true' );
268                                        akismet_update_comment_history( $comment->comment_ID, __('Akismet caught this comment as spam'), 'check-spam' );
269                                        if ( $comment->comment_approved != 'spam' )
270                                                akismet_update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s'), $comment->comment_approved), 'status-changed'.$comment->comment_approved );
271                                } elseif ( $akismet_last_comment['akismet_result'] == 'false' ) {
272                                        update_comment_meta( $comment->comment_ID, 'akismet_result', 'false' );
273                                        akismet_update_comment_history( $comment->comment_ID, __('Akismet cleared this comment'), 'check-ham' );
274                                        if ( $comment->comment_approved == 'spam' ) {
275                                                if ( wp_blacklist_check($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent) )
276                                                        akismet_update_comment_history( $comment->comment_ID, __('Comment was caught by wp_blacklist_check'), 'wp-blacklisted' );
277                                                else
278                                                        akismet_update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s'), $comment->comment_approved), 'status-changed-'.$comment->comment_approved );
279                                        }
280                                // abnormal result: error
281                                } else {
282                                        update_comment_meta( $comment->comment_ID, 'akismet_error', time() );
283                                        akismet_update_comment_history( $comment->comment_ID, sprintf( __('Akismet was unable to check this comment (response: %s), will automatically retry again later.'), $akismet_last_comment['akismet_result']), 'check-error' );
284                                }
285                               
286                                // record the complete original data as submitted for checking
287                                if ( isset($akismet_last_comment['comment_as_submitted']) )
288                                        update_comment_meta( $comment->comment_ID, 'akismet_as_submitted', $akismet_last_comment['comment_as_submitted'] );
289                }
290        }
291}
292
293add_action( 'wp_insert_comment', 'akismet_auto_check_update_meta', 10, 2 );
294
295
296function akismet_auto_check_comment( $commentdata ) {
297        global $akismet_api_host, $akismet_api_port, $akismet_last_comment;
298
299        $comment = $commentdata;
300        $comment['user_ip']    = $_SERVER['REMOTE_ADDR'];
301        $comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
302        $comment['referrer']   = $_SERVER['HTTP_REFERER'];
303        $comment['blog']       = get_option('home');
304        $comment['blog_lang']  = get_locale();
305        $comment['blog_charset'] = get_option('blog_charset');
306        $comment['permalink']  = get_permalink($comment['comment_post_ID']);
307       
308        if ( !empty( $comment['user_ID'] ) ) {
309                $comment['user_role'] = akismet_get_user_roles($comment['user_ID']);
310        }
311
312        $akismet_nonce_option = apply_filters( 'akismet_comment_nonce', get_option( 'akismet_comment_nonce' ) );
313        $comment['akismet_comment_nonce'] = 'inactive';
314        if ( $akismet_nonce_option == 'true' || $akismet_nonce_option == '' ) {
315                $comment['akismet_comment_nonce'] = 'failed';
316                if ( isset( $_POST['akismet_comment_nonce'] ) && wp_verify_nonce( $_POST['akismet_comment_nonce'], 'akismet_comment_nonce_' . $comment['comment_post_ID'] ) )
317                        $comment['akismet_comment_nonce'] = 'passed';
318
319                // comment reply in wp-admin
320                if ( isset( $_POST['_ajax_nonce-replyto-comment'] ) && check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' ) )
321                        $comment['akismet_comment_nonce'] = 'passed';
322
323        }
324
325        if ( akismet_test_mode() )
326                $comment['is_test'] = 'true';
327               
328        foreach ($_POST as $key => $value ) {
329                if ( is_string($value) )
330                        $comment["POST_{$key}"] = $value;
331        }
332
333        $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
334
335        foreach ( $_SERVER as $key => $value ) {
336                if ( !in_array( $key, $ignore ) && is_string($value) )
337                        $comment["$key"] = $value;
338                else
339                        $comment["$key"] = '';
340        }
341
342        $post = get_post( $comment['comment_post_ID'] );
343        $comment[ 'comment_post_modified_gmt' ] = $post->post_modified_gmt;
344
345        $query_string = '';
346        foreach ( $comment as $key => $data )
347                $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
348               
349        $commentdata['comment_as_submitted'] = $comment;
350
351        $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
352        $commentdata['akismet_result'] = $response[1];
353        if ( 'true' == $response[1] ) {
354                // akismet_spam_count will be incremented later by akismet_result_spam()
355                add_filter('pre_comment_approved', 'akismet_result_spam');
356
357                do_action( 'akismet_spam_caught' );
358
359                $last_updated = strtotime( $post->post_modified_gmt );
360                $diff = time() - $last_updated;
361                $diff = $diff / 86400;
362               
363                if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' && empty($comment['user_ID']) ) {
364                        // akismet_result_spam() won't be called so bump the counter here
365                        if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
366                                update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
367                        wp_safe_redirect( $_SERVER['HTTP_REFERER'] );
368                        die();
369                }
370        }
371       
372        // if the response is neither true nor false, hold the comment for moderation and schedule a recheck
373        if ( 'true' != $response[1] && 'false' != $response[1] ) {
374                if ( !wp_get_current_user() ) {
375                        add_filter('pre_comment_approved', 'akismet_result_hold');
376                }
377                wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' );
378        }
379       
380        if ( function_exists('wp_next_scheduled') && function_exists('wp_schedule_event') ) {
381                // WP 2.1+: delete old comments daily
382                if ( !wp_next_scheduled('akismet_scheduled_delete') )
383                        wp_schedule_event(time(), 'daily', 'akismet_scheduled_delete');
384        } elseif ( (mt_rand(1, 10) == 3) ) {
385                // WP 2.0: run this one time in ten
386                akismet_delete_old();
387        }
388        $akismet_last_comment = $commentdata;
389        return $commentdata;
390}
391
392add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
393
394function akismet_delete_old() {
395        global $wpdb;
396        $now_gmt = current_time('mysql', 1);
397        $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'");
398        if ( empty( $comment_ids ) )
399                return;
400               
401        $comma_comment_ids = implode( ', ', array_map('intval', $comment_ids) );
402
403        do_action( 'delete_comment', $comment_ids );
404        $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_id IN ( $comma_comment_ids )");
405        $wpdb->query("DELETE FROM $wpdb->commentmeta WHERE comment_id IN ( $comma_comment_ids )");
406        clean_comment_cache( $comment_ids );
407        $n = mt_rand(1, 5000);
408        if ( apply_filters('akismet_optimize_table', ($n == 11)) ) // lucky number
409                $wpdb->query("OPTIMIZE TABLE $wpdb->comments");
410
411}
412
413function akismet_delete_old_metadata() {
414        global $wpdb;
415
416        $now_gmt = current_time( 'mysql', 1 );
417        $interval = apply_filters( 'akismet_delete_commentmeta_interval', 15 );
418
419        # enfore a minimum of 1 day
420        $interval = absint( $interval );
421        if ( $interval < 1 ) {
422                return;
423        }
424
425        // akismet_as_submitted meta values are large, so expire them
426        // after $interval days regardless of the comment status
427        while ( TRUE ) {
428                $comment_ids = $wpdb->get_col( "SELECT $wpdb->comments.comment_id FROM $wpdb->commentmeta INNER JOIN $wpdb->comments USING(comment_id) WHERE meta_key = 'akismet_as_submitted' AND DATE_SUB('$now_gmt', INTERVAL {$interval} DAY) > comment_date_gmt LIMIT 10000" );
429
430                if ( empty( $comment_ids ) ) {
431                        return;
432                }
433
434                foreach ( $comment_ids as $comment_id ) {
435                        delete_comment_meta( $comment_id, 'akismet_as_submitted' );
436                }
437        }
438
439        /*
440        $n = mt_rand( 1, 5000 );
441        if ( apply_filters( 'akismet_optimize_table', ( $n == 11 ), 'commentmeta' ) ) { // lucky number
442                $wpdb->query( "OPTIMIZE TABLE $wpdb->commentmeta" );
443        }
444        */
445}
446
447add_action('akismet_scheduled_delete', 'akismet_delete_old');
448add_action('akismet_scheduled_delete', 'akismet_delete_old_metadata');
449
450function akismet_check_db_comment( $id, $recheck_reason = 'recheck_queue' ) {
451    global $wpdb, $akismet_api_host, $akismet_api_port;
452
453    $id = (int) $id;
454    $c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
455    if ( !$c )
456        return;
457
458    $c['user_ip']    = $c['comment_author_IP'];
459    $c['user_agent'] = $c['comment_agent'];
460    $c['referrer']   = '';
461    $c['blog']       = get_option('home');
462    $c['blog_lang']  = get_locale();
463    $c['blog_charset'] = get_option('blog_charset');
464    $c['permalink']  = get_permalink($c['comment_post_ID']);
465    $id = $c['comment_ID'];
466        if ( akismet_test_mode() )
467                $c['is_test'] = 'true';
468        $c['recheck_reason'] = $recheck_reason;
469
470    $query_string = '';
471    foreach ( $c as $key => $data )
472    $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
473
474    $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
475    return $response[1];
476}
477
478function akismet_cron_recheck() {
479        global $wpdb;
480
481        delete_option('akismet_available_servers');
482
483        $comment_errors = $wpdb->get_col( "
484                SELECT comment_id
485                FROM {$wpdb->prefix}commentmeta
486                WHERE meta_key = 'akismet_error'
487                LIMIT 100
488        " );
489       
490        foreach ( (array) $comment_errors as $comment_id ) {
491                // if the comment no longer exists, remove the meta entry from the queue to avoid getting stuck
492                if ( !get_comment( $comment_id ) ) {
493                        delete_comment_meta( $comment_id, 'akismet_error' );
494                        continue;
495                }
496               
497                add_comment_meta( $comment_id, 'akismet_rechecking', true );
498                $status = akismet_check_db_comment( $comment_id, 'retry' );
499
500                $msg = '';
501                if ( $status == 'true' ) {
502                        $msg = __( 'Akismet caught this comment as spam during an automatic retry.' );
503                } elseif ( $status == 'false' ) {
504                        $msg = __( 'Akismet cleared this comment during an automatic retry.' );
505                }
506               
507                // If we got back a legit response then update the comment history
508                // other wise just bail now and try again later.  No point in
509                // re-trying all the comments once we hit one failure.
510                if ( !empty( $msg ) ) {
511                        delete_comment_meta( $comment_id, 'akismet_error' );
512                        akismet_update_comment_history( $comment_id, $msg, 'cron-retry' );
513                        update_comment_meta( $comment_id, 'akismet_result', $status );
514                        // make sure the comment status is still pending.  if it isn't, that means the user has already moved it elsewhere.
515                        $comment = get_comment( $comment_id );
516                        if ( $comment && 'unapproved' == wp_get_comment_status( $comment_id ) ) {
517                                if ( $status == 'true' ) {
518                                        wp_spam_comment( $comment_id );
519                                } elseif ( $status == 'false' ) {
520                                        // comment is good, but it's still in the pending queue.  depending on the moderation settings
521                                        // we may need to change it to approved.
522                                        if ( check_comment($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent, $comment->comment_type) )
523                                                wp_set_comment_status( $comment_id, 1 );
524                                }
525                        }
526                } else {
527                        delete_comment_meta( $comment_id, 'akismet_rechecking' );
528                        wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' );
529                        return;
530                }
531        }
532       
533        $remaining = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) );
534        if ( $remaining && !wp_next_scheduled('akismet_schedule_cron_recheck') ) {
535                wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' );
536        }
537}
538add_action( 'akismet_schedule_cron_recheck', 'akismet_cron_recheck' );
539
540function akismet_add_comment_nonce( $post_id ) {
541        echo '<p style="display: none;">';
542        wp_nonce_field( 'akismet_comment_nonce_' . $post_id, 'akismet_comment_nonce', FALSE );
543        echo '</p>';
544}
545
546$akismet_comment_nonce_option = apply_filters( 'akismet_comment_nonce', get_option( 'akismet_comment_nonce' ) );
547
548if ( $akismet_comment_nonce_option == 'true' || $akismet_comment_nonce_option == '' )
549        add_action( 'comment_form', 'akismet_add_comment_nonce' );
550
551if ( '3.0.5' == $wp_version ) {
552        remove_filter( 'comment_text', 'wp_kses_data' );
553        if ( is_admin() )
554                add_filter( 'comment_text', 'wp_kses_post' );
555}
Note: See TracBrowser for help on using the repository browser.