WordPress 3.7.2 wordpress-3.7.2
authorEdward Z. Yang <ezyang@cs.stanford.edu>
Fri, 11 Apr 2014 00:48:55 +0000 (17:48 -0700)
committerEdward Z. Yang <ezyang@cs.stanford.edu>
Fri, 11 Apr 2014 00:48:55 +0000 (17:48 -0700)
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
24 files changed:
readme.html
wp-admin/about.php
wp-admin/includes/class-wp-posts-list-table.php
wp-admin/includes/class-wp-upgrader.php
wp-admin/includes/post.php
wp-admin/includes/update-core.php
wp-admin/includes/update.php
wp-admin/includes/upgrade.php
wp-content/plugins/akismet/admin.php
wp-content/plugins/akismet/akismet.css
wp-content/plugins/akismet/akismet.js
wp-content/plugins/akismet/akismet.php
wp-content/plugins/akismet/readme.txt
wp-content/themes/twentythirteen/languages/twentythirteen.pot
wp-content/themes/twentytwelve/languages/twentytwelve.pot
wp-includes/bookmark.php
wp-includes/class-wp-xmlrpc-server.php
wp-includes/cron.php
wp-includes/functions.php
wp-includes/js/plupload/plupload.silverlight.xap
wp-includes/option.php
wp-includes/pluggable.php
wp-includes/update.php
wp-includes/version.php

index 820583e4af1ef940b9e78455b32991ef97ebde24..2ccaa4a2dde015d5328a987e8ff40070b5cf79d4 100644 (file)
@@ -8,7 +8,7 @@
 <body>
 <h1 id="logo">
        <a href="http://wordpress.org/"><img alt="WordPress" src="wp-admin/images/wordpress-logo.png" /></a>
-       <br /> Version 3.7
+       <br /> Version 3.7.2
 </h1>
 <p style="text-align: center">Semantic Personal Publishing Platform</p>
 
index c0ef6c60361e93504b5dd0b69c01a8dc782e90f1..5d0254e10a02a3ac57e86693852196831e2fed72 100644 (file)
@@ -36,7 +36,11 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
 </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 some security issues and fixed %2$s bug.',
+         '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.', 9 ), '3.7.2', number_format_i18n( 9 ) ); ?>
+               <?php printf( __( 'For more information, see <a href="%s">the release notes</a>.' ), 'http://codex.wordpress.org/Version_3.7.2' ); ?>
+       </p>
        <p><?php printf( _n( '<strong>Version %1$s</strong> addressed %2$s bug.',
                '<strong>Version %1$s</strong> addressed %2$s bugs.', 11 ), '3.7.1', number_format_i18n( 11 ) ); ?>
                <?php printf( __( 'For more information, see <a href="%s">the release notes</a>.' ), 'http://codex.wordpress.org/Version_3.7.1' ); ?>
