Skip to content

Commit

Permalink
Feeds: ensure build/update date matches current query.
Browse files Browse the repository at this point in the history
Displaying the correct build date in feeds is as important today as it was twelve years ago when this ticket was opened.

Fix an issue where all feeds in WordPress showed the same date for their last build date (the datapoint is `lastBuildDate`, `updated` or `dc:date` depending on the feed type). 

Introduce a new `get_last_build_date` filter to adjust the date used for `lastBuildDate`. Developers who previously filtered `get_lastcommentmodified` to alter feed dates should use this filter instead.

* `get_last_build_date` extracts the latest post (or comment) in the current WP_Query object.
* In all feed templates, use `get_last_build_date` vs `get_lastpostmodified( 'GMT' );`.

Props stevenkword, spacedmonkey, ryanshoover, mauteri, nacin, jorbin, MikeNGarrett, Denis-de-Bernardy, peaceablewhale.
Fixes #4575.



git-svn-id: http://develop.svn.wordpress.org/trunk@44948 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
adamsilverstein committed Mar 20, 2019
1 parent c534b25 commit be15f33
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/wp-includes/feed-atom-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

<updated>
<?php
$date = get_lastcommentmodified( 'GMT' );
$date = get_last_build_date();
echo $date ? mysql2date( 'Y-m-d\TH:i:s\Z', $date, false ) : date( 'Y-m-d\TH:i:s\Z' );
?>
</updated>
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/feed-atom.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

<updated>
<?php
$date = get_lastpostmodified( 'GMT' );
$date = get_last_build_date();
echo $date ? mysql2date( 'Y-m-d\TH:i:s\Z', $date, false ) : date( 'Y-m-d\TH:i:s\Z' );
?>
</updated>
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/feed-rdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<description><?php bloginfo_rss( 'description' ); ?></description>
<dc:date>
<?php
$date = get_lastpostmodified( 'GMT' );
$date = get_last_build_date();
echo $date ? mysql2date( 'Y-m-d\TH:i:s\Z', $date ) : date( 'Y-m-d\TH:i:s\Z' );
?>
</dc:date>
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/feed-rss.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<description><?php bloginfo_rss( 'description' ); ?></description>
<lastBuildDate>
<?php
$date = get_lastpostmodified( 'GMT' );
$date = get_last_build_date();
echo $date ? mysql2date( 'D, d M Y H:i:s +0000', $date ) : date( 'D, d M Y H:i:s +0000' );
?>
</lastBuildDate>
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/feed-rss2-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<description><?php bloginfo_rss( 'description' ); ?></description>
<lastBuildDate>
<?php
$date = get_lastcommentmodified( 'GMT' );
$date = get_last_build_date();
echo $date ? mysql2date( 'r', $date, false ) : date( 'r' );
?>
</lastBuildDate>
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/feed-rss2.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<description><?php bloginfo_rss( 'description' ); ?></description>
<lastBuildDate>
<?php
$date = get_lastpostmodified( 'GMT' );
$date = get_last_build_date();
echo $date ? mysql2date( 'r', $date, false ) : date( 'r' );
?>
</lastBuildDate>
Expand Down
45 changes: 45 additions & 0 deletions src/wp-includes/feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
51 changes: 41 additions & 10 deletions tests/phpunit/tests/feed/rss2.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,23 @@ public static function wpSetUpBeforeClass( $factory ) {
);

// 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 ) {
Expand Down Expand Up @@ -396,6 +399,7 @@ function test_valid_archive_feed_endpoint() {
// 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();

Expand Down Expand Up @@ -463,4 +467,31 @@ function test_valid_search_feed_endpoint() {
// There should only be one <rss> child element.
$this->assertEquals( 1, count( $rss ) );
}

/**
* Test <rss> 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 <rss> child element of <xml>.
$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' ),
);

}
}

0 comments on commit be15f33

Please sign in to comment.