Make WordPress Core

Changeset 44948


Ignore:
Timestamp:
03/20/2019 08:37:02 PM (6 years ago)
Author:
adamsilverstein
Message:

Feeds: ensure build/update date matches current query.

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.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/feed-atom-comments.php

    r44574 r44948  
    4646    <updated>
    4747    <?php
    48         $date = get_lastcommentmodified( 'GMT' );
     48        $date = get_last_build_date();
    4949        echo $date ? mysql2date( 'Y-m-d\TH:i:s\Z', $date, false ) : date( 'Y-m-d\TH:i:s\Z' );
    5050    ?>
  • trunk/src/wp-includes/feed-atom.php

    r44574 r44948  
    3333    <updated>
    3434    <?php
    35         $date = get_lastpostmodified( 'GMT' );
     35        $date = get_last_build_date();
    3636        echo $date ? mysql2date( 'Y-m-d\TH:i:s\Z', $date, false ) : date( 'Y-m-d\TH:i:s\Z' );
    3737    ?>
  • trunk/src/wp-includes/feed-rdf.php

    r43571 r44948  
    3636    <dc:date>
    3737    <?php
    38         $date = get_lastpostmodified( 'GMT' );
     38        $date = get_last_build_date();
    3939        echo $date ? mysql2date( 'Y-m-d\TH:i:s\Z', $date ) : date( 'Y-m-d\TH:i:s\Z' );
    4040    ?>
  • trunk/src/wp-includes/feed-rss.php

    r43571 r44948  
    1717    <lastBuildDate>
    1818    <?php
    19         $date = get_lastpostmodified( 'GMT' );
     19        $date = get_last_build_date();
    2020        echo $date ? mysql2date( 'D, d M Y H:i:s +0000', $date ) : date( 'D, d M Y H:i:s +0000' );
    2121    ?>
  • trunk/src/wp-includes/feed-rss2-comments.php

    r44574 r44948  
    5252    <lastBuildDate>
    5353    <?php
    54         $date = get_lastcommentmodified( 'GMT' );
     54        $date = get_last_build_date();
    5555        echo $date ? mysql2date( 'r', $date, false ) : date( 'r' );
    5656    ?>
  • trunk/src/wp-includes/feed-rss2.php

    r43571 r44948  
    4545    <lastBuildDate>
    4646    <?php
    47         $date = get_lastpostmodified( 'GMT' );
     47        $date = get_last_build_date();
    4848        echo $date ? mysql2date( 'r', $date, false ) : date( 'r' );
    4949    ?>
  • trunk/src/wp-includes/feed.php

    r42414 r44948  
    638638}
    639639
     640/*
     641* Get the timestamp of the most recently modified post from WP_Query.
     642*
     643* If viewing a comment feed, the date of the most recently modified
     644* comment will be returned.
     645*
     646* @global WP_Query  $wp_query The global WP_Query object.
     647*
     648* @since 5.2.0
     649*
     650* @return string The timestamp.
     651*/
     652function get_last_build_date() {
     653    global $wp_query;
     654
     655    if ( empty( $wp_query ) || ! $wp_query->have_posts() ) {
     656        // Fallback to last time any post was modified or published.
     657        return get_lastpostmodified( 'GMT' );
     658    }
     659
     660    // Extract the post modified times from the posts.
     661    $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' );
     662
     663    // If this is a comment feed, check those objects too.
     664    if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) {
     665        // Extract the comment modified times from the comments.
     666        $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' );
     667
     668        // Add the comment times to the post times for comparison.
     669        $modified_times = array_merge( $modified_times, $comment_times );
     670    }
     671
     672    // Determine the maximum modified time.
     673    $max_modified_time = max( $modified_times );
     674
     675    /**
     676     * Filters the date the last post or comment in the query was modified.
     677     *
     678     * @since 5.2.0
     679     *
     680     * @param string $max_modified_times Date the last post or comment was modified in the query.
     681     */
     682    return apply_filters( 'get_last_build_date', $max_modified_time );
     683}
     684
    640685/**
    641686 * Return the content type for specified feed type.
  • trunk/tests/phpunit/tests/feed/rss2.php

    r43571 r44948  
    3737
    3838        // Set a predictable time for testing date archives.
    39         self::$post_date = '2003-05-27 10:07:53';
     39        self::$post_date = strtotime( '2003-05-27 10:07:53' );
    4040
    4141        $count = get_option( 'posts_per_rss' ) + 1;
    4242
     43        self::$posts = array();
    4344        // Create a few posts
    44         self::$posts = $factory->post->create_many(
    45             $count,
    46             array(
    47                 'post_author'  => self::$user_id,
    48                 'post_date'    => self::$post_date,
    49                 '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.',
    50                 'post_excerpt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
    51             )
    52         );
     45        for ( $i = 1; $i <= $count; $i++ ) {
     46            self::$posts[] = $factory->post->create(
     47                array(
     48                    'post_author'  => self::$user_id,
     49                    // Separate post dates 5 seconds apart.
     50                    'post_date'    => gmdate( 'Y-m-d H:i:s', self::$post_date + ( 5 * $i ) ),
     51                    '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.',
     52                    'post_excerpt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
     53                )
     54            );
     55        }
    5356
    5457        // Assign a category to those posts
     
    397400        $this->assertTrue( have_posts() );
    398401
     402
    399403        // Check to see if we have the expected XML output from the feed template.
    400404        $feed = $this->do_rss2();
     
    464468        $this->assertEquals( 1, count( $rss ) );
    465469    }
     470
     471    /**
     472     * Test <rss> element has correct last build date.
     473     *
     474     * @ticket 4575
     475     *
     476     * @dataProvider data_test_get_last_build_date
     477     */
     478    public function test_get_last_build_date( $url, $element ) {
     479        $this->go_to( $url );
     480        $feed = $this->do_rss2();
     481        $xml  = xml_to_array( $feed );
     482
     483        // Get the <rss> child element of <xml>.
     484        $rss             = xml_find( $xml, $element );
     485        $last_build_date = $rss[0]['child'][0]['child'][4]['content'];
     486        $this->assertEquals( strtotime( get_last_build_date() ), strtotime( $last_build_date ) );
     487    }
     488
     489
     490    public function data_test_get_last_build_date() {
     491        return array(
     492            array( '/?feed=rss2', 'rss' ),
     493            array( '/?feed=commentsrss2', 'rss' ),
     494        );
     495
     496    }
    466497}
Note: See TracChangeset for help on using the changeset viewer.