X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/9e77185fafaf4e60e2b73821e0e4b9b1a11fb85f..784f914b1e4b1c62d6657e86397c2e83bcee4295:/wp-content/plugins/akismet/class.akismet-admin.php diff --git a/wp-content/plugins/akismet/class.akismet-admin.php b/wp-content/plugins/akismet/class.akismet-admin.php index a1c712e0..08d67701 100644 --- a/wp-content/plugins/akismet/class.akismet-admin.php +++ b/wp-content/plugins/akismet/class.akismet-admin.php @@ -4,7 +4,25 @@ class Akismet_Admin { const NONCE = 'akismet-update-key'; private static $initiated = false; - private static $notices = array(); + private static $notices = array(); + private static $allowed = array( + 'a' => array( + 'href' => true, + 'title' => true, + ), + 'b' => array(), + 'code' => array(), + 'del' => array( + 'datetime' => true, + ), + 'em' => array(), + 'i' => array(), + 'q' => array( + 'cite' => true, + ), + 'strike' => array(), + 'strong' => array(), + ); public static function init() { if ( ! self::$initiated ) { @@ -37,10 +55,10 @@ class Akismet_Admin { add_action( 'wp_ajax_akismet_recheck_queue', array( 'Akismet_Admin', 'recheck_queue' ) ); add_action( 'wp_ajax_comment_author_deurl', array( 'Akismet_Admin', 'remove_comment_author_url' ) ); add_action( 'wp_ajax_comment_author_reurl', array( 'Akismet_Admin', 'add_comment_author_url' ) ); + add_action( 'jetpack_auto_activate_akismet', array( 'Akismet_Admin', 'connect_jetpack_user' ) ); add_filter( 'plugin_action_links', array( 'Akismet_Admin', 'plugin_action_links' ), 10, 2 ); add_filter( 'comment_row_actions', array( 'Akismet_Admin', 'comment_row_action' ), 10, 2 ); - add_filter( 'comment_text', array( 'Akismet_Admin', 'text_add_link_class' ) ); add_filter( 'plugin_action_links_'.plugin_basename( plugin_dir_path( __FILE__ ) . 'akismet.php'), array( 'Akismet_Admin', 'admin_plugin_settings_link' ) ); @@ -91,11 +109,12 @@ class Akismet_Admin { 'post.php', 'settings_page_akismet-key-config', 'jetpack_page_akismet-key-config', + 'plugins.php', ) ) ) { - wp_register_style( 'akismet.css', AKISMET__PLUGIN_URL . '_inc/akismet.css', array(), AKISMET_VERSION ); + wp_register_style( 'akismet.css', plugin_dir_url( __FILE__ ) . '_inc/akismet.css', array(), AKISMET_VERSION ); wp_enqueue_style( 'akismet.css'); - wp_register_script( 'akismet.js', AKISMET__PLUGIN_URL . '_inc/akismet.js', array('jquery','postbox'), AKISMET_VERSION ); + wp_register_script( 'akismet.js', plugin_dir_url( __FILE__ ) . '_inc/akismet.js', array('jquery','postbox'), AKISMET_VERSION ); wp_enqueue_script( 'akismet.js' ); wp_localize_script( 'akismet.js', 'WPAkismet', array( 'comment_author_url_nonce' => wp_create_nonce( 'comment_author_url_nonce' ), @@ -128,8 +147,8 @@ class Akismet_Admin { 'title' => __( 'Overview' , 'akismet'), 'content' => '

' . esc_html__( 'Akismet Setup' , 'akismet') . '

' . - '

' . esc_html__( 'Akismet filters out your comment and trackback spam for you, so you can focus on more important things.' , 'akismet') . '

' . - '

' . esc_html__( 'On this page, you are able to setup the Akismet plugin.' , 'akismet') . '

', + '

' . esc_html__( 'Akismet filters out spam, so you can focus on more important things.' , 'akismet') . '

' . + '

' . esc_html__( 'On this page, you are able to set up the Akismet plugin.' , 'akismet') . '

', ) ); @@ -140,7 +159,7 @@ class Akismet_Admin { 'content' => '

' . esc_html__( 'Akismet Setup' , 'akismet') . '

' . '

' . esc_html__( 'You need to enter an API key to activate the Akismet service on your site.' , 'akismet') . '

' . - '

' . sprintf( __( 'Signup for an account on %s to get an API Key.' , 'akismet'), 'Akismet.com' ) . '

', + '

' . sprintf( __( 'Sign up for an account on %s to get an API Key.' , 'akismet'), 'Akismet.com' ) . '

', ) ); @@ -166,7 +185,7 @@ class Akismet_Admin { 'title' => __( 'Overview' , 'akismet'), 'content' => '

' . esc_html__( 'Akismet Stats' , 'akismet') . '

' . - '

' . esc_html__( 'Akismet filters out your comment and trackback spam for you, so you can focus on more important things.' , 'akismet') . '

' . + '

' . esc_html__( 'Akismet filters out spam, so you can focus on more important things.' , 'akismet') . '

' . '

' . esc_html__( 'On this page, you are able to view stats on spam filtered on your site.' , 'akismet') . '

', ) ); @@ -179,7 +198,7 @@ class Akismet_Admin { 'title' => __( 'Overview' , 'akismet'), 'content' => '

' . esc_html__( 'Akismet Configuration' , 'akismet') . '

' . - '

' . esc_html__( 'Akismet filters out your comment and trackback spam for you, so you can focus on more important things.' , 'akismet') . '

' . + '

' . esc_html__( 'Akismet filters out spam, so you can focus on more important things.' , 'akismet') . '

' . '

' . esc_html__( 'On this page, you are able to enter/remove an API key, view account information and view spam stats.' , 'akismet') . '

', ) ); @@ -231,7 +250,7 @@ class Akismet_Admin { if ( defined( 'WPCOM_API_KEY' ) ) return false; //shouldn't have option to save key if already defined - $new_key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] ); + $new_key = preg_replace( '/[^a-f0-9]/i', '', $_POST['key'] ); $old_key = Akismet::get_api_key(); if ( empty( $new_key ) ) { @@ -257,8 +276,10 @@ class Akismet_Admin { if ( in_array( $akismet_user->status, array( 'active', 'active-dunning', 'no-sub' ) ) ) update_option( 'wordpress_api_key', $api_key ); - if ( $akismet_user->status == 'active' ) + if ( $akismet_user->status == 'active' ) self::$notices['status'] = 'new-key-valid'; + elseif ( $akismet_user->status == 'notice' ) + self::$notices['status'] = $akismet_user; else self::$notices['status'] = $akismet_user->status; } @@ -289,15 +310,6 @@ class Akismet_Admin { // WP 2.5+ public static function rightnow_stats() { - global $submenu, $wp_db_version; - - if ( 8645 < $wp_db_version ) // 2.7 - $link = add_query_arg( array( 'comment_status' => 'spam' ), admin_url( 'edit-comments.php' ) ); - elseif ( isset( $submenu['edit-comments.php'] ) ) - $link = add_query_arg( array( 'page' => 'akismet-admin' ), admin_url( 'edit-comments.php' ) ); - else - $link = add_query_arg( array( 'page' => 'akismet-admin' ), admin_url( 'edit.php' ) ); - if ( $count = get_option('akismet_spam_count') ) { $intro = sprintf( _n( 'Akismet has protected your site from %2$s spam comment already. ', @@ -308,15 +320,16 @@ class Akismet_Admin { $intro = sprintf( __('Akismet blocks spam from getting to your blog. ', 'akismet'), 'https://akismet.com/wordpress/' ); } - $link = function_exists( 'esc_url' ) ? esc_url( $link ) : clean_url( $link ); + $link = add_query_arg( array( 'comment_status' => 'spam' ), admin_url( 'edit-comments.php' ) ); + if ( $queue_count = self::get_spam_count() ) { $queue_text = sprintf( _n( 'There’s %1$s comment in your spam queue right now.', 'There are %1$s comments in your spam queue right now.', $queue_count - , 'akismet'), number_format_i18n( $queue_count ), $link ); + , 'akismet'), number_format_i18n( $queue_count ), esc_url( $link ) ); } else { - $queue_text = sprintf( __( "There’s nothing in your spam queue at the moment." , 'akismet'), $link ); + $queue_text = sprintf( __( "There’s nothing in your spam queue at the moment." , 'akismet'), esc_url( $link ) ); } $text = $intro . '
' . $queue_text; @@ -324,8 +337,12 @@ class Akismet_Admin { } public static function check_for_spam_button( $comment_status ) { - if ( 'approved' == $comment_status ) + // The "Check for Spam" button should only appear when the page might be showing + // a comment with comment_approved=0, which means an un-trashed, un-spammed, + // not-yet-moderated comment. + if ( 'all' != $comment_status && 'moderated' != $comment_status ) { return; + } if ( function_exists('plugins_url') ) $link = add_query_arg( array( 'action' => 'akismet_recheck_queue' ), admin_url( 'admin.php' ) ); @@ -374,17 +391,22 @@ class Akismet_Admin { update_comment_meta( $c['comment_ID'], 'akismet_result', 'true' ); delete_comment_meta( $c['comment_ID'], 'akismet_error' ); delete_comment_meta( $c['comment_ID'], 'akismet_delayed_moderation_email' ); - Akismet::update_comment_history( $c['comment_ID'], __('Akismet re-checked and caught this comment as spam', 'akismet'), 'check-spam' ); + Akismet::update_comment_history( $c['comment_ID'], '', 'recheck-spam' ); } elseif ( 'false' == $response[1] ) { update_comment_meta( $c['comment_ID'], 'akismet_result', 'false' ); delete_comment_meta( $c['comment_ID'], 'akismet_error' ); delete_comment_meta( $c['comment_ID'], 'akismet_delayed_moderation_email' ); - Akismet::update_comment_history( $c['comment_ID'], __('Akismet re-checked and cleared this comment', 'akismet'), 'check-ham' ); + Akismet::update_comment_history( $c['comment_ID'], '', 'recheck-ham' ); // abnormal result: error } else { update_comment_meta( $c['comment_ID'], 'akismet_result', 'error' ); - Akismet::update_comment_history( $c['comment_ID'], sprintf( __('Akismet was unable to re-check this comment (response: %s)', 'akismet'), substr($response[1], 0, 50)), 'check-error' ); + Akismet::update_comment_history( + $c['comment_ID'], + '', + 'recheck-error', + array( 'response' => substr( $response[1], 0, 50 ) ) + ); } delete_comment_meta( $c['comment_ID'], 'akismet_rechecking' ); @@ -489,35 +511,107 @@ class Akismet_Admin { if ( $history ) { echo '
'; + foreach ( $history as $row ) { $time = date( 'D d M Y @ h:i:m a', $row['time'] ) . ' GMT'; - echo '
' . sprintf( esc_html__('%s ago', 'akismet'), human_time_diff( $row['time'] ) ) . ' - '; - echo esc_html( $row['message'] ) . '
'; + + $message = ''; + + if ( ! empty( $row['message'] ) ) { + // Old versions of Akismet stored the message as a literal string in the commentmeta. + // New versions don't do that for two reasons: + // 1) Save space. + // 2) The message can be translated into the current language of the blog, not stuck + // in the language of the blog when the comment was made. + $message = $row['message']; + } + + // If possible, use a current translation. + switch ( $row['event'] ) { + case 'recheck-spam'; + $message = __( 'Akismet re-checked and caught this comment as spam.', 'akismet' ); + break; + case 'check-spam': + $message = __( 'Akismet caught this comment as spam.', 'akismet' ); + break; + case 'recheck-ham': + $message = __( 'Akismet re-checked and cleared this comment.', 'akismet' ); + break; + case 'check-ham': + $message = __( 'Akismet cleared this comment.', 'akismet' ); + break; + case 'wp-blacklisted': + $message = __( 'Comment was caught by wp_blacklist_check.', 'akismet' ); + break; + case 'report-spam': + if ( isset( $row['user'] ) ) { + $message = sprintf( __( '%s reported this comment as spam.', 'akismet' ), $row['user'] ); + } + else if ( ! $message ) { + $message = __( 'This comment was reported as spam.', 'akismet' ); + } + break; + case 'report-ham': + if ( isset( $row['user'] ) ) { + $message = sprintf( __( '%s reported this comment as not spam.', 'akismet' ), $row['user'] ); + } + else if ( ! $message ) { + $message = __( 'This comment was reported as not spam.', 'akismet' ); + } + break; + case 'cron-retry-spam': + $message = __( 'Akismet caught this comment as spam during an automatic retry.' , 'akismet'); + break; + case 'cron-retry-ham': + $message = __( 'Akismet cleared this comment during an automatic retry.', 'akismet'); + break; + case 'check-error': + if ( isset( $row['meta'], $row['meta']['response'] ) ) { + $message = sprintf( __( 'Akismet was unable to check this comment (response: %s) but will automatically retry later.', 'akismet'), $row['meta']['response'] ); + } + break; + case 'recheck-error': + if ( isset( $row['meta'], $row['meta']['response'] ) ) { + $message = sprintf( __( 'Akismet was unable to recheck this comment (response: %s).', 'akismet'), $row['meta']['response'] ); + } + break; + default: + if ( preg_match( '/^status-changed/', $row['event'] ) ) { + // Half of these used to be saved without the dash after 'status-changed'. + // See https://plugins.trac.wordpress.org/changeset/1150658/akismet/trunk + $new_status = preg_replace( '/^status-changed-?/', '', $row['event'] ); + $message = sprintf( __( 'Comment status was changed to %s', 'akismet' ), $new_status ); + } + else if ( preg_match( '/^status-/', $row['event'] ) ) { + $new_status = preg_replace( '/^status-/', '', $row['event'] ); + + if ( isset( $row['user'] ) ) { + $message = sprintf( __( '%1$s changed the comment status to %2$s.', 'akismet' ), $row['user'], $new_status ); + } + } + break; + + } + + echo '
'; + echo '' . sprintf( esc_html__('%s ago', 'akismet'), human_time_diff( $row['time'] ) ) . ''; + echo ' - '; + echo esc_html( $message ); + echo '
'; } + echo '
'; } } public static function plugin_action_links( $links, $file ) { - if ( $file == plugin_basename( AKISMET__PLUGIN_URL . '/akismet.php' ) ) { + if ( $file == plugin_basename( plugin_dir_url( __FILE__ ) . '/akismet.php' ) ) { $links[] = ''.esc_html__( 'Settings' , 'akismet').''; } return $links; } - public static function text_add_link_callback( $m ) { - // bare link? - if ( $m[4] == $m[2] ) - return ''.$m[4].''; - else - return ''.$m[4].''; - } - - public static function text_add_link_class( $comment_text ) { - return preg_replace_callback( '#]*)href="([^"]+)"([^>]*)>(.*?)#i', array( 'Akismet_Admin', 'text_add_link_callback' ), $comment_text ); - } - // Total spam in queue // get_option( 'akismet_spam_count' ) is the total caught ever public static function get_spam_count( $type = false ) { @@ -626,13 +720,16 @@ class Akismet_Admin { } public static function get_akismet_user( $api_key ) { - $akismet_user = Akismet::http_post( Akismet::build_query( array( 'key' => $api_key ) ), 'get-subscription' ); + $akismet_user = false; + + $subscription_verification = Akismet::http_post( Akismet::build_query( array( 'key' => $api_key, 'blog' => get_bloginfo( 'url' ) ) ), 'get-subscription' ); + + if ( ! empty( $subscription_verification[1] ) ) { + if ( 'invalid' !== $subscription_verification[1] ) { + $akismet_user = json_decode( $subscription_verification[1] ); + } + } - if ( ! empty( $akismet_user[1] ) ) - $akismet_user = json_decode( $akismet_user[1] ); - else - $akismet_user = false; - return $akismet_user; } @@ -640,22 +737,22 @@ class Akismet_Admin { $stat_totals = array(); foreach( array( '6-months', 'all' ) as $interval ) { - $response = Akismet::http_post( Akismet::build_query( array( 'blog' => urlencode( get_bloginfo('url') ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' ); + $response = Akismet::http_post( Akismet::build_query( array( 'blog' => get_bloginfo( 'url' ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' ); if ( ! empty( $response[1] ) ) { $stat_totals[$interval] = json_decode( $response[1] ); } } + return $stat_totals; } - public static function verify_wpcom_key( $api_key, $user_id, $token = '' ) { - $akismet_account = Akismet::http_post( Akismet::build_query( array( + public static function verify_wpcom_key( $api_key, $user_id, $extra = array() ) { + $akismet_account = Akismet::http_post( Akismet::build_query( array_merge( array( 'user_id' => $user_id, 'api_key' => $api_key, - 'token' => $token, 'get_account_type' => 'true' - ) ), 'verify-wpcom-key' ); + ), $extra ) ), 'verify-wpcom-key' ); if ( ! empty( $akismet_account[1] ) ) $akismet_account = json_decode( $akismet_account[1] ); @@ -664,6 +761,22 @@ class Akismet_Admin { return $akismet_account; } + + public static function connect_jetpack_user() { + + if ( $jetpack_user = self::get_jetpack_user() ) { + if ( isset( $jetpack_user['user_id'] ) && isset( $jetpack_user['api_key'] ) ) { + $akismet_user = self::verify_wpcom_key( $jetpack_user['api_key'], $jetpack_user['user_id'], array( 'action' => 'connect_jetpack_user' ) ); + + if ( is_object( $akismet_user ) ) { + self::save_key( $akismet_user->api_key ); + return in_array( $akismet_user->status, array( 'active', 'active-dunning', 'no-sub' ) ); + } + } + } + + return false; + } public static function display_alert() { Akismet::view( 'notice', array( @@ -707,7 +820,7 @@ class Akismet_Admin { } } - if ( $api_key = Akismet::get_api_key() ) { + if ( $api_key = Akismet::get_api_key() && ( empty( self::$notices['status'] ) || 'existing-key-invalid' != self::$notices['status'] ) ) { self::display_configuration_page(); return; } @@ -719,7 +832,7 @@ class Akismet_Admin { $akismet_user = false; if ( isset( $_GET['token'] ) && preg_match('/^(\d+)-[0-9a-f]{20}$/', $_GET['token'] ) ) - $akismet_user = self::verify_wpcom_key( '', '', $_GET['token'] ); + $akismet_user = self::verify_wpcom_key( '', '', array( 'token' => $_GET['token'] ) ); elseif ( $jetpack_user = self::get_jetpack_user() ) $akismet_user = self::verify_wpcom_key( $jetpack_user['api_key'], $jetpack_user['user_id'] ); @@ -748,8 +861,16 @@ class Akismet_Admin { public static function display_configuration_page() { $api_key = Akismet::get_api_key(); $akismet_user = self::get_akismet_user( $api_key ); - $stat_totals = self::get_stats( $api_key ); + if ( ! $akismet_user ) { + // This could happen if the user's key became invalid after it was previously valid and successfully set up. + self::$notices['status'] = 'existing-key-invalid'; + self::display_start_page(); + return; + } + + $stat_totals = self::get_stats( $api_key ); + // If unset, create the new strictness option using the old discard option to determine its default if ( get_option( 'akismet_strictness' ) === false ) add_option( 'akismet_strictness', (get_option('akismet_discard_month') === 'true' ? '1' : '0') ); @@ -767,11 +888,11 @@ class Akismet_Admin { $cleaning_up = __( 'Cleaning up spam takes time.' , 'akismet'); if ( $total_in_days > 1 ) - $time_saved = $cleaning_up . ' ' . sprintf( __( 'Since you joined us, Akismet has saved you %s days!' , 'akismet'), number_format_i18n( $total_in_days ) ); + $time_saved = $cleaning_up . ' ' . sprintf( _n( 'Akismet has saved you %s day!', 'Akismet has saved you %s days!', $total_in_days, 'akismet' ), number_format_i18n( $total_in_days ) ); elseif ( $total_in_hours > 1 ) - $time_saved = $cleaning_up . ' ' . sprintf( __( 'Since you joined us, Akismet has saved you %d hours!' , 'akismet'), $total_in_hours ); + $time_saved = $cleaning_up . ' ' . sprintf( _n( 'Akismet has saved you %d hour!', 'Akismet has saved you %d hours!', $total_in_hours, 'akismet' ), $total_in_hours ); elseif ( $total_in_minutes >= 30 ) - $time_saved = $cleaning_up . ' ' . sprintf( __( 'Since you joined us, Akismet has saved you %d minutes!' , 'akismet'), $total_in_minutes ); + $time_saved = $cleaning_up . ' ' . sprintf( _n( 'Akismet has saved you %d minute!', 'Akismet has saved you %d minutes!', $total_in_minutes, 'akismet' ), $total_in_minutes ); } Akismet::view( 'notice', array( 'type' => 'active-notice', 'time_saved' => $time_saved ) ); @@ -793,7 +914,10 @@ class Akismet_Admin { global $hook_suffix; if ( in_array( $hook_suffix, array( 'jetpack_page_akismet-key-config', 'settings_page_akismet-key-config', 'edit-comments.php' ) ) && (int) get_option( 'akismet_alert_code' ) > 0 ) { - self::display_alert(); + Akismet::verify_key( Akismet::get_api_key() ); //verify that the key is still in alert state + + if ( get_option( 'akismet_alert_code' ) > 0 ) + self::display_alert(); } elseif ( $hook_suffix == 'plugins.php' && !Akismet::get_api_key() ) { self::display_api_key_warning(); @@ -815,8 +939,24 @@ class Akismet_Admin { if ( !empty( $type ) ) Akismet::view( 'notice', compact( 'type' ) ); elseif ( !empty( self::$notices ) ) { - foreach ( self::$notices as $type ) - Akismet::view( 'notice', compact( 'type' ) ); + foreach ( self::$notices as $type ) { + if ( is_object( $type ) ) { + $notice_header = $notice_text = ''; + + if ( property_exists( $type, 'notice_header' ) ) + $notice_header = wp_kses( $type->notice_header, self::$allowed ); + + if ( property_exists( $type, 'notice_text' ) ) + $notice_text = wp_kses( $type->notice_text, self::$allowed ); + + if ( property_exists( $type, 'status' ) ) { + $type = wp_kses( $type->status, self::$allowed ); + Akismet::view( 'notice', compact( 'type', 'notice_header', 'notice_text' ) ); + } + } + else + Akismet::view( 'notice', compact( 'type' ) ); + } } }