<body>
<h1 id="logo">
<a href="https://wordpress.org/"><img alt="WordPress" src="wp-admin/images/wordpress-logo.png" /></a>
- <br /> Version 3.9.1
+ <br /> Version 3.9.2
</h1>
<p style="text-align: center">Semantic Personal Publishing Platform</p>
</h2>
<div class="changelog point-releases">
- <h3><?php echo _n( 'Maintenance Release', 'Maintenance Releases', 1 ); ?></h3>
+ <h3><?php echo _n( 'Maintenance and Security Release', 'Maintenance and Security Releases', 2 ); ?></h3>
+ <p><?php printf( _n( '<strong>Version %1$s</strong> addressed a security issue.',
+ '<strong>Version %1$s</strong> addressed some security issues.', 6 ), '3.9.2', number_format_i18n( 6 ) ); ?>
+ <?php printf( __( 'For more information, see <a href="%s">the release notes</a>.' ), 'http://codex.wordpress.org/Version_3.9.2' ); ?>
+ </p>
<p><?php printf( _n( '<strong>Version %1$s</strong> addressed %2$s bug.',
'<strong>Version %1$s</strong> addressed %2$s bugs.', 34 ), '3.9.1', number_format_i18n( 34 ) ); ?>
<?php printf( __( 'For more information, see <a href="%s">the release notes</a>.' ), 'http://codex.wordpress.org/Version_3.9.1' ); ?>
--- /dev/null
+Order Deny,Allow
+Deny from all
+
+<FilesMatch "^(form|akismet)\.(css|js)$">
+ Allow from all
+</FilesMatch>
+
+#allow access to any image
+<FilesMatch "^(.+)\.(png|gif)$">
+ Allow from all
+</FilesMatch>
\ No newline at end of file
display: inline-block !important;
}
.checkforspam-spinner {
- display: none;
- margin-top: 10px;
+ display: inline-block;
+ margin-top: 7px;
}
.config-wrap {
});
$('.checkforspam:not(.button-disabled)').click( function(e) {
$('.checkforspam:not(.button-disabled)').addClass('button-disabled');
- $('.checkforspam-spinner').show();
+ $('.checkforspam-spinner').addClass( 'spinner' );
akismet_check_for_spam(0, 100);
e.preventDefault();
});
-jQuery( function ( $ ) {
- var ak_js = $( '#ak_js' );
+var ak_js = document.getElementById( "ak_js" );
- // If the form field already exists just use that
- if ( ak_js.length == 0 ) {
- ak_js = $( '<input type="hidden" id="ak_js" name="ak_js" />' );
- }
- else {
- ak_js.remove();
- }
+if ( ! ak_js ) {
+ ak_js = document.createElement( 'input' );
+ ak_js.setAttribute( 'id', 'ak_js' );
+ ak_js.setAttribute( 'name', 'ak_js' );
+ ak_js.setAttribute( 'type', 'hidden' );
+}
+else {
+ ak_js.parentNode.removeChild( ak_js );
+}
+
+ak_js.setAttribute( 'value', ( new Date() ).getTime() );
- ak_js.val( ( new Date() ).getTime() );
+var commentForm = document.getElementById( 'commentform' );
- // single page, front-end comment form
- // inline comment reply, wp-admin
- $( '#commentform, #replyrow td:first' ).append( ak_js );
-} );
+if ( commentForm ) {
+ commentForm.appendChild( ak_js );
+}
+else {
+ var replyRowContainer = document.getElementById( 'replyrow' );
+
+ if ( replyRowContainer ) {
+ var children = replyRowContainer.getElementsByTagName( 'td' );
+
+ if ( children.length > 0 ) {
+ children[0].appendChild( ak_js );
+ }
+ }
+}
\ No newline at end of file
Plugin Name: Akismet
Plugin URI: http://akismet.com/
Description: 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/">Sign up for an Akismet API key</a>, and 3) Go to your Akismet configuration page, and save your API key.
-Version: 3.0.0
+Version: 3.0.1
Author: Automattic
Author URI: http://automattic.com/wordpress-plugins/
License: GPLv2 or later
exit;
}
-define( 'AKISMET_VERSION', '3.0.0' );
-define( 'AKISMET__MINIMUM_WP_VERSION', '3.0' );
+define( 'AKISMET_VERSION', '3.0.1' );
+define( 'AKISMET__MINIMUM_WP_VERSION', '3.1' );
define( 'AKISMET__PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'AKISMET_DELETE_LIMIT', 100000 );
add_action( 'activity_box_end', array( 'Akismet_Admin', 'dashboard_stats' ) );
add_action( 'rightnow_end', array( 'Akismet_Admin', 'rightnow_stats' ) );
add_action( 'manage_comments_nav', array( 'Akismet_Admin', 'check_for_spam_button' ) );
- add_action( 'transition_comment_status', array( 'Akismet_Admin', 'transition_comment_status' ), 10, 3 );
add_action( 'admin_action_akismet_recheck_queue', array( 'Akismet_Admin', 'recheck_queue' ) );
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_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' ) );
+
+ add_filter( 'wxr_export_skip_commentmeta', array( 'Akismet_Admin', 'exclude_commentmeta_from_export' ), 10, 3 );
}
public static function admin_init() {
}
public static function admin_plugin_settings_link( $links ) {
- $settings_link = '<a href="'.self::get_page_url().'">'.__('Settings', 'akismet').'</a>';
+ $settings_link = '<a href="'.esc_url( self::get_page_url() ).'">'.__('Settings', 'akismet').'</a>';
array_unshift( $links, $settings_link );
return $links;
}
else
$link = add_query_arg( array( 'page' => 'akismet-admin', 'recheckqueue' => 'true', 'noheader' => 'true' ), admin_url( 'edit-comments.php' ) );
- echo '</div><div class="alignleft"><a class="button-secondary checkforspam" href="' . esc_url( $link ) . '">' . esc_html__('Check for Spam', 'akismet') . '</a>';
- echo '<img src="' . esc_url( admin_url( 'images/wpspin_light.gif' ) ) . '" class="checkforspam-spinner" />';
- }
-
- public static function transition_comment_status( $new_status, $old_status, $comment ) {
- if ( $new_status == $old_status )
- return;
-
- # we don't need to record a history item for deleted comments
- if ( $new_status == 'delete' )
- return;
-
- if ( !is_admin() )
- return;
-
- if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) )
- return;
-
- if ( defined('WP_IMPORTING') && WP_IMPORTING == true )
- return;
-
- // if this is present, it means the status has been changed by a re-check, not an explicit user action
- if ( get_comment_meta( $comment->comment_ID, 'akismet_rechecking' ) )
- return;
-
- global $current_user;
- $reporter = '';
- if ( is_object( $current_user ) )
- $reporter = $current_user->user_login;
-
- // Assumption alert:
- // We want to submit comments to Akismet only when a moderator explicitly spams or approves it - not if the status
- // is changed automatically by another plugin. Unfortunately WordPress doesn't provide an unambiguous way to
- // determine why the transition_comment_status action was triggered. And there are several different ways by which
- // to spam and unspam comments: bulk actions, ajax, links in moderation emails, the dashboard, and perhaps others.
- // We'll assume that this is an explicit user action if POST or GET has an 'action' key.
- if ( isset($_POST['action']) || isset($_GET['action']) ) {
- if ( $new_status == 'spam' && ( $old_status == 'approved' || $old_status == 'unapproved' || !$old_status ) ) {
- return self::submit_spam_comment( $comment->comment_ID );
- } elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) {
- return self::submit_nonspam_comment( $comment->comment_ID );
- }
- }
-
- Akismet::update_comment_history( $comment->comment_ID, sprintf( __('%1$s changed the comment status to %2$s', 'akismet'), $reporter, $new_status ), 'status-' . $new_status );
+ echo '</div><div class="alignleft"><a class="button-secondary checkforspam" href="' . esc_url( $link ) . '">' . esc_html__('Check for Spam', 'akismet') . '</a><span class="checkforspam-spinner"></span>';
}
public static function recheck_queue() {
add_comment_meta( $c['comment_ID'], 'akismet_rechecking', true );
- $response = Akismet::http_post( http_build_query( $c ), 'comment-check' );
+ $response = Akismet::http_post( build_query( $c ), 'comment-check' );
if ( 'true' == $response[1] ) {
wp_set_comment_status( $c['comment_ID'], 'spam' );
update_comment_meta( $c['comment_ID'], 'akismet_result', 'true' );
if ( $desc )
echo '<span class="akismet-status" commentid="'.$comment->comment_ID.'"><a href="comment.php?action=editcomment&c='.$comment->comment_ID.'#akismet-status" title="' . esc_attr__( 'View comment history' , 'akismet') . '">'.esc_html( $desc ).'</a></span>';
- if ( apply_filters( 'akismet_show_user_comments_approved', get_option('akismet_show_user_comments_approved') ) ) {
+ $show_user_comments = apply_filters( 'akismet_show_user_comments_approved', get_option('akismet_show_user_comments_approved') );
+ $show_user_comments = $show_user_comments === 'false' ? false : $show_user_comments; //option used to be saved as 'false' / 'true'
+
+ if ( $show_user_comments ) {
$comment_count = Akismet::get_user_comments_approved( $comment->user_id, $comment->comment_author_email, $comment->comment_author, $comment->comment_author_url );
$comment_count = intval( $comment_count );
echo '<span class="akismet-user-comment-count" commentid="'.$comment->comment_ID.'" style="display:none;"><br><span class="akismet-user-comment-counts">'. sprintf( esc_html( _n( '%s approved', '%s approved', $comment_count , 'akismet') ), number_format_i18n( $comment_count ) ) . '</span></span>';
return preg_replace_callback( '#<a ([^>]*)href="([^"]+)"([^>]*)>(.*?)</a>#i', array( 'Akismet_Admin', 'text_add_link_callback' ), $comment_text );
}
- public static function submit_spam_comment( $comment_id ) {
- global $wpdb, $current_user, $current_site;
-
- $comment_id = (int) $comment_id;
-
- $comment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_ID = %d", $comment_id ) );
-
- if ( !$comment ) // it was deleted
- return;
-
- if ( 'spam' != $comment->comment_approved )
- return;
-
- // use the original version stored in comment_meta if available
- $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
-
- if ( $as_submitted && is_array( $as_submitted ) && isset( $as_submitted['comment_content'] ) )
- $comment = (object) array_merge( (array)$comment, $as_submitted );
-
- $comment->blog = get_bloginfo('url');
- $comment->blog_lang = get_locale();
- $comment->blog_charset = get_option('blog_charset');
- $comment->permalink = get_permalink($comment->comment_post_ID);
-
- if ( is_object($current_user) )
- $comment->reporter = $current_user->user_login;
-
- if ( is_object($current_site) )
- $comment->site_domain = $current_site->domain;
-
- $comment->user_role = '';
- if ( isset( $comment->user_ID ) )
- $comment->user_role = Akismet::get_user_roles( $comment->user_ID );
-
- if ( Akismet::is_test_mode() )
- $comment->is_test = 'true';
-
- $post = get_post( $comment->comment_post_ID );
- $comment->comment_post_modified_gmt = $post->post_modified_gmt;
-
- $response = Akismet::http_post( http_build_query( $comment ), 'submit-spam' );
- if ( $comment->reporter ) {
- Akismet::update_comment_history( $comment_id, sprintf( __('%s reported this comment as spam', 'akismet'), $comment->reporter ), 'report-spam' );
- update_comment_meta( $comment_id, 'akismet_user_result', 'true' );
- update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
- }
-
- do_action('akismet_submit_spam_comment', $comment_id, $response[1]);
- }
-
- public static function submit_nonspam_comment( $comment_id ) {
- global $wpdb, $current_user, $current_site;
-
- $comment_id = (int) $comment_id;
-
- $comment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_ID = %d", $comment_id ) );
- if ( !$comment ) // it was deleted
- return;
-
- // use the original version stored in comment_meta if available
- $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
-
- if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) )
- $comment = (object) array_merge( (array)$comment, $as_submitted );
-
- $comment->blog = get_bloginfo('url');
- $comment->blog_lang = get_locale();
- $comment->blog_charset = get_option('blog_charset');
- $comment->permalink = get_permalink( $comment->comment_post_ID );
- $comment->user_role = '';
-
- if ( is_object($current_user) )
- $comment->reporter = $current_user->user_login;
-
- if ( is_object($current_site) )
- $comment->site_domain = $current_site->domain;
-
- if ( isset( $comment->user_ID ) )
- $comment->user_role = Akismet::get_user_roles($comment->user_ID);
-
- if ( Akismet::is_test_mode() )
- $comment->is_test = 'true';
-
- $post = get_post( $comment->comment_post_ID );
- $comment->comment_post_modified_gmt = $post->post_modified_gmt;
-
- $response = Akismet::http_post( http_build_query( $comment ), 'submit-ham' );
- if ( $comment->reporter ) {
- Akismet::update_comment_history( $comment_id, sprintf( __('%s reported this comment as not spam', 'akismet'), $comment->reporter ), 'report-ham' );
- update_comment_meta( $comment_id, 'akismet_user_result', 'false' );
- update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
- }
-
- do_action('akismet_submit_nonspam_comment', $comment_id, $response[1]);
- }
-
// Total spam in queue
// get_option( 'akismet_spam_count' ) is the total caught ever
public static function get_spam_count( $type = false ) {
return $count;
} elseif ( 'comments' == $type || 'comment' == $type ) { // comments
$type = '';
- } else { // pingback, trackback, ...
- $type = $wpdb->escape( $type );
}
- return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE comment_approved = 'spam' AND comment_type='$type'");
+ return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE comment_approved = 'spam' AND comment_type = %s", $type ) );
}
// Check connectivity between the WordPress blog and Akismet's servers.
// 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).
- public static function check_server_connectivity() {
- $test_host = 'rest.akismet.com';
-
- // Some web hosts may disable one or both functions
- if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') )
- return array();
-
- $ips = gethostbynamel( $test_host );
- if ( !$ips || !is_array($ips) || !count($ips) )
- return array();
-
- $api_key = Akismet::get_api_key();
+ public static function check_server_ip_connectivity() {
+
+ $servers = $ips = array();
- $servers = array();
- foreach ( $ips as $ip ) {
- $response = Akismet::verify_key( $api_key, $ip );
- // even if the key is invalid, at least we know we have connectivity
- if ( $response == 'valid' || $response == 'invalid' )
- $servers[$ip] = true;
- else
- $servers[$ip] = false;
+ // Some web hosts may disable this function
+ if ( function_exists('gethostbynamel') ) {
+
+ $ips = gethostbynamel( 'rest.akismet.com' );
+ if ( $ips && is_array($ips) && count($ips) ) {
+ $api_key = Akismet::get_api_key();
+
+ foreach ( $ips as $ip ) {
+ $response = Akismet::verify_key( $api_key, $ip );
+ // even if the key is invalid, at least we know we have connectivity
+ if ( $response == 'valid' || $response == 'invalid' )
+ $servers[$ip] = 'connected';
+ else
+ $servers[$ip] = $response ? $response : 'unable to connect';
+ }
+ }
}
+
return $servers;
}
-
- // Check the server connectivity and store the results in an option.
- // Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update.
- // Returns the same associative array as check_server_connectivity()
- public static function get_server_connectivity( $cache_timeout = 86400 ) {
+
+ // Simpler connectivity check
+ public static function check_server_connectivity($cache_timeout = 86400) {
+
+ $debug = array();
+ $debug[ 'PHP_VERSION' ] = PHP_VERSION;
+ $debug[ 'WORDPRESS_VERSION' ] = $GLOBALS['wp_version'];
+ $debug[ 'AKISMET_VERSION' ] = AKISMET_VERSION;
+ $debug[ 'AKISMET__PLUGIN_DIR' ] = AKISMET__PLUGIN_DIR;
+ $debug[ 'SITE_URL' ] = site_url();
+ $debug[ 'HOME_URL' ] = home_url();
+
$servers = get_option('akismet_available_servers');
- if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false )
- return $servers;
+ if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false ) {
+ $servers = self::check_server_ip_connectivity();
+ update_option('akismet_available_servers', $servers);
+ update_option('akismet_connectivity_time', time());
+ }
+
+ $response = wp_remote_get( 'http://rest.akismet.com/1.1/test' );
+
+ $debug[ 'gethostbynamel' ] = function_exists('gethostbynamel') ? 'exists' : 'not here';
+ $debug[ 'Servers' ] = $servers;
+ $debug[ 'Test Connection' ] = $response;
+
+ Akismet::log( $debug );
+
+ if ( $response && 'connected' == wp_remote_retrieve_body( $response ) )
+ return true;
+
+ return false;
+ }
- // There's a race condition here but the effect is harmless.
- $servers = self::check_server_connectivity();
- update_option('akismet_available_servers', $servers);
- update_option('akismet_connectivity_time', time());
- return $servers;
+ // Check the server connectivity and store the available servers in an option.
+ public static function get_server_connectivity($cache_timeout = 86400) {
+ return self::check_server_connectivity( $cache_timeout );
}
public static function get_number_spam_waiting() {
}
public static function get_akismet_user( $api_key ) {
- $akismet_user = Akismet::http_post( http_build_query( array( 'key' => $api_key ) ), 'get-subscription' );
+ $akismet_user = Akismet::http_post( build_query( array( 'key' => $api_key ) ), 'get-subscription' );
if ( ! empty( $akismet_user[1] ) )
$akismet_user = json_decode( $akismet_user[1] );
$stat_totals = array();
foreach( array( '6-months', 'all' ) as $interval ) {
- $response = Akismet::http_post( http_build_query( array( 'blog' => urlencode( get_bloginfo('url') ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' );
+ $response = Akismet::http_post( build_query( array( 'blog' => urlencode( get_bloginfo('url') ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' );
if ( ! empty( $response[1] ) ) {
$stat_totals[$interval] = json_decode( $response[1] );
}
public static function verify_wpcom_key( $api_key, $user_id, $token = '' ) {
- $akismet_account = Akismet::http_post( http_build_query( array(
+ $akismet_account = Akismet::http_post( build_query( array(
'user_id' => $user_id,
'api_key' => $api_key,
'token' => $token,
public static function display_spam_check_warning() {
Akismet::fix_scheduled_recheck();
+
+ $link_text = apply_filters( 'akismet_spam_check_warning_link_text', sprintf( __( 'Please check your <a href="%s">Akismet configuration</a> and contact your web host if problems persist.', 'akismet'), esc_url( self::get_page_url() ) ) );
if ( self::get_number_spam_waiting() > 0 && wp_next_scheduled('akismet_schedule_cron_recheck') > time() )
- Akismet::view( 'notice', array( 'type' => 'spam-check' ) );
+ Akismet::view( 'notice', array( 'type' => 'spam-check', 'link_text' => $link_text ) );
}
public static function display_invalid_version() {
if ( empty( self::$notices ) ) {
//show status
- if ( $akismet_user->status == 'active' && $akismet_user->account_type == 'free-api-key' ) {
+ if ( ! empty( $stat_totals['all'] ) && isset( $stat_totals['all']->time_saved ) && $akismet_user->status == 'active' && $akismet_user->account_type == 'free-api-key' ) {
$time_saved = false;
}
public static function display_status() {
- $servers = self::get_server_connectivity();
- $fail_count = count( $servers ) - count( array_filter( $servers ) );
- $type = '';
+ $type = '';
- if ( empty( $servers ) || $fail_count > 0 )
+ if ( !self::get_server_connectivity() )
$type = 'servers-be-down';
- if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') )
- $type = 'missing-functions';
-
if ( !empty( $type ) )
Akismet::view( 'notice', compact( 'type' ) );
elseif ( !empty( self::$notices ) ) {
}
return false;
}
+
+ /**
+ * Some commentmeta isn't useful in an export file. Suppress it (when supported).
+ *
+ * @param bool $exclude
+ * @param string $key The meta key
+ * @param object $meta The meta object
+ * @return bool Whether to exclude this meta entry from the export.
+ */
+ public static function exclude_commentmeta_from_export( $exclude, $key, $meta ) {
+ if ( in_array( $key, array( 'akismet_as_submitted', 'akismet_rechecking', 'akismet_delayed_moderation_email' ) ) ) {
+ return true;
+ }
+
+ return $exclude;
+ }
}
\ No newline at end of file
if ( $akismet_comment_nonce_option == 'true' || $akismet_comment_nonce_option == '' )
add_action( 'comment_form', array( 'Akismet', 'add_comment_nonce' ), 1 );
- add_action( 'admin_footer-edit-comments.php', array( 'Akismet', 'load_form_js' ) );
+ add_action( 'admin_head-edit-comments.php', array( 'Akismet', 'load_form_js' ) );
add_action( 'comment_form', array( 'Akismet', 'load_form_js' ) );
add_action( 'comment_form', array( 'Akismet', 'inject_ak_js' ) );
add_filter( 'comment_moderation_recipients', array( 'Akismet', 'disable_moderation_emails_if_unreachable' ), 1000, 2 );
add_filter( 'pre_comment_approved', array( 'Akismet', 'last_comment_status' ), 10, 2 );
+
+ add_action( 'transition_comment_status', array( 'Akismet', 'transition_comment_status' ), 10, 3 );
if ( '3.0.5' == $GLOBALS['wp_version'] ) {
remove_filter( 'comment_text', 'wp_kses_data' );
}
public static function get_api_key() {
- return defined('WPCOM_API_KEY') ? constant('WPCOM_API_KEY') : get_option('wordpress_api_key');
+ return apply_filters( 'akismet_get_api_key', defined('WPCOM_API_KEY') ? constant('WPCOM_API_KEY') : get_option('wordpress_api_key') );
}
public static function check_key_status( $key, $ip = null ) {
- return self::http_post( http_build_query( array( 'key' => $key, 'blog' => get_option('home') ) ), 'verify-key', $ip );
+ return self::http_post( build_query( array( 'key' => $key, 'blog' => get_option('home') ) ), 'verify-key', $ip );
}
public static function verify_key( $key, $ip = null ) {
$post = get_post( $comment['comment_post_ID'] );
$comment[ 'comment_post_modified_gmt' ] = $post->post_modified_gmt;
- $response = self::http_post( http_build_query( $comment ), 'comment-check' );
+ $response = self::http_post( build_query( $comment ), 'comment-check' );
do_action( 'akismet_comment_check_response', $response );
self::update_alert( $response );
- $commentdata['comment_as_submitted'] = $comment;
+ $commentdata['comment_as_submitted'] = array_intersect_key( $comment, array( 'blog' => '', 'blog_charset' => '', 'blog_lang' => '', 'blog_ua' => '', 'comment_agent' => '', 'comment_author' => '', 'comment_author_IP' => '', 'comment_author_email' => '', 'comment_author_url' => '', 'comment_content' => '', 'comment_date_gmt' => '', 'comment_tags' => '', 'comment_type' => '', 'guid' => '', 'is_test' => '', 'permalink' => '', 'reporter' => '', 'site_domain' => '', 'submit_referer' => '', 'submit_uri' => '', 'user_ID' => '', 'user_agent' => '', 'user_id' => '', 'user_ip' => '' ) );
$commentdata['akismet_result'] = $response[1];
if ( isset( $response[0]['x-akismet-pro-tip'] ) )
$commentdata['akismet_pro_tip'] = $response[0]['x-akismet-pro-tip'];
- if ( 'true' == $response[1] ) {
+ if ( isset( $response[0]['x-akismet-error'] ) ) {
+ // An error occurred that we anticipated (like a suspended key) and want the user to act on.
+ // Send to moderation.
+ self::$last_comment_result = '0';
+ }
+ else if ( 'true' == $response[1] ) {
// akismet_spam_count will be incremented later by comment_is_spam()
self::$last_comment_result = 'spam';
if ( self::is_test_mode() )
$c['is_test'] = 'true';
- $response = self::http_post( http_build_query( $c ), 'comment-check' );
+ $response = self::http_post( build_query( $c ), 'comment-check' );
return ( is_array( $response ) && ! empty( $response[1] ) ) ? $response[1] : false;
}
+
+
+
+ public static function transition_comment_status( $new_status, $old_status, $comment ) {
+
+ if ( $new_status == $old_status )
+ return;
+
+ # we don't need to record a history item for deleted comments
+ if ( $new_status == 'delete' )
+ return;
+
+ if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) )
+ return;
+
+ if ( defined('WP_IMPORTING') && WP_IMPORTING == true )
+ return;
+
+ // if this is present, it means the status has been changed by a re-check, not an explicit user action
+ if ( get_comment_meta( $comment->comment_ID, 'akismet_rechecking' ) )
+ return;
+
+ global $current_user;
+ $reporter = '';
+ if ( is_object( $current_user ) )
+ $reporter = $current_user->user_login;
+
+ // Assumption alert:
+ // We want to submit comments to Akismet only when a moderator explicitly spams or approves it - not if the status
+ // is changed automatically by another plugin. Unfortunately WordPress doesn't provide an unambiguous way to
+ // determine why the transition_comment_status action was triggered. And there are several different ways by which
+ // to spam and unspam comments: bulk actions, ajax, links in moderation emails, the dashboard, and perhaps others.
+ // We'll assume that this is an explicit user action if certain POST/GET variables exist.
+ if ( ( isset( $_POST['status'] ) && in_array( $_POST['status'], array( 'spam', 'unspam' ) ) ) ||
+ ( isset( $_POST['spam'] ) && (int) $_POST['spam'] == 1 ) ||
+ ( isset( $_POST['unspam'] ) && (int) $_POST['unspam'] == 1 ) ||
+ ( isset( $_POST['comment_status'] ) && in_array( $_POST['comment_status'], array( 'spam', 'unspam' ) ) ) ||
+ ( isset( $_GET['action'] ) && in_array( $_GET['action'], array( 'spam', 'unspam' ) ) ) ||
+ ( isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'editedcomment' ) ) )
+ ) {
+ if ( $new_status == 'spam' && ( $old_status == 'approved' || $old_status == 'unapproved' || !$old_status ) ) {
+ return self::submit_spam_comment( $comment->comment_ID );
+ } elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) {
+ return self::submit_nonspam_comment( $comment->comment_ID );
+ }
+ }
+
+ self::update_comment_history( $comment->comment_ID, sprintf( __('%1$s changed the comment status to %2$s', 'akismet'), $reporter, $new_status ), 'status-' . $new_status );
+ }
+
+ public static function submit_spam_comment( $comment_id ) {
+ global $wpdb, $current_user, $current_site;
+
+ $comment_id = (int) $comment_id;
+
+ $comment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_ID = %d", $comment_id ) );
+
+ if ( !$comment ) // it was deleted
+ return;
+
+ if ( 'spam' != $comment->comment_approved )
+ return;
+
+ // use the original version stored in comment_meta if available
+ $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
+
+ if ( $as_submitted && is_array( $as_submitted ) && isset( $as_submitted['comment_content'] ) )
+ $comment = (object) array_merge( (array)$comment, $as_submitted );
+
+ $comment->blog = get_bloginfo('url');
+ $comment->blog_lang = get_locale();
+ $comment->blog_charset = get_option('blog_charset');
+ $comment->permalink = get_permalink($comment->comment_post_ID);
+
+ if ( is_object($current_user) )
+ $comment->reporter = $current_user->user_login;
+
+ if ( is_object($current_site) )
+ $comment->site_domain = $current_site->domain;
+
+ $comment->user_role = '';
+ if ( isset( $comment->user_ID ) )
+ $comment->user_role = Akismet::get_user_roles( $comment->user_ID );
+
+ if ( self::is_test_mode() )
+ $comment->is_test = 'true';
+
+ $post = get_post( $comment->comment_post_ID );
+ $comment->comment_post_modified_gmt = $post->post_modified_gmt;
+
+ $response = Akismet::http_post( build_query( $comment ), 'submit-spam' );
+ if ( $comment->reporter ) {
+ self::update_comment_history( $comment_id, sprintf( __('%s reported this comment as spam', 'akismet'), $comment->reporter ), 'report-spam' );
+ update_comment_meta( $comment_id, 'akismet_user_result', 'true' );
+ update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
+ }
+
+ do_action('akismet_submit_spam_comment', $comment_id, $response[1]);
+ }
+
+ public static function submit_nonspam_comment( $comment_id ) {
+ global $wpdb, $current_user, $current_site;
+
+ $comment_id = (int) $comment_id;
+
+ $comment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_ID = %d", $comment_id ) );
+ if ( !$comment ) // it was deleted
+ return;
+
+ // use the original version stored in comment_meta if available
+ $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
+
+ if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) )
+ $comment = (object) array_merge( (array)$comment, $as_submitted );
+
+ $comment->blog = get_bloginfo('url');
+ $comment->blog_lang = get_locale();
+ $comment->blog_charset = get_option('blog_charset');
+ $comment->permalink = get_permalink( $comment->comment_post_ID );
+ $comment->user_role = '';
+
+ if ( is_object($current_user) )
+ $comment->reporter = $current_user->user_login;
+
+ if ( is_object($current_site) )
+ $comment->site_domain = $current_site->domain;
+
+ if ( isset( $comment->user_ID ) )
+ $comment->user_role = Akismet::get_user_roles($comment->user_ID);
+
+ if ( Akismet::is_test_mode() )
+ $comment->is_test = 'true';
+
+ $post = get_post( $comment->comment_post_ID );
+ $comment->comment_post_modified_gmt = $post->post_modified_gmt;
+
+ $response = self::http_post( build_query( $comment ), 'submit-ham' );
+ if ( $comment->reporter ) {
+ self::update_comment_history( $comment_id, sprintf( __('%s reported this comment as not spam', 'akismet'), $comment->reporter ), 'report-ham' );
+ update_comment_meta( $comment_id, 'akismet_user_result', 'false' );
+ update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
+ }
+
+ do_action('akismet_submit_nonspam_comment', $comment_id, $response[1]);
+ }
public static function cron_recheck() {
global $wpdb;
}
public static function load_form_js() {
- wp_enqueue_script( 'akismet-form', AKISMET__PLUGIN_URL . '_inc/form.js', array( 'jquery' ), AKISMET_VERSION );
+ // WP < 3.3 can't enqueue a script this late in the game and still have it appear in the footer.
+ // Once we drop support for everything pre-3.3, this can change back to a single enqueue call.
+ wp_register_script( 'akismet-form', AKISMET__PLUGIN_URL . '_inc/form.js', array(), AKISMET_VERSION, true );
+ add_action( 'wp_footer', array( 'Akismet', 'print_form_js' ) );
+ add_action( 'admin_footer', array( 'Akismet', 'print_form_js' ) );
+ }
+
+ public static function print_form_js() {
wp_print_scripts( 'akismet-form' );
}
=== Akismet ===
Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic
Tags: akismet, comments, spam
-Requires at least: 3.0
-Tested up to: 3.9
-Stable tag: 3.0.0
+Requires at least: 3.1
+Tested up to: 3.9.1
+Stable tag: 3.0.1
License: GPLv2 or later
-Akismet checks your comments against the Akismet web service to see if they look like spam or not.
+Akismet checks your comments against the Akismet Web service to see if they look like spam or not.
== Description ==
-Akismet checks your comments against the Akismet web service to see if they look like spam or not and lets you
-review the spam it catches under your blog's "Comments" admin screen.
+Akismet checks your comments against the Akismet Web service to see if they look like spam or not and lets you review the spam it catches under your blog's "Comments" admin screen.
-Major new features in Akismet 2.5 include:
+Major features in Akismet include:
-* A comment status history, so you can easily see which comments were caught or cleared by Akismet, and which were spammed or unspammed by a moderator
-* Links are highlighted in the comment body, to reveal hidden or misleading links
-* If your web host is unable to reach Akismet's servers, the plugin will automatically retry when your connection is back up
-* Moderators can see the number of approved comments for each user
-* Spam and Unspam reports now include more information, to help improve accuracy
+* Automatically checks all comments and filters out the ones that look like spam.
+* Each comment has a status history, so you can easily see which comments were caught or cleared by Akismet and which were spammed or unspammed by a moderator.
+* URLs are shown in the comment body to reveal hidden or misleading links.
+* Moderators can see the number of approved comments for each user.
+* A discard feature that outright blocks the worst spam, saving you disk space and speeding up your site.
-PS: You'll need an [Akismet.com API key](http://akismet.com/get/) to use it. Keys are free for personal blogs, with paid subscriptions available for businesses and commercial sites.
+PS: You'll need an [Akismet.com API key](http://akismet.com/get/) to use it. Keys are free for personal blogs; paid subscriptions are available for businesses and commercial sites.
== Installation ==
== Changelog ==
+= 3.0.1 =
+* Removed dependency on PHP's fsockopen function
+* Fix spam/ham reports to work when reported outside of the WP dashboard, e.g., from Notifications or the WP app
+* Remove jQuery dependency for comment form JavaScript
+* Remove unnecessary data from some Akismet comment meta
+* Suspended keys will now result in all comments being put in moderation, not spam.
+
= 3.0.0 =
* Move Akismet to Settings menu
* Drop Akismet Stats menu
* Add Akismet subscription details and status to Akismet settings
* Add contextual help for each page
* Improve Akismet setup to use Jetpack to automate plugin setup
-* Fix Update Check for Spam to use ajax to avoid page timing out
+* Fix "Check for Spam" to use AJAX to avoid page timing out
* Fix Akismet settings page to be responsive
* Drop legacy code
* Tidy up CSS and Javascript
<?php elseif ( $type == 'missing-functions' ) :?>
<div class="wrap alert critical">
<h3 class="key-status failed"><?php esc_html_e('Network functions are disabled.', 'akismet'); ?></h3>
- <p class="description"><?php printf( __('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>.', 'akismet'), 'https://blog.akismet.com/akismet-hosting-faq/'); ?></p>
+ <p class="description"><?php printf( __('Your web host or server administrator has disabled PHP’s <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>.', 'akismet'), 'https://blog.akismet.com/akismet-hosting-faq/'); ?></p>
</div>
<?php elseif ( $type == 'servers-be-down' ) :?>
<div class="wrap alert critical">
function akismet_http_post( $request, $host, $path, $port = 80, $ip = null ) {
_deprecated_function( __FUNCTION__, '3.0', 'Akismet::http_post()' );
- $path = str_ireplace( '/1.1/', '', $path );
+ $path = str_replace( '/1.1/', '', $path );
return Akismet::http_post( $request, $path, $ip );
}
return Akismet_Admin::check_for_spam_button( $comment_status );
}
function akismet_submit_nonspam_comment( $comment_id ) {
- _deprecated_function( __FUNCTION__, '3.0', 'Akismet_Admin::submit_nonspam_comment()' );
+ _deprecated_function( __FUNCTION__, '3.0', 'Akismet::submit_nonspam_comment()' );
- return Akismet_Admin::submit_nonspam_comment( $comment_id );
+ return Akismet::submit_nonspam_comment( $comment_id );
}
function akismet_submit_spam_comment( $comment_id ) {
- _deprecated_function( __FUNCTION__, '3.0', 'Akismet_Admin::submit_spam_comment()' );
+ _deprecated_function( __FUNCTION__, '3.0', 'Akismet::submit_spam_comment()' );
- return Akismet_Admin::submit_spam_comment( $comment_id );
+ return Akismet::submit_spam_comment( $comment_id );
}
function akismet_transition_comment_status( $new_status, $old_status, $comment ) {
- _deprecated_function( __FUNCTION__, '3.0', 'Akismet_Admin::transition_comment_status()' );
+ _deprecated_function( __FUNCTION__, '3.0', 'Akismet::transition_comment_status()' );
- return Akismet_Admin::transition_comment_status( $new_status, $old_status, $comment );
+ return Akismet::transition_comment_status( $new_status, $old_status, $comment );
}
function akismet_spam_count( $type = false ) {
_deprecated_function( __FUNCTION__, '3.0', 'Akismet_Admin::get_spam_count()' );
_deprecated_function( __FUNCTION__, '3.0' );
return 0;
-}
+}
\ No newline at end of file
}
public static function XML2array($XMLstring) {
- if (function_exists('simplexml_load_string')) {
- if (function_exists('get_object_vars')) {
- $XMLobject = simplexml_load_string($XMLstring);
- return self::SimpleXMLelement2array($XMLobject);
- }
+ if ( function_exists( 'simplexml_load_string' ) && function_exists( 'libxml_disable_entity_loader' ) ) {
+ $loader = libxml_disable_entity_loader( true );
+ $XMLobject = simplexml_load_string( $XMLstring, 'SimpleXMLElement', LIBXML_NOENT );
+ $return = self::SimpleXMLelement2array( $XMLobject );
+ libxml_disable_entity_loader( $loader );
+ return $return;
}
return false;
}
{
// first remove the XML declaration
// merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
- $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr($this->message, 0, 100), 1);
- $this->message = substr_replace($this->message, $header, 0, 100);
- if (trim($this->message) == '') {
+ $header = preg_replace( '/<\?xml.*?\?'.'>/s', '', substr( $this->message, 0, 100 ), 1 );
+ $this->message = trim( substr_replace( $this->message, $header, 0, 100 ) );
+ if ( '' == $this->message ) {
return false;
}
+
+ // Then remove the DOCTYPE
+ $header = preg_replace( '/^<!DOCTYPE[^>]*+>/i', '', substr( $this->message, 0, 200 ), 1 );
+ $this->message = trim( substr_replace( $this->message, $header, 0, 200 ) );
+ if ( '' == $this->message ) {
+ return false;
+ }
+
+ // Check that the root tag is valid
+ $root_tag = substr( $this->message, 0, strcspn( substr( $this->message, 0, 20 ), "> \t\r\n" ) );
+ if ( '<!DOCTYPE' === strtoupper( $root_tag ) ) {
+ return false;
+ }
+ if ( ! in_array( $root_tag, array( '<methodCall', '<methodResponse', '<fault' ) ) ) {
+ return false;
+ }
+
+ // Bail if there are too many elements to parse
+ $element_limit = 30000;
+ if ( function_exists( 'apply_filters' ) ) {
+ $element_limit = apply_filters( 'xmlrpc_element_limit', $element_limit );
+ }
+ if ( $element_limit && 2 * $element_limit < substr_count( $this->message, '<' ) ) {
+ return false;
+ }
+
$this->_parser = xml_parser_create();
// Set XML parser to take the case of tags in to account
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
}
/**
- * Get a widget instance's hash key.
+ * Get MAC for a serialized widget instance string.
*
- * Serialize an instance and hash it with the AUTH_KEY; when a JS value is
- * posted back to save, this instance hash key is used to ensure that the
- * serialized_instance was not tampered with, but that it had originated
- * from WordPress and so is sanitized.
+ * Allows values posted back from JS to be rejected if any tampering of the
+ * data has occurred.
*
* @since 3.9.0
* @access protected
*
- * @param array $instance Widget instance.
- * @return string Widget instance's hash key.
+ * @param string $serialized_instance Widget instance.
+ * @return string MAC for serialized widget instance.
*/
- protected function get_instance_hash_key( $instance ) {
- $hash = md5( AUTH_KEY . serialize( $instance ) );
- return $hash;
+ protected function get_instance_hash_key( $serialized_instance ) {
+ return wp_hash( $serialized_instance );
}
/**
}
$decoded = base64_decode( $value['encoded_serialized_instance'], true );
-
if ( false === $decoded ) {
return null;
}
- $instance = unserialize( $decoded );
- if ( false === $instance ) {
+ if ( $this->get_instance_hash_key( $decoded ) !== $value['instance_hash_key'] ) {
return null;
}
- if ( $this->get_instance_hash_key( $instance ) !== $value['instance_hash_key'] ) {
+
+ $instance = unserialize( $decoded );
+ if ( false === $instance ) {
return null;
}
+
return $instance;
}
'encoded_serialized_instance' => base64_encode( $serialized ),
'title' => empty( $value['title'] ) ? '' : $value['title'],
'is_widget_customizer_js_value' => true,
- 'instance_hash_key' => $this->get_instance_hash_key( $value ),
+ 'instance_hash_key' => $this->get_instance_hash_key( $serialized ),
);
}
return $value;
return is_array($data) ? array_map(__FUNCTION__, $data) : $data;
}
}
+
+if ( ! function_exists( 'hash_equals' ) ) :
+/**
+ * Compare two strings in constant time.
+ *
+ * This function was added in PHP 5.6.
+ * It can leak the length of a string.
+ *
+ * @since 3.9.2
+ *
+ * @param string $a Expected string.
+ * @param string $b Actual string.
+ * @return bool Whether strings are equal.
+ */
+function hash_equals( $a, $b ) {
+ $a_length = strlen( $a );
+ if ( $a_length !== strlen( $b ) ) {
+ return false;
+ }
+ $result = 0;
+
+ // Do not attempt to "optimize" this.
+ for ( $i = 0; $i < $a_length; $i++ ) {
+ $result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
+ }
+
+ return $result === 0;
+}
+endif;
\ No newline at end of file
$key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);
$hash = hash_hmac('md5', $username . '|' . $expiration, $key);
- if ( hash_hmac( 'md5', $hmac, $key ) !== hash_hmac( 'md5', $hash, $key ) ) {
+ if ( ! hash_equals( $hash, $hmac ) ) {
/**
* Fires if a bad authentication cookie hash is encountered.
*
$i = wp_nonce_tick();
// Nonce generated 0-12 hours ago
- if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) === $nonce )
+ $expected = substr( wp_hash( $i . '|' . $action . '|' . $uid, 'nonce'), -12, 10 );
+ if ( hash_equals( $expected, $nonce ) ) {
return 1;
+ }
+
// Nonce generated 12-24 hours ago
- if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) === $nonce )
+ $expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid, 'nonce' ), -12, 10 );
+ if ( hash_equals( $expected, $nonce ) ) {
return 2;
+ }
+
// Invalid nonce
return false;
}
$i = wp_nonce_tick();
- return substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10);
+ return substr(wp_hash($i . '|' . $action . '|' . $uid, 'nonce'), -12, 10);
}
endif;
$out = str_replace( '&', '&', esc_url( $out ) );
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
} else {
- $avatar = "<img alt='{$safe_alt}' src='{$default}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
+ $out = esc_url( $default );
+ $avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
}
/**
}
endif;
+if ( ! function_exists( 'hash_equals' ) ) :
+/**
+ * Compare two strings in constant time.
+ *
+ * This function is NOT pluggable. It is in this file (in addition to
+ * compat.php) to prevent errors if, during an update, pluggable.php
+ * copies over but compat.php does not.
+ *
+ * This function was added in PHP 5.6.
+ * It can leak the length of a string.
+ *
+ * @since 3.9.2
+ *
+ * @param string $a Expected string.
+ * @param string $b Actual string.
+ * @return bool Whether strings are equal.
+ */
+function hash_equals( $a, $b ) {
+ $a_length = strlen( $a );
+ if ( $a_length !== strlen( $b ) ) {
+ return false;
+ }
+ $result = 0;
+
+ // Do not attempt to "optimize" this.
+ for ( $i = 0; $i < $a_length; $i++ ) {
+ $result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
+ }
+
+ return $result === 0;
+}
+endif;
*
* @global string $wp_version
*/
-$wp_version = '3.9.1';
+$wp_version = '3.9.2';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
case 'resetpass' :
case 'rp' :
- $user = check_password_reset_key($_GET['key'], $_GET['login']);
+ list( $rp_path ) = explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) );
+ $rp_cookie = 'wp-resetpass-' . COOKIEHASH;
+ if ( isset( $_GET['key'] ) ) {
+ $value = sprintf( '%s:%s', wp_unslash( $_GET['login'] ), wp_unslash( $_GET['key'] ) );
+ setcookie( $rp_cookie, $value, 0, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
+ wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) );
+ exit;
+ }
+
+ if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ':' ) ) {
+ list( $rp_login, $rp_key ) = explode( ':', wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
+ $user = check_password_reset_key( $rp_key, $rp_login );
+ } else {
+ $user = false;
+ }
- if ( is_wp_error($user) ) {
- if ( $user->get_error_code() === 'expired_key' )
+ if ( ! $user || is_wp_error( $user ) ) {
+ setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
+ if ( $user && $user->get_error_code() === 'expired_key' )
wp_redirect( site_url( 'wp-login.php?action=lostpassword&error=expiredkey' ) );
else
wp_redirect( site_url( 'wp-login.php?action=lostpassword&error=invalidkey' ) );
if ( ( ! $errors->get_error_code() ) && isset( $_POST['pass1'] ) && !empty( $_POST['pass1'] ) ) {
reset_password($user, $_POST['pass1']);
+ setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
login_header( __( 'Password Reset' ), '<p class="message reset-pass">' . __( 'Your password has been reset.' ) . ' <a href="' . esc_url( wp_login_url() ) . '">' . __( 'Log in' ) . '</a></p>' );
login_footer();
exit;
login_header(__('Reset Password'), '<p class="message reset-pass">' . __('Enter your new password below.') . '</p>', $errors );
?>
-<form name="resetpassform" id="resetpassform" action="<?php echo esc_url( site_url( 'wp-login.php?action=resetpass&key=' . urlencode( $_GET['key'] ) . '&login=' . urlencode( $_GET['login'] ), 'login_post' ) ); ?>" method="post" autocomplete="off">
- <input type="hidden" id="user_login" value="<?php echo esc_attr( $_GET['login'] ); ?>" autocomplete="off" />
+<form name="resetpassform" id="resetpassform" action="<?php echo esc_url( site_url( 'wp-login.php?action=resetpass', 'login_post' ) ); ?>" method="post" autocomplete="off">
+ <input type="hidden" id="user_login" value="<?php echo esc_attr( $rp_login ); ?>" autocomplete="off" />
<p>
<label for="pass1"><?php _e('New password') ?><br />