index 016a726b74b1270709ae84a1ae1258c3a7b6133f..dba1a3dee532e752a592578be671c91589d84e20 100644 (file)
@@ -832,7 +832,7 @@ class WP_Posts_List_Table extends WP_List_Table {
        <?php if ( !$bulk ) echo $authors_dropdown;
        endif; // post_type_supports author
 
-       if ( !$bulk ) :
+       if ( !$bulk && $can_publish ) :
        ?>
 
                        <div class="inline-edit-group">
index 90b9658d573f4d81bcb3586707d2f3e843c49082..330f5ea0550d7b98fe52ddddfddfc9d66a05a90d 100644 (file)
@@ -1314,7 +1314,9 @@ class Core_Upgrader extends WP_Upgrader {
        }
 
        function upgrade( $current, $args = array() ) {
-               global $wp_filesystem, $wp_version;
+               global $wp_filesystem;
+
+               include ABSPATH . WPINC . '/version.php'; // $wp_version;
 
                $start_time = time();
 
@@ -1333,8 +1335,9 @@ class Core_Upgrader extends WP_Upgrader {
                        return new WP_Error('up_to_date', $this->strings['up_to_date']);
 
                $res = $this->fs_connect( array(ABSPATH, WP_CONTENT_DIR) );
-               if ( is_wp_error($res) )
+               if ( ! $res || is_wp_error( $res ) ) {
                        return $res;
+               }
 
                $wp_dir = trailingslashit($wp_filesystem->abspath());
 
@@ -1421,6 +1424,7 @@ class Core_Upgrader extends WP_Upgrader {
                                'fs_method'        => $wp_filesystem->method,
                                'fs_method_forced' => defined( 'FS_METHOD' ) || has_filter( 'filesystem_method' ),
                                'time_taken'       => time() - $start_time,
+                               'reported'         => $wp_version,
                                'attempted'        => $current->version,
                        );
 
@@ -1868,18 +1872,21 @@ class WP_Automatic_Updater {
                if ( ! $this->should_update( $type, $item, $context ) )
                        return false;
 
+               $upgrader_item = $item;
                switch ( $type ) {
                        case 'core':
                                $skin->feedback( __( 'Updating to WordPress %s' ), $item->version );
                                $item_name = sprintf( __( 'WordPress %s' ), $item->version );
                                break;
                        case 'theme':
-                               $theme = wp_get_theme( $item );
+                               $upgrader_item = $item->theme;
+                               $theme = wp_get_theme( $upgrader_item );
                                $item_name = $theme->Get( 'Name' );
                                $skin->feedback( __( 'Updating theme: %s' ), $item_name );
                                break;
                        case 'plugin':
-                               $plugin_data = get_plugin_data( $context . '/' . $item );
+                               $upgrader_item = $item->plugin;
+                               $plugin_data = get_plugin_data( $context . '/' . $upgrader_item );
                                $item_name = $plugin_data['Name'];
                                $skin->feedback( __( 'Updating plugin: %s' ), $item_name );
                                break;
@@ -1891,12 +1898,17 @@ class WP_Automatic_Updater {
                }
 
                // Boom, This sites about to get a whole new splash of paint!
-               $upgrade_result = $upgrader->upgrade( $item, array(
+               $upgrade_result = $upgrader->upgrade( $upgrader_item, array(
                        'clear_update_cache' => false,
                        'pre_check_md5'      => false, /* always use partial builds if possible for core updates */
                        'attempt_rollback'   => true, /* only available for core updates */
                ) );
 
+               // if the filesystem is unavailable, false is returned.
+               if ( false === $upgrade_result ) {
+                       $upgrade_result = new WP_Error( 'fs_unavailable', __( 'Could not access filesystem.' ) );
+               }
+
                // Core doesn't output this, so lets append it so we don't get confused
                if ( 'core' == $type ) {
                        if ( is_wp_error( $upgrade_result ) ) {
@@ -1960,7 +1972,7 @@ class WP_Automatic_Updater {
                wp_update_plugins(); // Check for Plugin updates
                $plugin_updates = get_site_transient( 'update_plugins' );
                if ( $plugin_updates && !empty( $plugin_updates->response ) ) {
-                       foreach ( array_keys( $plugin_updates->response ) as $plugin ) {
+                       foreach ( $plugin_updates->response as $plugin ) {
                                $this->update( 'plugin', $plugin );
                        }
                        // Force refresh of plugin update information
@@ -1971,8 +1983,8 @@ class WP_Automatic_Updater {
                wp_update_themes();  // Check for Theme updates
                $theme_updates = get_site_transient( 'update_themes' );
                if ( $theme_updates && !empty( $theme_updates->response ) ) {
-                       foreach ( array_keys( $theme_updates->response ) as $theme ) {
-                               $this->update( 'theme', $theme );
+                       foreach ( $theme_updates->response as $theme ) {
+                               $this->update( 'theme', (object) $theme );
                        }
                        // Force refresh of theme update information
                        wp_clean_themes_cache();
@@ -1987,8 +1999,21 @@ class WP_Automatic_Updater {
 
                // Clean up, and check for any pending translations
                // (Core_Upgrader checks for core updates)
-               wp_update_themes();  // Check for Theme updates
-               wp_update_plugins(); // Check for Plugin updates
+               $theme_stats = array();
+               if ( isset( $this->update_results['theme'] ) ) {
+                       foreach ( $this->update_results['theme'] as $upgrade ) {
+                               $theme_stats[ $upgrade->item->theme ] = ( true === $upgrade->result );
+                       }
+               }
+               wp_update_themes( $theme_stats );  // Check for Theme updates
+
+               $plugin_stats = array();
+               if ( isset( $this->update_results['plugin'] ) ) {
+                       foreach ( $this->update_results['plugin'] as $upgrade ) {
+                               $plugin_stats[ $upgrade->item->plugin ] = ( true === $upgrade->result );
+                       }
+               }
+               wp_update_plugins( $plugin_stats ); // Check for Plugin updates
 
                // Finally, Process any new translations
                $language_updates = wp_get_translation_updates();
index 7d074dd77988f3b392422161767c1af440bb405e..fea812e0cc92207cd44fc64b16e949a00cf7cc10 100644 (file)
@@ -100,6 +100,10 @@ function _wp_translate_postdata( $update = false, $post_data = null ) {
                $post_id = false;
        $previous_status = $post_id ? get_post_field( 'post_status', $post_id ) : false;
 
+       if ( isset( $post_data['post_status'] ) && 'private' == $post_data['post_status'] && ! current_user_can( $ptype->cap->publish_posts ) ) {
+               $post_data['post_status'] = $previous_status ? $previous_status : 'pending';
+       }
+
        $published_statuses = array( 'publish', 'future' );
 
        // Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
@@ -111,6 +115,10 @@ function _wp_translate_postdata( $update = false, $post_data = null ) {
        if ( ! isset($post_data['post_status']) )
                $post_data['post_status'] = $previous_status;
 
+       if ( isset( $post_data['post_password'] ) && ! current_user_can( $ptype->cap->publish_posts ) ) {
+               unset( $post_data['post_password'] );
+       }
+
        if (!isset( $post_data['comment_status'] ))
                $post_data['comment_status'] = 'closed';
 
@@ -170,6 +178,14 @@ function edit_post( $post_data = null ) {
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
 
+       if ( ! empty( $post_data['post_status'] ) ) {
+               $post_data['post_status'] = sanitize_key( $post_data['post_status'] );
+
+               if ( 'inherit' == $post_data['post_status'] ) {
+                       unset( $post_data['post_status'] );
+               }
+       }
+
        $ptype = get_post_type_object($post_data['post_type']);
        if ( !current_user_can( 'edit_post', $post_ID ) ) {
                if ( 'page' == $post_data['post_type'] )
@@ -187,9 +203,6 @@ function edit_post( $post_data = null ) {
                        _wp_upgrade_revisions_of_post( $post, wp_get_post_revisions( $post_ID ) );
        }
 
-       $post_data = _wp_translate_postdata( true, $post_data );
-       if ( is_wp_error($post_data) )
-               wp_die( $post_data->get_error_message() );
        if ( ( empty( $post_data['action'] ) || 'autosave' != $post_data['action'] ) && 'auto-draft' == $post_data['post_status'] ) {
                $post_data['post_status'] = 'draft';
        }
@@ -210,6 +223,10 @@ function edit_post( $post_data = null ) {
                }
        }
 
+       $post_data = _wp_translate_postdata( true, $post_data );
+       if ( is_wp_error($post_data) )
+               wp_die( $post_data->get_error_message() );
+
        // Post Formats
        if ( isset( $post_data['post_format'] ) )
                set_post_format( $post_ID, $post_data['post_format'] );
@@ -332,6 +349,14 @@ function bulk_edit_posts( $post_data = null ) {
        }
        unset($post_data['_status']);
 
+       if ( ! empty( $post_data['post_status'] ) ) {
+               $post_data['post_status'] = sanitize_key( $post_data['post_status'] );
+
+               if ( 'inherit' == $post_data['post_status'] ) {
+                       unset( $post_data['post_status'] );
+               }
+       }
+
        $post_IDs = array_map( 'intval', (array) $post_data['post'] );
 
        $reset = array(
@@ -422,11 +447,26 @@ function bulk_edit_posts( $post_data = null ) {
                        unset( $post_data['tax_input']['category'] );
                }
 
+               $post_data['post_type'] = $post->post_type;
                $post_data['post_mime_type'] = $post->post_mime_type;
                $post_data['guid'] = $post->guid;
 
+               foreach ( array( 'comment_status', 'ping_status', 'post_author' ) as $field ) {
+                       if ( ! isset( $post_data[ $field ] ) ) {
+                               $post_data[ $field ] = $post->$field;
+                       }
+               }
+
                $post_data['ID'] = $post_ID;
-               $updated[] = wp_update_post( $post_data );
+               $post_data['post_ID'] = $post_ID;
+
+               $translated_post_data = _wp_translate_postdata( true, $post_data );
+               if ( is_wp_error( $translated_post_data ) ) {
+                       $skipped[] = $post_ID;
+                       continue;
+               }
+
+               $updated[] = wp_update_post( $translated_post_data );
 
                if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) {
                        if ( 'sticky' == $post_data['sticky'] )
@@ -569,10 +609,6 @@ function wp_write_post() {
        if ( isset( $_POST['post_ID'] ) )
                return edit_post();
 
-       $translated = _wp_translate_postdata( false );
-       if ( is_wp_error($translated) )
-               return $translated;
-
        if ( isset($_POST['visibility']) ) {
                switch ( $_POST['visibility'] ) {
                        case 'public' :
@@ -589,6 +625,10 @@ function wp_write_post() {
                }
        }
 
+       $translated = _wp_translate_postdata( false );
+       if ( is_wp_error($translated) )
+               return $translated;
+
        // Create the post.
        $post_ID = wp_insert_post( $_POST );
        if ( is_wp_error( $post_ID ) )
index b841268b5ee3e8bd313154597262d62dfd5fe429..913a9d4ceae516c5a68430d2e63e82a3bc97c1aa 100644 (file)
@@ -697,6 +697,9 @@ function update_core($from, $to) {
 
        // Check to see which files don't really need updating - only available for 3.7 and higher
        if ( function_exists( 'get_core_checksums' ) ) {
+               // Find the local version of the working directory
+               $working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro;
+
                $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );
                if ( is_array( $checksums ) && isset( $checksums[ $wp_version ] ) )
                        $checksums = $checksums[ $wp_version ]; // Compat code for 3.7-beta2
@@ -706,6 +709,8 @@ function update_core($from, $to) {
                                        continue;
                                if ( ! file_exists( ABSPATH . $file ) )
                                        continue;
+                               if ( ! file_exists( $working_dir_local . $file ) )
+                                       continue;
                                if ( md5_file( ABSPATH . $file ) === $checksum )
                                        $skip[] = $file;
                                else
@@ -752,9 +757,10 @@ function update_core($from, $to) {
        $failed = array();
        if ( isset( $checksums ) && is_array( $checksums ) ) {
                foreach ( $checksums as $file => $checksum ) {
-                       if ( 0 === strpos( $file, 'wp-content' ) )
+                       if ( 'wp-content' == substr( $file, 0, 10 ) )
+                               continue;
+                       if ( ! file_exists( $working_dir_local . $file ) )
                                continue;
-
                        if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) == $checksum )
                                $skip[] = $file;
                        else
@@ -765,8 +771,6 @@ function update_core($from, $to) {
        // Some files didn't copy properly
        if ( ! empty( $failed ) ) {
                $total_size = 0;
-               // Find the local version of the working directory
-               $working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro;
                foreach ( $failed as $file ) {
                        if ( file_exists( $working_dir_local . $file ) )
                                $total_size += filesize( $working_dir_local . $file );
@@ -882,6 +886,11 @@ function update_core($from, $to) {
        $db_upgrade_url = admin_url('upgrade.php?step=upgrade_db');
        wp_remote_post($db_upgrade_url, array('timeout' => 60));
 
+       // Clear the cache to prevent an update_option() from saving a stale db_version to the cache
+       wp_cache_flush();
+       // (Not all cache backends listen to 'flush')
+       wp_cache_delete( 'alloptions', 'options' );
+
        // Remove working directory
        $wp_filesystem->delete($from, true);
 
index feafd94b8759c5112b19e1f42c18d83ff32f9d68..5ee195a79f0f6ec6211df8c5179c812e40895e93 100644 (file)
@@ -364,7 +364,7 @@ function maintenance_nag() {
                 * This flag is cleared whenever a successful update occurs using Core_Upgrader.
                 */
                $comparison = ! empty( $failed['critical'] ) ? '>=' : '>';
-               if ( version_compare( $failed['attempted'], $wp_version, '>=' ) )
+               if ( version_compare( $failed['attempted'], $wp_version, $comparison ) )
                        $nag = true;
        }
 
index b1b85555e3c393d47aed918c3f644bd309ff6f6b..6108d67d99605e403b3ff4bfb4fabc36e0d70f51 100644 (file)
@@ -405,6 +405,9 @@ function upgrade_all() {
        if ( $wp_current_db_version < 25824 )
                upgrade_370();
 
+       if ( $wp_current_db_version < 26148 )
+               upgrade_372();
+
        maybe_disable_link_manager();
 
        maybe_disable_automattic_widgets();
@@ -1222,6 +1225,18 @@ function upgrade_370() {
                wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' );
 }
 
+/**
+ * Execute changes made in WordPress 3.7.2.
+ *
+ * @since 3.7.2
+ * @since 3.8.0
+ */
+function upgrade_372() {
+       global $wp_current_db_version;
+       if ( $wp_current_db_version < 26148 )
+               wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
+}
+
 /**
  * Execute network level changes
  *
index f80719169977cd3f11a0b76c564704af050b9f69..56d8c92d9e37058cc5c20f0aec085e8debec6df2 100644 (file)
@@ -39,13 +39,20 @@ function akismet_load_js_and_css() {
                'plugins_page_akismet-key-config', 
                'jetpack_page_akismet-key-config',
        ) ) ) {
-               wp_register_style( 'akismet.css', AKISMET_PLUGIN_URL . 'akismet.css', array(), '2.5.9' );
+               wp_register_style( 'akismet.css', AKISMET_PLUGIN_URL . 'akismet.css', array(), AKISMET_VERSION );
                wp_enqueue_style( 'akismet.css');
        
-               wp_register_script( 'akismet.js', AKISMET_PLUGIN_URL . 'akismet.js', array('jquery'), '2.5.9' );
+               wp_register_script( 'akismet.js', AKISMET_PLUGIN_URL . 'akismet.js', array('jquery'), 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' )
+                       'comment_author_url_nonce' => wp_create_nonce( 'comment_author_url_nonce' ),
+                       'strings' => array(
+                               'Remove this URL' => __( 'Remove this URL' ),
+                               'Removing...' => __( 'Removing...' ),
+                               'URL removed' => __( 'URL removed' ),
+                               '(undo)' => __( '(undo)' ),
+                               'Re-adding...' => __( 'Re-adding...' ),
+                       )
                ) );
        }
 }
@@ -335,11 +342,7 @@ function akismet_stats() {
        $path = plugin_basename(__FILE__);
        echo '<h3>' . _x( 'Spam', 'comments' ) . '</h3>';
        global $submenu;
-       if ( isset( $submenu['edit-comments.php'] ) )
-               $link = 'edit-comments.php';
-       else
-               $link = 'edit.php';
-       echo '<p>'.sprintf( _n( '<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.', '<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.', $count ), 'http://akismet.com/?return=true', clean_url("$link?page=akismet-admin"), number_format_i18n($count) ).'</p>';
+       echo '<p>'.sprintf( _n( '<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.', '<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.', $count ), 'http://akismet.com/?return=true', esc_url( add_query_arg( array( 'page' => 'akismet-admin' ), admin_url( isset( $submenu['edit-comments.php'] ) ? 'edit-comments.php' : 'edit.php' ) ) ), number_format_i18n($count) ).'</p>';
 }
 add_action('activity_box_end', 'akismet_stats');
 
@@ -546,11 +549,11 @@ function akismet_rightnow() {
        global $submenu, $wp_db_version;
 
        if ( 8645 < $wp_db_version  ) // 2.7
-               $link = 'edit-comments.php?comment_status=spam';
+               $link = add_query_arg( array( 'comment_status' => 'spam' ), admin_url( 'edit-comments.php' ) );
        elseif ( isset( $submenu['edit-comments.php'] ) )
-               $link = 'edit-comments.php?page=akismet-admin';
+               $link = add_query_arg( array( 'page' => 'akismet-admin' ), admin_url( 'edit-comments.php' ) );
        else
-               $link = 'edit.php?page=akismet-admin';
+               $link = add_query_arg( array( 'page' => 'akismet-admin' ), admin_url( 'edit.php' ) );
 
        if ( $count = get_option('akismet_spam_count') ) {
                $intro = sprintf( _n(
@@ -581,14 +584,17 @@ add_action('rightnow_end', 'akismet_rightnow');
 
 
 // For WP >= 2.5
-function akismet_check_for_spam_button($comment_status) {
+function akismet_check_for_spam_button( $comment_status ) {
        if ( 'approved' == $comment_status )
                return;
+               
        if ( function_exists('plugins_url') )
-               $link = 'admin.php?action=akismet_recheck_queue';
+               $link = add_query_arg( array( 'action' => 'akismet_recheck_queue' ), admin_url( 'admin.php' ) );
        else
-               $link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
-       echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
+               $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="' . $link . '">' . esc_html__('Check for Spam') . '</a>';
+       echo '<img src="' . esc_url( admin_url( 'images/wpspin_light.gif' ) ) . '" class="checkforspam-spinner" />';
 }
 add_action('manage_comments_nav', 'akismet_check_for_spam_button');
 
@@ -771,8 +777,12 @@ function akismet_recheck_queue() {
 
        if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
                return;
-               
-       $moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
+                                       
+       $paginate = ''; 
+       if ( isset( $_POST['limit'] ) && isset( $_POST['offset'] ) ) { 
+               $paginate = $wpdb->prepare( " LIMIT %d OFFSET %d", array( $_POST['limit'], $_POST['offset'] ) ); 
+       } 
+       $moderation = $wpdb->get_results( "SELECT * FROM {$wpdb->comments} WHERE comment_approved = '0'{$paginate}", ARRAY_A );
        foreach ( (array) $moderation as $c ) {
                $c['user_ip']    = $c['comment_author_IP'];
                $c['user_agent'] = $c['comment_agent'];
@@ -780,7 +790,7 @@ function akismet_recheck_queue() {
                $c['blog']       = get_bloginfo('url');
                $c['blog_lang']  = get_locale();
                $c['blog_charset'] = get_option('blog_charset');
-               $c['permalink']  = get_permalink($c['comment_post_ID']);
+               $c['permalink']    = get_permalink($c['comment_post_ID']);
 
                $c['user_role'] = '';
                if ( isset( $c['user_ID'] ) )
@@ -815,12 +825,20 @@ function akismet_recheck_queue() {
 
                delete_comment_meta( $c['comment_ID'], 'akismet_rechecking' );
        }
-       $redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url( 'edit-comments.php' );
-       wp_safe_redirect( $redirect_to );
-       exit;
+       if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { 
+               wp_send_json( array( 
+                       'processed' => count((array) $moderation), 
+               )); 
+       } 
+       else { 
+               $redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url( 'edit-comments.php' ); 
+               wp_safe_redirect( $redirect_to ); 
+               exit; 
+       }
 }
 
 add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
+add_action('wp_ajax_akismet_recheck_queue', 'akismet_recheck_queue');
 
 // Adds an 'x' link next to author URLs, clicking will remove the author URL and show an undo link
 function akismet_remove_comment_author_url() {
index e96bc8a50663b6f4521fe6941279011cd02e9a40..5126449daa8aa7117ab168332b00d6ae82b3ada0 100644 (file)
@@ -1 +1 @@
-#submitted-on{position:relative}#the-comment-list .author .akismet-user-comment-count{display:inline}#the-comment-list .author a span{text-decoration:none;color:#999}#the-comment-list .remove_url{margin-left:3px;color:#999;padding:2px 3px 2px 0}#the-comment-list .remove_url:hover{color:#A7301F;font-weight:bold;padding:2px 2px 2px 0}#dashboard_recent_comments .akismet-status{display:none}.akismet-status{float:right}.akismet-status a{color:#AAA;font-style:italic}span.comment-link a{text-decoration:underline}span.comment-link:after{content:" "attr(title) " ";color:#aaa;text-decoration:none}.mshot-arrow{width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent;border-right:10px solid #5C5C5C;position:absolute;left:-6px;top:91px}.mshot-container{background:#5C5C5C;position:absolute;top:-94px;padding:7px;width:450px;height:338px;z-index:20000;-moz-border-radius:6px;border-radius:6px;-webkit-border-radius:6px}h2.ak-header{padding-left:38px;background:url('img/logo.png') no-repeat 0 9px;margin-bottom:14px;line-height:32px}.key-status{padding:0.4em 1em;color:#fff;font-weight:bold;text-align:center;-webkit-border-radius:3px;border-radius:3px;border-width:1px;border-style:solid;max-width:23.3em}input#key{width:25.3em !important}input#key.valid{border-color:#4F800D}input#key.invalid,input#key.failed{border-color:#888}.key-status.under-input{margin-top:-5px;padding-bottom:0px}.key-status.invalid,.key-status.failed{background-color:#888}.key-status.valid{background-color:#4F800D}.key-status.some{background-color:#993300}.key-status.empty{display:none}table.network-status th,table.network-status td{padding:0.4em;margin:0;text-align:center}table.network-status{border-color:#dfdfdf;border-width:0 0 1px 1px;border-style:solid;border-spacing:0;width:25.6em}table.network-status th,table.network-status td{border-color:#dfdfdf;border-width:1px 1px 0 0;border-style:solid;margin:0;border-spacing:0}table.network-status td.key-status{border-radius:0px;-webkit-border-radius:0px}
\ No newline at end of file
+#submitted-on{position:relative}#the-comment-list .author .akismet-user-comment-count{display:inline}#the-comment-list .author a span{text-decoration:none;color:#999}#the-comment-list .remove_url{margin-left:3px;color:#999;padding:2px 3px 2px 0}#the-comment-list .remove_url:hover{color:#A7301F;font-weight:bold;padding:2px 2px 2px 0}#dashboard_recent_comments .akismet-status{display:none}.akismet-status{float:right}.akismet-status a{color:#AAA;font-style:italic}span.comment-link a{text-decoration:underline}span.comment-link:after{content:" "attr(title) " ";color:#aaa;text-decoration:none}.mshot-arrow{width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent;border-right:10px solid #5C5C5C;position:absolute;left:-6px;top:91px}.mshot-container{background:#5C5C5C;position:absolute;top:-94px;padding:7px;width:450px;height:338px;z-index:20000;-moz-border-radius:6px;border-radius:6px;-webkit-border-radius:6px}h2.ak-header{padding-left:38px;background:url('img/logo.png') no-repeat 0 9px;margin-bottom:14px;line-height:32px}.key-status{padding:0.4em 1em;color:#fff;font-weight:bold;text-align:center;-webkit-border-radius:3px;border-radius:3px;border-width:1px;border-style:solid;max-width:23.3em}input#key{width:25.3em !important}input#key.valid{border-color:#4F800D}input#key.invalid,input#key.failed{border-color:#888}.key-status.under-input{margin-top:-5px;padding-bottom:0px}.key-status.invalid,.key-status.failed{background-color:#888}.key-status.valid{background-color:#4F800D}.key-status.some{background-color:#993300}.key-status.empty{display:none}table.network-status th,table.network-status td{padding:0.4em;margin:0;text-align:center}table.network-status{border-color:#dfdfdf;border-width:0 0 1px 1px;border-style:solid;border-spacing:0;width:25.6em}table.network-status th,table.network-status td{border-color:#dfdfdf;border-width:1px 1px 0 0;border-style:solid;margin:0;border-spacing:0}table.network-status td.key-status{border-radius:0px;-webkit-border-radius:0px}.checkforspam{display:inline-block !important;}.checkforspam-spinner{display:none;margin-top:10px;}
\ No newline at end of file
index f3da8fd6d1d6e3525012625d66bc5636a73e6cec..2db61ebfb2d191d6f8c51876d18b26c35108280d 100644 (file)
-jQuery(document).ready(function () {
-       jQuery( '.switch-have-key' ).click( function() {
-               var no_key = jQuery( this ).parents().find('div.no-key');               
-               var have_key = jQuery( this ).parents().find('div.have-key');
+jQuery( function ( $ ) {
+       $( '.switch-have-key' ).click( function() {
+               var no_key = $( this ).parents().find('div.no-key');            
+               var have_key = $( this ).parents().find('div.have-key');
                
                no_key.addClass( 'hidden' );
                have_key.removeClass( 'hidden' );               
                
                return false;
        });
-       jQuery( 'p.need-key a' ).click( function(){
+       $( 'p.need-key a' ).click( function(){
                document.akismet_activate.submit();
        });
-       jQuery('.akismet-status').each(function () {
-               var thisId = jQuery(this).attr('commentid');
-               jQuery(this).prependTo('#comment-' + thisId + ' .column-comment div:first-child');
+       $('.akismet-status').each(function () {
+               var thisId = $(this).attr('commentid');
+               $(this).prependTo('#comment-' + thisId + ' .column-comment div:first-child');
        });
-       jQuery('.akismet-user-comment-count').each(function () {
-               var thisId = jQuery(this).attr('commentid');
-               jQuery(this).insertAfter('#comment-' + thisId + ' .author strong:first').show();
+       $('.akismet-user-comment-count').each(function () {
+               var thisId = $(this).attr('commentid');
+               $(this).insertAfter('#comment-' + thisId + ' .author strong:first').show();
        });
-       jQuery('#the-comment-list tr.comment .column-author a[title ^= "http://"]').each(function () {
-               var thisTitle = jQuery(this).attr('title');
-                   thisCommentId = jQuery(this).parents('tr:first').attr('id').split("-");
+       $('#the-comment-list').find('tr.comment, tr[id ^= "comment-"]').find('.column-author a[title ^= "http://"]').each(function () {
+               var thisTitle = $(this).attr('title');
+                   thisCommentId = $(this).parents('tr:first').attr('id').split("-");
                
-               jQuery(this).attr("id", "author_comment_url_"+ thisCommentId[1]);
+               $(this).attr("id", "author_comment_url_"+ thisCommentId[1]);
                
                if (thisTitle) {
-                       jQuery(this).after(' <a href="#" class="remove_url" commentid="'+ thisCommentId[1] +'" title="Remove this URL">x</a>');
+                       $(this).after(
+                               $( '<a href="#" class="remove_url">x</a>' )
+                                       .attr( 'commentid', thisCommentId[1] )
+                                       .attr( 'title', WPAkismet.strings['Remove this URL'] )
+                       );
                }
        });
-       jQuery('.remove_url').live('click', function () {
-               var thisId = jQuery(this).attr('commentid');
+       $('.remove_url').live('click', function () {
+               var thisId = $(this).attr('commentid');
                var data = {
                        action: 'comment_author_deurl',
                        _wpnonce: WPAkismet.comment_author_url_nonce,
                        id: thisId
                };
-               jQuery.ajax({
+               $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: data,
                    beforeSend: function () {
                        // Removes "x" link
-                               jQuery("a[commentid='"+ thisId +"']").hide();
+                               $("a[commentid='"+ thisId +"']").hide();
                                // Show temp status
-                       jQuery("#author_comment_url_"+ thisId).html('<span>Removing...</span>');
+                       $("#author_comment_url_"+ thisId).html( $( '<span/>' ).text( WPAkismet.strings['Removing...'] ) );
                    },
                    success: function (response) {
                        if (response) {
                                        // Show status/undo link
-                                       jQuery("#author_comment_url_"+ thisId).attr('cid', thisId).addClass('akismet_undo_link_removal').html('<span>URL removed (</span>undo<span>)</span>');
-                               }
+                                       $("#author_comment_url_"+ thisId)
+                                               .attr('cid', thisId)
+                                               .addClass('akismet_undo_link_removal')
+                                               .html(
+                                                       $( '<span/>' ).text( WPAkismet.strings['URL removed'] )
+                                               )
+                                               .append( ' ' )
+                                               .append(
+                                                       $( '<span/>' )
+                                                               .text( WPAkismet.strings['(undo)'] )
+                                                               .addClass( 'akismet-span-link' )
+                                               );
+                               }
                    }
                });
 
                return false;
        });
-       jQuery('.akismet_undo_link_removal').live('click', function () {
-               var thisId = jQuery(this).attr('cid');
-               var thisUrl = jQuery(this).attr('href').replace("http://www.", "").replace("http://", "");
+       $('.akismet_undo_link_removal').live('click', function () {
+               var thisId = $(this).attr('cid');
+               var thisUrl = $(this).attr('href').replace("http://www.", "").replace("http://", "");
                var data = {
                        action: 'comment_author_reurl',
                        _wpnonce: WPAkismet.comment_author_url_nonce,
                        id: thisId,
                        url: thisUrl
                };
-               jQuery.ajax({
+               $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: data,
                    beforeSend: function () {
                                // Show temp status
-                       jQuery("#author_comment_url_"+ thisId).html('<span>Re-adding…</span>');
+                       $("#author_comment_url_"+ thisId).html( $( '<span/>' ).text( WPAkismet.strings['Re-adding...'] ) );
                    },
                    success: function (response) {
                        if (response) {
                                        // Add "x" link
-                                       jQuery("a[commentid='"+ thisId +"']").show();
+                                       $("a[commentid='"+ thisId +"']").show();
                                        // Show link
-                                       jQuery("#author_comment_url_"+ thisId).removeClass('akismet_undo_link_removal').html(thisUrl);
+                                       $("#author_comment_url_"+ thisId).removeClass('akismet_undo_link_removal').html(thisUrl);
                                }
                    }
                });
                
                return false;
        });
-       jQuery('a[id^="author_comment_url"]').mouseover(function () {
+       $('a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type').mouseover(function () {
                var wpcomProtocol = ( 'https:' === location.protocol ) ? 'https://' : 'http://';
                // Need to determine size of author column
-               var thisParentWidth = jQuery(this).parent().width();
+               var thisParentWidth = $(this).parent().width();
                // It changes based on if there is a gravatar present
-               thisParentWidth = (jQuery(this).parent().find('.grav-hijack').length) ? thisParentWidth - 42 + 'px' : thisParentWidth + 'px';
-               if (jQuery(this).find('.mShot').length == 0 && !jQuery(this).hasClass('akismet_undo_link_removal')) {
-                       var thisId = jQuery(this).attr('id').replace('author_comment_url_', '');
-                       jQuery('.widefat td').css('overflow', 'visible');
-                       jQuery(this).css('position', 'relative');
-                       var thisHref = jQuery.URLEncode(jQuery(this).attr('href'));
-                       jQuery(this).append('<div class="mShot mshot-container" style="left: '+thisParentWidth+'"><div class="mshot-arrow"></div><img src="'+wpcomProtocol+'s0.wordpress.com/mshots/v1/'+thisHref+'?w=450" width="450" class="mshot-image_'+thisId+'" style="margin: 0;" /></div>');
+               thisParentWidth = ($(this).parent().find('.grav-hijack').length) ? thisParentWidth - 42 + 'px' : thisParentWidth + 'px';
+               if ($(this).find('.mShot').length == 0 && !$(this).hasClass('akismet_undo_link_removal')) {
+                       var self = $( this );
+                       $('.widefat td').css('overflow', 'visible');
+                       $(this).css('position', 'relative');
+                       var thisHref = $.URLEncode( $(this).attr('href') );
+                       $(this).append('<div class="mShot mshot-container" style="left: '+thisParentWidth+'"><div class="mshot-arrow"></div><img src="//s0.wordpress.com/mshots/v1/'+thisHref+'?w=450" width="450" class="mshot-image" style="margin: 0;" /></div>');
                        setTimeout(function () {
-                               jQuery('.mshot-image_'+thisId).attr('src', wpcomProtocol+'s0.wordpress.com/mshots/v1/'+thisHref+'?w=450&r=2');
+                               self.find( '.mshot-image' ).attr('src', '//s0.wordpress.com/mshots/v1/'+thisHref+'?w=450&r=2');
                        }, 6000);
                        setTimeout(function () {
-                               jQuery('.mshot-image_'+thisId).attr('src', wpcomProtocol+'s0.wordpress.com/mshots/v1/'+thisHref+'?w=450&r=3');
+                               self.find( '.mshot-image' ).attr('src', '//s0.wordpress.com/mshots/v1/'+thisHref+'?w=450&r=3');
                        }, 12000);
                } else {
-                       jQuery(this).find('.mShot').css('left', thisParentWidth).show();
+                       $(this).find('.mShot').css('left', thisParentWidth).show();
                }
        }).mouseout(function () {
-               jQuery(this).find('.mShot').hide();
+               $(this).find('.mShot').hide();
        });
+       $('.checkforspam:not(.button-disabled)').click( function(e) { 
+           $('.checkforspam:not(.button-disabled)').addClass('button-disabled'); 
+               $('.checkforspam-spinner').show(); 
+               akismet_check_for_spam(0, 100); 
+               e.preventDefault(); 
+       });
+       
+       function akismet_check_for_spam(offset, limit) { 
+               $.post( 
+                       ajaxurl, 
+                       { 
+                               'action': 'akismet_recheck_queue', 
+                               'offset': offset, 
+                               'limit': limit 
+                       }, 
+                       function(result) { 
+                               if (result.processed < limit) { 
+                                       window.location.reload(); 
+                               } 
+                               else { 
+                                       akismet_check_for_spam(offset + limit, limit); 
+                               } 
+                       } 
+               ); 
+       }
 });
 // URL encode plugin
 jQuery.extend({URLEncode:function(c){var o='';var x=0;c=c.toString();var r=/(^[a-zA-Z0-9_.]*)/;
@@ -117,10 +157,3 @@ jQuery.extend({URLEncode:function(c){var o='';var x=0;c=c.toString();var r=/(^[a
     }else{if(c[x]==' ')o+='+';else{var d=c.charCodeAt(x);var h=d.toString(16);
     o+='%'+(h.length<2?'0':'')+h.toUpperCase();}x++;}}return o;}
 });
-// Preload mshot images after everything else has loaded
-jQuery(window).load(function() {
-       var wpcomProtocol = ( 'https:' === location.protocol ) ? 'https://' : 'http://';
-       jQuery('a[id^="author_comment_url"]').each(function () {
-               jQuery.get(wpcomProtocol+'s0.wordpress.com/mshots/v1/'+jQuery.URLEncode(jQuery(this).attr('href'))+'?w=450');
-       });
-});
index 919ea0e7596b3677a8438c006e4b2db4ce7f9fcb..4fff8bb684e01ffd8cc9ac01495e4553283f94a5 100644 (file)
@@ -6,7 +6,7 @@
 Plugin Name: Akismet
 Plugin URI: http://akismet.com/?return=true
 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/?return=true">Sign up for an Akismet API key</a>, and 3) Go to your Akismet configuration page, and save your API key.
-Version: 2.5.9
+Version: 2.6.0
 Author: Automattic
 Author URI: http://automattic.com/wordpress-plugins/
 License: GPLv2 or later
@@ -34,8 +34,9 @@ if ( !function_exists( 'add_action' ) ) {
        exit;
 }
 
-define('AKISMET_VERSION', '2.5.9');
+define('AKISMET_VERSION', '2.6.0');
 define('AKISMET_PLUGIN_URL', plugin_dir_url( __FILE__ ));
+define('AKISMET_DELETE_LIMIT', 10000);
 
 /** If you hardcode a WP.com API key here, all key config screens will be hidden */
 if ( defined('WPCOM_API_KEY') )
@@ -197,17 +198,26 @@ function akismet_http_post($request, $host, $path, $port = 80, $ip=null) {
 
 // filter handler used to return a spam result to pre_comment_approved
 function akismet_result_spam( $approved ) {
+       static $just_once = false;
+       if ( $just_once )
+               return $approved;
+               
        // bump the counter here instead of when the filter is added to reduce the possibility of overcounting
        if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
                update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
+               
        // this is a one-shot deal
-       remove_filter( 'pre_comment_approved', 'akismet_result_spam' );
+       $just_once = true;
        return 'spam';
 }
 
 function akismet_result_hold( $approved ) {
+       static $just_once = false;
+       if ( $just_once )
+               return $approved;
+               
        // once only
-       remove_filter( 'pre_comment_approved', 'akismet_result_hold' );
+       $just_once = true;
        return '0';
 }
 
@@ -321,7 +331,7 @@ function akismet_auto_check_comment( $commentdata ) {
        global $akismet_api_host, $akismet_api_port, $akismet_last_comment;
 
        $comment = $commentdata;
-       $comment['user_ip']    = $_SERVER['REMOTE_ADDR'];
+       $comment['user_ip']    = akismet_get_ip_address();
        $comment['user_agent'] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null; 
        $comment['referrer']   = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
        $comment['blog']       = get_option('home');
@@ -422,58 +432,70 @@ function akismet_auto_check_comment( $commentdata ) {
 
 add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
 
+function akismet_get_ip_address() {
+       foreach( array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR' ) as $key ) {
+               if ( array_key_exists( $key, $_SERVER ) === true ) {
+                       foreach ( explode( ',', $_SERVER[$key] ) as $ip ) {
+                               $ip = trim($ip); 
+       
+                               if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false ) {
+                                       return $ip;
+                               }
+                       }
+               }
+       }
+       return null;
+}
+
 function akismet_delete_old() {
        global $wpdb;
-       $now_gmt = current_time('mysql', 1);
-       $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'");
-       if ( empty( $comment_ids ) )
-               return;
+       
+       while( $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_id FROM {$wpdb->comments} WHERE DATE_SUB(NOW(), INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam' LIMIT %d", defined( 'AKISMET_DELETE_LIMIT' ) ? AKISMET_DELETE_LIMIT : 10000 ) ) ) {
+               if ( empty( $comment_ids ) )
+                       return;
                
-       $comma_comment_ids = implode( ', ', array_map('intval', $comment_ids) );
+               $wpdb->queries = array();
 
-       do_action( 'delete_comment', $comment_ids );
-       $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_id IN ( $comma_comment_ids )");
-       $wpdb->query("DELETE FROM $wpdb->commentmeta WHERE comment_id IN ( $comma_comment_ids )");
-       clean_comment_cache( $comment_ids );
-       $n = mt_rand(1, 5000);
-       if ( apply_filters('akismet_optimize_table', ($n == 11)) ) // lucky number
-               $wpdb->query("OPTIMIZE TABLE $wpdb->comments");
+               do_action( 'delete_comment', $comment_ids );
+               
+               $comma_comment_ids = implode( ', ', array_map('intval', $comment_ids) );
+       
+               $wpdb->query("DELETE FROM {$wpdb->comments} WHERE comment_id IN ( $comma_comment_ids )");
+               $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE comment_id IN ( $comma_comment_ids )");
+               
+               clean_comment_cache( $comment_ids );
+       }
 
+       if ( apply_filters( 'akismet_optimize_table', ( mt_rand(1, 5000) == 11) ) ) // lucky number
+               $wpdb->query("OPTIMIZE TABLE {$wpdb->comments}");
 }
 
 function akismet_delete_old_metadata() { 
        global $wpdb; 
 
-       $now_gmt = current_time( 'mysql', 1 ); 
        $interval = apply_filters( 'akismet_delete_commentmeta_interval', 15 );
 
        # enfore a minimum of 1 day
        $interval = absint( $interval );
-       if ( $interval < 1 ) {
-               return;
-       }
+       if ( $interval < 1 )
+               $interval = 1;
 
        // akismet_as_submitted meta values are large, so expire them 
        // after $interval days regardless of the comment status 
-       while ( TRUE ) {
-               $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" ); 
-
-               if ( empty( $comment_ids ) ) {
-                       return; 
-               }
-
+       while ( $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT m.comment_id FROM {$wpdb->commentmeta} as m INNER JOIN {$wpdb->comments} as c USING(comment_id) WHERE m.meta_key = 'akismet_as_submitted' AND DATE_SUB(NOW(), INTERVAL %d DAY) > c.comment_date_gmt LIMIT 10000", $interval ) ) ) {      
+               if ( empty( $comment_ids ) )
+                       return;
+               
+               $wpdb->queries = array();
+               
                foreach ( $comment_ids as $comment_id ) {
                        delete_comment_meta( $comment_id, 'akismet_as_submitted' );
                }
        }
-
-       /*
-       $n = mt_rand( 1, 5000 ); 
-       if ( apply_filters( 'akismet_optimize_table', ( $n == 11 ), 'commentmeta' ) ) { // lucky number 
-               $wpdb->query( "OPTIMIZE TABLE $wpdb->commentmeta" ); 
-       }
-       */
-} 
+       
+       if ( apply_filters( 'akismet_optimize_table', ( mt_rand(1, 5000) == 11) ) ) // lucky number
+               $wpdb->query("OPTIMIZE TABLE {$wpdb->comments}");
+}
 
 add_action('akismet_scheduled_delete', 'akismet_delete_old');
 add_action('akismet_scheduled_delete', 'akismet_delete_old_metadata'); 
@@ -588,6 +610,71 @@ $akismet_comment_nonce_option = apply_filters( 'akismet_comment_nonce', get_opti
 if ( $akismet_comment_nonce_option == 'true' || $akismet_comment_nonce_option == '' )
        add_action( 'comment_form', 'akismet_add_comment_nonce' );
 
+function akismet_pingback_forwarded_for( $r, $url ) {
+       static $urls = array();
+       
+       // Call this with $r == null to prime the callback to add headers on a specific URL
+       if ( is_null( $r ) && !in_array( $url, $urls ) ) {
+               $urls[] = $url;
+       }
+
+       // Add X-Pingback-Forwarded-For header, but only for requests to a specific URL (the apparent pingback source)
+       if ( is_array( $r ) && is_array( $r['headers'] ) && !isset( $r['headers']['X-Pingback-Forwarded-For'] ) && in_array( $url, $urls ) ) {
+               $remote_ip = preg_replace( '/[^a-fx0-9:.,]/i', '', $_SERVER['REMOTE_ADDR'] );
+               
+               // Note: this assumes REMOTE_ADDR is correct, and it may not be if a reverse proxy or CDN is in use
+               $r['headers']['X-Pingback-Forwarded-For'] = $remote_ip;
+
+               // Also identify the request as a pingback verification in the UA string so it appears in logs
+               $r['user-agent'] .= '; verifying pingback from ' . $remote_ip;
+       }
+
+       return $r;
+}
+
+function akismet_pre_check_pingback( $method ) {
+       
+       if ( $method !== 'pingback.ping' )
+               return;
+
+       global $wp_xmlrpc_server;
+       
+       if ( !is_object( $wp_xmlrpc_server ) )
+               return false;
+       
+       // Lame: tightly coupled with the IXR class.
+       $args = $wp_xmlrpc_server->message->params;
+       
+       if ( !empty( $args[1] ) ) {
+               $post_id = url_to_postid( $args[1] );
+
+               // If this gets through the pre-check, make sure we properly identify the outbound request as a pingback verification
+               akismet_pingback_forwarded_for( null, $args[0] );
+               add_filter( 'http_request_args', 'akismet_pingback_forwarded_for', 10, 2 );
+
+               $comment = array(
+                       'comment_author_url' => $args[0],
+                       'comment_post_ID' => $post_id,
+                       'comment_author' => '',
+                       'comment_author_email' => '',
+                       'comment_content' => '',
+                       'comment_type' => 'pingback',
+                       'akismet_pre_check' => '1',
+                       'comment_pingback_target' => $args[1],
+               );
+
+               $comment = akismet_auto_check_comment( $comment );
+
+               if ( isset( $comment['akismet_result'] ) && 'true' == $comment['akismet_result'] ) {
+                       // Lame: tightly coupled with the IXR classes. Unfortunately the action provides no context and no way to return anything.
+                       $wp_xmlrpc_server->error( new IXR_Error( 0, 'Invalid discovery target' ) );
+               }
+       }
+}
+
+// Run this early in the pingback call, before doing a remote fetch of the source uri
+add_action( 'xmlrpc_call', 'akismet_pre_check_pingback' );
+
 global $wp_version;
 if ( '3.0.5' == $wp_version ) { 
        remove_filter( 'comment_text', 'wp_kses_data' ); 
index d0094d2029c0e57b6b067b65cae2bfe351691a24..fca32ab73f937836ee34fa31b986d0f911ee0066 100644 (file)
@@ -2,8 +2,8 @@
 Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, automattic
 Tags: akismet, comments, spam
 Requires at least: 3.0
-Tested up to: 3.6
-Stable tag: 2.5.9
+Tested up to: 3.8.1
+Stable tag: 2.6.0
 License: GPLv2 or later
 
 Akismet checks your comments against the Akismet web service to see if they look like spam or not.
@@ -31,6 +31,14 @@ Upload the Akismet plugin to your blog, Activate it, then enter your [Akismet.co
 
 == Changelog ==
 
+= 2.6.0 =
+* Add ajax paging to the check for spam button to handle large volumes of comments
+* Optimize javascript and add localization support 
+* Fix bug in link to spam comments from right now dashboard widget
+* Fix bug with deleting old comments to avoid timeouts dealing with large volumes of comments
+* Include X-Pingback-Forwarded-For header in outbound WordPress pingback verifications
+* Add pre-check for pingbacks, to stop spam before an outbound verification request is made
+
 = 2.5.9 =
 * Update 'Already have a key' link to redirect page rather than depend on javascript
 * Fix some non-translatable strings to be translatable
index 0d8f53de42cd3c55c1e83bbfc1e9b4c244c084ca..d252bf262e2fe62f1d8b8e65ee625e35df3220cc 100644 (file)
@@ -1,14 +1,14 @@
-# Copyright (C) 2013 the WordPress team
+# Copyright (C) 2014 the WordPress team
 # This file is distributed under the GNU General Public License v2 or later.
 msgid ""
 msgstr ""
 "Project-Id-Version: Twenty Thirteen 1.1\n"
 "Report-Msgid-Bugs-To: http://wordpress.org/tags/twentythirteen\n"
-"POT-Creation-Date: 2013-10-24 20:32:07+00:00\n"
+"POT-Creation-Date: 2014-03-18 19:16:26+00:00\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2013-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 
index a504372e6547f7c00b0d4ed68343cbde985ccd71..4f35f4ab6098a35ef0aa20c17430393b528d7c2f 100644 (file)
@@ -1,14 +1,14 @@
-# Copyright (C) 2013 the WordPress team
+# Copyright (C) 2014 the WordPress team
 # This file is distributed under the GNU General Public License v2 or later.
 msgid ""
 msgstr ""
 "Project-Id-Version: Twenty Twelve 1.3\n"
 "Report-Msgid-Bugs-To: http://wordpress.org/tags/twentytwelve\n"
-"POT-Creation-Date: 2013-10-24 20:32:05+00:00\n"
+"POT-Creation-Date: 2014-03-18 19:16:25+00:00\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2013-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 
index 9a3ac6107c2526e304c9f42c8279d057733c8341..04beff373b69e3e3c7325b5ff82c69c785b17caf 100644 (file)
@@ -208,8 +208,8 @@ function get_bookmarks($args = '') {
                $join = " INNER JOIN $wpdb->term_relationships AS tr ON ($wpdb->links.link_id = tr.object_id) INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id";
        }
 
-       if ( $show_updated && get_option('links_recently_updated_time') ) {
-               $recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL " . get_option('links_recently_updated_time') . " MINUTE) >= NOW(), 1,0) as recently_updated ";
+       if ( $show_updated ) {
+               $recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated ";
        } else {
                $recently_updated_test = '';
        }
index d3ebdb8bb3ab2cc7604794505ced0f0434e26c22..5b5081193ffb714e60f9df7c3649e470c5cc322f 100644 (file)
@@ -5391,11 +5391,18 @@ class wp_xmlrpc_server extends IXR_Server {
                // very stupid, but gives time to the 'from' server to publish !
                sleep(1);
 
+               $remote_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'] );
+               $user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . $GLOBALS['wp_version'] . '; ' . get_bloginfo( 'url' ) );
+
                // Let's check the remote site
                $http_api_args = array(
                        'timeout' => 10,
                        'redirection' => 0,
                        'limit_response_size' => 153600, // 150 KB
+                       'user-agent' => "$user_agent; verifying pingback from $remote_ip",
+                       'headers' => array(
+                               'X-Pingback-Forwarded-For' => $remote_ip,
+                       ),
                );
                $linea = wp_remote_retrieve_body( wp_safe_remote_get( $pagelinkedfrom, $http_api_args ) );
 
index 6668dc546e292ce77f9d859762d1798451340b48..1c68e146cf24902030c6537cf9d59b0a0064b299 100644 (file)
@@ -160,8 +160,19 @@ function wp_clear_scheduled_hook( $hook, $args = array() ) {
                $args = array_slice( func_get_args(), 1 );
        }
 
-       while ( $timestamp = wp_next_scheduled( $hook, $args ) )
-               wp_unschedule_event( $timestamp, $hook, $args );
+       // This logic duplicates wp_next_scheduled()
+       // It's required due to a scenario where wp_unschedule_event() fails due to update_option() failing,
+       // and, wp_next_scheduled() returns the same schedule in an infinite loop.
+       $crons = _get_cron_array();
+       if ( empty( $crons ) )
+               return;
+
+       $key = md5( serialize( $args ) );
+       foreach ( $crons as $timestamp => $cron ) {
+               if ( isset( $cron[ $hook ][ $key ] ) ) {
+                       wp_unschedule_event( $timestamp, $hook, $args );
+               }
+       }
 }
 
 /**
index aea813b7d007880cd447594a51bae0832ff543d0..c9db0910090a0f7e673047803d24acedcbbb9f0b 100644 (file)
@@ -1372,14 +1372,23 @@ function wp_mkdir_p( $target ) {
        }
 
        // Get the permission bits.
-       if ( $target_parent && '.' != $target_parent ) {
-               $stat = @stat( $target_parent );
+       $dir_perms = false;
+       if ( $stat = @stat( $target_parent ) ) {
                $dir_perms = $stat['mode'] & 0007777;
        } else {
                $dir_perms = 0777;
        }
 
        if ( @mkdir( $target, $dir_perms, true ) ) {
+
+               // If a umask is set that modifies $dir_perms, we'll have to re-set the $dir_perms correctly with chmod()
+               if ( $dir_perms != ( $dir_perms & ~umask() ) ) {
+                       $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
+                       for ( $i = 1; $i <= count( $folder_parts ); $i++ ) {
+                               @chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
+                       }
+               }
+
                return true;
        }
 
index e1584d3b1a9960ed66af1d9b9980126bceb5cc70..20c8fd82bd140c4ac7f54bbf73598a935e26cc77 100644 (file)
Binary files a/wp-includes/js/plupload/plupload.silverlight.xap and b/wp-includes/js/plupload/plupload.silverlight.xap differ
index 6f7a3a6059df8fc289490e063cfdfbe4d2a637f7..ec30231d5ebae0b481ee00a0e689cd05cb3c94cc 100644 (file)
@@ -757,7 +757,8 @@ function get_site_option( $option, $default = false, $use_cache = true ) {
                return $pre;
 
        // prevent non-existent options from triggering multiple queries
-       $notoptions = wp_cache_get( 'notoptions', 'site-options' );
+       $notoptions_key = "{$wpdb->siteid}:notoptions";
+       $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
        if ( isset( $notoptions[$option] ) )
                return apply_filters( 'default_site_option_' . $option, $default );
 
@@ -779,7 +780,7 @@ function get_site_option( $option, $default = false, $use_cache = true ) {
                                wp_cache_set( $cache_key, $value, 'site-options' );
                        } else {
                                $notoptions[$option] = true;
-                               wp_cache_set( 'notoptions', $notoptions, 'site-options' );
+                               wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
                                $value = apply_filters( 'default_site_option_' . $option, $default );
                        }
                }
@@ -812,6 +813,7 @@ function add_site_option( $option, $value ) {
        wp_protect_special_option( $option );
 
        $value = apply_filters( 'pre_add_site_option_' . $option, $value );
+       $notoptions_key = "{$wpdb->siteid}:notoptions";
 
        if ( !is_multisite() ) {
                $result = add_option( $option, $value );
@@ -819,7 +821,7 @@ function add_site_option( $option, $value ) {
                $cache_key = "{$wpdb->siteid}:$option";
 
                // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query
-               $notoptions = wp_cache_get( 'notoptions', 'site-options' );
+               $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
                if ( ! is_array( $notoptions ) || ! isset( $notoptions[$option] ) )
                        if ( false !== get_site_option( $option ) )
                                return false;
@@ -835,10 +837,10 @@ function add_site_option( $option, $value ) {
                wp_cache_set( $cache_key, $value, 'site-options' );
 
                // This option exists now
-               $notoptions = wp_cache_get( 'notoptions', 'site-options' ); // yes, again... we need it to be fresh
+               $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); // yes, again... we need it to be fresh
                if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) {
                        unset( $notoptions[$option] );
-                       wp_cache_set( 'notoptions', $notoptions, 'site-options' );
+                       wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
                }
        }
 
@@ -922,10 +924,11 @@ function update_site_option( $option, $value ) {
        if ( false === $old_value )
                return add_site_option( $option, $value );
 
-       $notoptions = wp_cache_get( 'notoptions', 'site-options' );
+       $notoptions_key = "{$wpdb->siteid}:notoptions";
+       $notoptions = wp_cache_get( $notoptions_key, 'site-options' );
        if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) {
                unset( $notoptions[$option] );
-               wp_cache_set( 'notoptions', $notoptions, 'site-options' );
+               wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
        }
 
        if ( !is_multisite() ) {
index 6839b015ac4c9239a9517d2f54712f9781183eea..e340fc725c50f5da2e3801aed7a3e1c0d8ef0890 100644 (file)
@@ -546,7 +546,7 @@ function wp_validate_auth_cookie($cookie = '', $scheme = '') {
        $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);
        $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
 
-       if ( $hmac != $hash ) {
+       if ( hash_hmac( 'md5', $hmac, $key ) !== hash_hmac( 'md5', $hash, $key ) ) {
                do_action('auth_cookie_bad_hash', $cookie_elements);
                return false;
        }
index bc666fd22508b6bf33e279e7fea49d194a2b0e53..de335a04c9e7696f2e6c0bb2d2adfcc1b6a55601 100644 (file)
@@ -160,9 +160,10 @@ function wp_version_check( $extra_stats = array() ) {
  * @since 2.3.0
  * @uses $wp_version Used to notify the WordPress version.
  *
+ * @param array $extra_stats Extra statistics to report to the WordPress.org API.
  * @return mixed Returns null if update is unsupported. Returns false if check is too soon.
  */
-function wp_update_plugins() {
+function wp_update_plugins( $extra_stats = array() ) {
        include ABSPATH . WPINC . '/version.php'; // include an unmodified $wp_version
 
        if ( defined('WP_INSTALLING') )
@@ -201,7 +202,7 @@ function wp_update_plugins() {
 
        $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
 
-       if ( $time_not_changed ) {
+       if ( $time_not_changed && ! $extra_stats ) {
                $plugin_changed = false;
                foreach ( $plugins as $file => $p ) {
                        $new_option->checked[ $file ] = $p['Version'];
@@ -250,6 +251,10 @@ function wp_update_plugins() {
                'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
        );
 
+       if ( $extra_stats ) {
+               $options['body']['update_stats'] = json_encode( $extra_stats );
+       }
+
        $url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/';
        if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
                $url = set_url_scheme( $url, 'https' );
@@ -291,9 +296,10 @@ function wp_update_plugins() {
  * @since 2.7.0
  * @uses $wp_version Used to notify the WordPress version.
  *
+ * @param array $extra_stats Extra statistics to report to the WordPress.org API.
  * @return mixed Returns null if update is unsupported. Returns false if check is too soon.
  */
-function wp_update_themes() {
+function wp_update_themes( $extra_stats = array() ) {
        include ABSPATH . WPINC . '/version.php'; // include an unmodified $wp_version
 
        if ( defined( 'WP_INSTALLING' ) )
@@ -343,7 +349,7 @@ function wp_update_themes() {
 
        $time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time() - $last_update->last_checked );
 
-       if ( $time_not_changed ) {
+       if ( $time_not_changed && ! $extra_stats ) {
                $theme_changed = false;
                foreach ( $checked as $slug => $v ) {
                        if ( !isset( $last_update->checked[ $slug ] ) || strval($last_update->checked[ $slug ]) !== strval($v) )
@@ -390,6 +396,10 @@ function wp_update_themes() {
                'user-agent'    => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
        );
 
+       if ( $extra_stats ) {
+               $options['body']['update_stats'] = json_encode( $extra_stats );
+       }
+
        $url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';
        if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
                $url = set_url_scheme( $url, 'https' );
@@ -584,6 +594,8 @@ function wp_schedule_update_checks() {
                        $next += 12 * HOUR_IN_SECONDS;
                }
                $next = $next - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
+               // Add a random number of minutes, so we don't have all sites trying to update exactly on the hour
+               $next = $next + rand( 0, 59 ) * MINUTE_IN_SECONDS;
                wp_schedule_event( $next, 'twicedaily', 'wp_maybe_auto_update' );
        }
 }
@@ -600,14 +612,14 @@ add_action( 'load-update.php', 'wp_update_plugins' );
 add_action( 'load-update-core.php', 'wp_update_plugins' );
 add_action( 'admin_init', '_maybe_update_plugins' );
 add_action( 'wp_update_plugins', 'wp_update_plugins' );
-add_action( 'upgrader_process_complete', 'wp_update_plugins' );
+add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
 
 add_action( 'load-themes.php', 'wp_update_themes' );
 add_action( 'load-update.php', 'wp_update_themes' );
 add_action( 'load-update-core.php', 'wp_update_themes' );
 add_action( 'admin_init', '_maybe_update_themes' );
 add_action( 'wp_update_themes', 'wp_update_themes' );
-add_action( 'upgrader_process_complete', 'wp_update_themes' );
+add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
 
 add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
 
index 7aed0355034bff5bb966b7bf1e0c6c940d38fcd7..a42664daf9644f08575018faf99516f6bde80d11 100644 (file)
@@ -4,14 +4,14 @@
  *
  * @global string $wp_version
  */
-$wp_version = '3.7.1';
+$wp_version = '3.7.2';
 
 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
  *
  * @global int $wp_db_version
  */
-$wp_db_version = 25824;
+$wp_db_version = 26148;
 
 /**
  * Holds the TinyMCE version