diff --git a/src/wp-includes/feed-atom-comments.php b/src/wp-includes/feed-atom-comments.php index 64e26aa2fd..fe92ed71fa 100644 --- a/src/wp-includes/feed-atom-comments.php +++ b/src/wp-includes/feed-atom-comments.php @@ -45,7 +45,7 @@ do_action( 'rss_tag_pre', 'atom-comments' ); diff --git a/src/wp-includes/feed-atom.php b/src/wp-includes/feed-atom.php index 73cfda1e5b..a30ae3e3b1 100644 --- a/src/wp-includes/feed-atom.php +++ b/src/wp-includes/feed-atom.php @@ -32,7 +32,7 @@ do_action( 'rss_tag_pre', 'atom' ); diff --git a/src/wp-includes/feed-rdf.php b/src/wp-includes/feed-rdf.php index 4fa4147431..708893245f 100644 --- a/src/wp-includes/feed-rdf.php +++ b/src/wp-includes/feed-rdf.php @@ -35,7 +35,7 @@ do_action( 'rss_tag_pre', 'rdf' ); diff --git a/src/wp-includes/feed-rss.php b/src/wp-includes/feed-rss.php index c776c77b56..06d5f66a60 100644 --- a/src/wp-includes/feed-rss.php +++ b/src/wp-includes/feed-rss.php @@ -16,7 +16,7 @@ echo ' diff --git a/src/wp-includes/feed-rss2-comments.php b/src/wp-includes/feed-rss2-comments.php index b26c913408..c736bebccd 100644 --- a/src/wp-includes/feed-rss2-comments.php +++ b/src/wp-includes/feed-rss2-comments.php @@ -51,7 +51,7 @@ do_action( 'rss_tag_pre', 'rss2-comments' ); diff --git a/src/wp-includes/feed-rss2.php b/src/wp-includes/feed-rss2.php index 6a99165ac7..d7ddccabe0 100644 --- a/src/wp-includes/feed-rss2.php +++ b/src/wp-includes/feed-rss2.php @@ -44,7 +44,7 @@ do_action( 'rss_tag_pre', 'rss2' ); diff --git a/src/wp-includes/feed.php b/src/wp-includes/feed.php index c8f5fd5d3d..f8662b3055 100644 --- a/src/wp-includes/feed.php +++ b/src/wp-includes/feed.php @@ -637,6 +637,51 @@ function self_link() { echo esc_url( apply_filters( 'self_link', set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); } +/* +* Get the timestamp of the most recently modified post from WP_Query. +* +* If viewing a comment feed, the date of the most recently modified +* comment will be returned. +* +* @global WP_Query $wp_query The global WP_Query object. +* +* @since 5.2.0 +* +* @return string The timestamp. +*/ +function get_last_build_date() { + global $wp_query; + + if ( empty( $wp_query ) || ! $wp_query->have_posts() ) { + // Fallback to last time any post was modified or published. + return get_lastpostmodified( 'GMT' ); + } + + // Extract the post modified times from the posts. + $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' ); + + // If this is a comment feed, check those objects too. + if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) { + // Extract the comment modified times from the comments. + $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' ); + + // Add the comment times to the post times for comparison. + $modified_times = array_merge( $modified_times, $comment_times ); + } + + // Determine the maximum modified time. + $max_modified_time = max( $modified_times ); + + /** + * Filters the date the last post or comment in the query was modified. + * + * @since 5.2.0 + * + * @param string $max_modified_times Date the last post or comment was modified in the query. + */ + return apply_filters( 'get_last_build_date', $max_modified_time ); +} + /** * Return the content type for specified feed type. * diff --git a/tests/phpunit/tests/feed/rss2.php b/tests/phpunit/tests/feed/rss2.php index 79be2fcc64..3fad4c1fb1 100644 --- a/tests/phpunit/tests/feed/rss2.php +++ b/tests/phpunit/tests/feed/rss2.php @@ -36,20 +36,23 @@ class Tests_Feeds_RSS2 extends WP_UnitTestCase { ); // Set a predictable time for testing date archives. - self::$post_date = '2003-05-27 10:07:53'; + self::$post_date = strtotime( '2003-05-27 10:07:53' ); $count = get_option( 'posts_per_rss' ) + 1; + self::$posts = array(); // Create a few posts - self::$posts = $factory->post->create_many( - $count, - array( - 'post_author' => self::$user_id, - 'post_date' => self::$post_date, - 'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec velit massa, ultrices eu est suscipit, mattis posuere est. Donec vitae purus lacus. Cras vitae odio odio.', - 'post_excerpt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', - ) - ); + for ( $i = 1; $i <= $count; $i++ ) { + self::$posts[] = $factory->post->create( + array( + 'post_author' => self::$user_id, + // Separate post dates 5 seconds apart. + 'post_date' => gmdate( 'Y-m-d H:i:s', self::$post_date + ( 5 * $i ) ), + 'post_content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec velit massa, ultrices eu est suscipit, mattis posuere est. Donec vitae purus lacus. Cras vitae odio odio.', + 'post_excerpt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + ) + ); + } // Assign a category to those posts foreach ( self::$posts as $post ) { @@ -396,6 +399,7 @@ class Tests_Feeds_RSS2 extends WP_UnitTestCase { // Queries performed on valid feed endpoints should contain posts. $this->assertTrue( have_posts() ); + // Check to see if we have the expected XML output from the feed template. $feed = $this->do_rss2(); @@ -463,4 +467,31 @@ class Tests_Feeds_RSS2 extends WP_UnitTestCase { // There should only be one child element. $this->assertEquals( 1, count( $rss ) ); } + + /** + * Test element has correct last build date. + * + * @ticket 4575 + * + * @dataProvider data_test_get_last_build_date + */ + public function test_get_last_build_date( $url, $element ) { + $this->go_to( $url ); + $feed = $this->do_rss2(); + $xml = xml_to_array( $feed ); + + // Get the child element of . + $rss = xml_find( $xml, $element ); + $last_build_date = $rss[0]['child'][0]['child'][4]['content']; + $this->assertEquals( strtotime( get_last_build_date() ), strtotime( $last_build_date ) ); + } + + + public function data_test_get_last_build_date() { + return array( + array( '/?feed=rss2', 'rss' ), + array( '/?feed=commentsrss2', 'rss' ), + ); + + } }