Make WordPress Core

Changeset 46974


Ignore:
Timestamp:
12/17/2019 08:41:09 PM (4 years ago)
Author:
SergeyBiryukov
Message:

Date/Time: Ensure that get_feed_build_date() correctly handles a modified post object with invalid date.

  • Clarify in the documentation that the function returns false on failure.
  • Consistently pass the return value through the get_feed_build_date filter.

Props Rarst, dd32, azaozz, tellyworth.
Fixes #48957.

Location:
trunk
Files:
2 edited

Legend:

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

    r46823 r46974  
    649649
    650650/**
    651  * Get the timestamp of the most recently modified post from WP_Query.
    652  *
    653  * If viewing a comment feed, the timestamp of the most recently modified
     651 * Get the UTC time of the most recently modified post from WP_Query.
     652 *
     653 * If viewing a comment feed, the time of the most recently modified
    654654 * comment will be returned.
    655655 *
     
    658658 * @since 5.2.0
    659659 *
    660  * @param string $format Format of the timestamp to return, passed to mysql2date.
    661  *
    662  * @return string The timestamp.
     660 * @param string $format Date format string to return the time in.
     661 * @return string|false The time in requested format, or false on failure.
    663662 */
    664663function get_feed_build_date( $format ) {
    665664    global $wp_query;
    666665
    667     if ( empty( $wp_query ) || ! $wp_query->have_posts() ) {
    668         // Fallback to last time any post was modified or published.
    669         return get_lastpostmodified( 'GMT' );
    670     }
    671 
    672     // Extract the post modified times from the posts.
    673     $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' );
    674 
    675     // If this is a comment feed, check those objects too.
    676     if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) {
    677         // Extract the comment modified times from the comments.
    678         $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' );
    679 
    680         // Add the comment times to the post times for comparison.
    681         $modified_times = array_merge( $modified_times, $comment_times );
    682     }
    683 
    684     // Determine the maximum modified time.
    685     $datetime = date_create_immutable_from_format(
    686         'Y-m-d H:i:s',
    687         max( $modified_times ),
    688         new DateTimeZone( 'UTC' )
    689     );
    690 
    691     $max_modified_time = $datetime->format( $format );
     666    $datetime          = false;
     667    $max_modified_time = false;
     668    $utc               = new DateTimeZone( 'UTC' );
     669
     670    if ( ! empty( $wp_query ) && $wp_query->have_posts() ) {
     671        // Extract the post modified times from the posts.
     672        $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' );
     673
     674        // If this is a comment feed, check those objects too.
     675        if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) {
     676            // Extract the comment modified times from the comments.
     677            $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' );
     678
     679            // Add the comment times to the post times for comparison.
     680            $modified_times = array_merge( $modified_times, $comment_times );
     681        }
     682
     683        // Determine the maximum modified time.
     684        $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc );
     685    }
     686
     687    if ( false === $datetime ) {
     688        // Fall back to last time any post was modified or published.
     689        $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', get_lastpostmodified( 'GMT' ), $utc );
     690    }
     691
     692    if ( false !== $datetime ) {
     693        $max_modified_time = $datetime->format( $format );
     694    }
    692695
    693696    /**
     
    696699     * @since 5.2.0
    697700     *
    698      * @param string $max_modified_time Date the last post or comment was modified in the query.
    699      * @param string $format            The date format requested in get_feed_build_date.
     701     * @param string|false $max_modified_time Date the last post or comment was modified in the query, in UTC.
     702     *                                        False on failure.
     703     * @param string       $format            The date format requested in get_feed_build_date().
    700704     */
    701705    return apply_filters( 'get_feed_build_date', $max_modified_time, $format );
  • trunk/tests/phpunit/tests/date/getFeedBuildDate.php

    r46785 r46974  
    3838        $this->assertEquals( '2018-07-23T03:13:23+00:00', get_feed_build_date( DATE_RFC3339 ) );
    3939    }
     40
     41    /**
     42     * Test that get_feed_build_date() works with invalid post dates.
     43     *
     44     * @ticket 48957
     45     */
     46    public function test_should_fall_back_to_last_post_modified() {
     47        global $wp_query;
     48
     49        update_option( 'timezone_string', 'Europe/Kiev' );
     50        $datetime     = new DateTimeImmutable( 'now', wp_timezone() );
     51        $datetime_utc = $datetime->setTimezone( new DateTimeZone( 'UTC' ) );
     52
     53        $wp_query->posts = array();
     54
     55        $this->assertFalse( get_feed_build_date( DATE_RFC3339 ), 'False when unable to determine valid time' );
     56
     57        $this->factory->post->create(
     58            array(
     59                'post_date' => $datetime->format( 'Y-m-d H:i:s' ),
     60            )
     61        );
     62
     63        $this->assertEquals(
     64            $datetime_utc->format( DATE_RFC3339 ),
     65            get_feed_build_date( DATE_RFC3339 ),
     66            'Fall back to time of last post modified with no posts'
     67        );
     68
     69        $post_id_broken = $this->factory->post->create();
     70        $post_broken    = get_post( $post_id_broken );
     71
     72        $post_broken->post_modified_gmt = 0;
     73
     74        $wp_query->posts = array( $post_broken );
     75
     76        $this->assertEquals(
     77            $datetime_utc->format( DATE_RFC3339 ),
     78            get_feed_build_date( DATE_RFC3339 ),
     79            'Fall back to time of last post modified with broken post object'
     80        );
     81    }
    4082}
Note: See TracChangeset for help on using the changeset viewer.