diff --git a/src/wp-includes/class-wp.php b/src/wp-includes/class-wp.php
index cac538d6cd..c62d79082b 100644
--- a/src/wp-includes/class-wp.php
+++ b/src/wp-includes/class-wp.php
@@ -422,22 +422,30 @@ class WP {
}
$headers['Content-Type'] = feed_content_type( $type ) . '; charset=' . get_option( 'blog_charset' );
- // We're showing a feed, so WP is indeed the only thing that last changed
- if ( !empty($this->query_vars['withcomments'])
- || false !== strpos( $this->query_vars['feed'], 'comments-' )
- || ( empty($this->query_vars['withoutcomments'])
- && ( !empty($this->query_vars['p'])
- || !empty($this->query_vars['name'])
- || !empty($this->query_vars['page_id'])
- || !empty($this->query_vars['pagename'])
- || !empty($this->query_vars['attachment'])
- || !empty($this->query_vars['attachment_id'])
- )
- )
- )
- $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastcommentmodified('GMT'), 0).' GMT';
- else
- $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT';
+ // We're showing a feed, so WP is indeed the only thing that last changed.
+ if ( ! empty( $this->query_vars['withcomments'] )
+ || false !== strpos( $this->query_vars['feed'], 'comments-' )
+ || ( empty( $this->query_vars['withoutcomments'] )
+ && ( ! empty( $this->query_vars['p'] )
+ || ! empty( $this->query_vars['name'] )
+ || ! empty( $this->query_vars['page_id'] )
+ || ! empty( $this->query_vars['pagename'] )
+ || ! empty( $this->query_vars['attachment'] )
+ || ! empty( $this->query_vars['attachment_id'] )
+ )
+ )
+ ) {
+ $wp_last_modified = mysql2date( 'D, d M Y H:i:s', get_lastcommentmodified( 'GMT' ), false );
+ } else {
+ $wp_last_modified = mysql2date( 'D, d M Y H:i:s', get_lastpostmodified( 'GMT' ), false );
+ }
+
+ if ( ! $wp_last_modified ) {
+ $wp_last_modified = date( 'D, d M Y H:i:s' );
+ }
+
+ $wp_last_modified .= ' GMT';
+
$wp_etag = '"' . md5($wp_last_modified) . '"';
$headers['Last-Modified'] = $wp_last_modified;
$headers['ETag'] = $wp_etag;
diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php
index 49ddda8b6d..7da516266f 100644
--- a/src/wp-includes/comment.php
+++ b/src/wp-includes/comment.php
@@ -293,38 +293,46 @@ function get_default_comment_status( $post_type = 'post', $comment_type = 'comme
* The date the last comment was modified.
*
* @since 1.5.0
+ * @since 4.7.0 Replaced caching the modified date in a local static variable
+ * with the Object Cache API.
*
* @global wpdb $wpdb WordPress database abstraction object.
- * @staticvar array $cache_lastcommentmodified
*
- * @param string $timezone Which timezone to use in reference to 'gmt', 'blog',
- * or 'server' locations.
- * @return string Last comment modified date.
+ * @param string $timezone Which timezone to use in reference to 'gmt', 'blog', or 'server' locations.
+ * @return string|false Last comment modified date on success, false on failure.
*/
-function get_lastcommentmodified($timezone = 'server') {
+function get_lastcommentmodified( $timezone = 'server' ) {
global $wpdb;
- static $cache_lastcommentmodified = array();
- if ( isset($cache_lastcommentmodified[$timezone]) )
- return $cache_lastcommentmodified[$timezone];
+ $timezone = strtolower( $timezone );
+ $key = "lastcommentmodified:$timezone";
- $add_seconds_server = date('Z');
+ $comment_modified_date = wp_cache_get( $key, 'timeinfo' );
+ if ( false !== $comment_modified_date ) {
+ return $comment_modified_date;
+ }
- switch ( strtolower($timezone)) {
+ switch ( $timezone ) {
case 'gmt':
- $lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1");
+ $comment_modified_date = $wpdb->get_var( "SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1" );
break;
case 'blog':
- $lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1");
+ $comment_modified_date = $wpdb->get_var( "SELECT comment_date FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1" );
break;
case 'server':
- $lastcommentmodified = $wpdb->get_var($wpdb->prepare("SELECT DATE_ADD(comment_date_gmt, INTERVAL %s SECOND) FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1", $add_seconds_server));
+ $add_seconds_server = date( 'Z' );
+
+ $comment_modified_date = $wpdb->get_var( $wpdb->prepare( "SELECT DATE_ADD(comment_date_gmt, INTERVAL %s SECOND) FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1", $add_seconds_server ) );
break;
}
- $cache_lastcommentmodified[$timezone] = $lastcommentmodified;
+ if ( $comment_modified_date ) {
+ wp_cache_set( $key, $comment_modified_date, 'timeinfo' );
- return $lastcommentmodified;
+ return $comment_modified_date;
+ }
+
+ return false;
}
/**
@@ -1572,6 +1580,26 @@ function wp_transition_comment_status($new_status, $old_status, $comment) {
do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment );
}
+/**
+ * Clear the lastcommentmodified cached value when a comment status is changed.
+ *
+ * Deletes the lastcommentmodified cache key when a comment enters or leaves
+ * 'approved' status.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @param string $new_status The new comment status.
+ * @param string $old_status The old comment status.
+ */
+function _clear_modified_cache_on_transition_comment_status( $new_status, $old_status ) {
+ if ( 'approved' === $new_status || 'approved' === $old_status ) {
+ foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
+ wp_cache_delete( "lastcommentmodified:$timezone", 'timeinfo' );
+ }
+ }
+}
+
/**
* Get current commenter's name, email, and URL.
*
@@ -1681,6 +1709,10 @@ function wp_insert_comment( $commentdata ) {
if ( $comment_approved == 1 ) {
wp_update_comment_count( $comment_post_ID );
+
+ foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
+ wp_cache_delete( "lastcommentmodified:$timezone", 'timeinfo' );
+ }
}
clean_comment_cache( $id );
diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php
index 71255c3497..323e55e840 100644
--- a/src/wp-includes/default-filters.php
+++ b/src/wp-includes/default-filters.php
@@ -214,6 +214,8 @@ add_filter( 'pingback_ping_source_uri', 'pingback_ping_source_uri' );
add_filter( 'xmlrpc_pingback_error', 'xmlrpc_pingback_error' );
add_filter( 'title_save_pre', 'trim' );
+add_action( 'transition_comment_status', '_clear_modified_cache_on_transition_comment_status', 10, 2 );
+
add_filter( 'http_request_host_is_external', 'allowed_http_request_hosts', 10, 2 );
// REST API filters.
diff --git a/src/wp-includes/feed-atom-comments.php b/src/wp-includes/feed-atom-comments.php
index e5c7089164..5b494a2992 100644
--- a/src/wp-includes/feed-atom-comments.php
+++ b/src/wp-includes/feed-atom-comments.php
@@ -37,7 +37,10 @@ do_action( 'rss_tag_pre', 'atom-comments' );
?>