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' ),
+ );
+
+ }
}