Make WordPress Core

Changeset 46977


Ignore:
Timestamp:
12/17/2019 08:52:44 PM (7 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.
Merges [46974] and [46973] to the 5.3 branch.
Fixes #48957.

Location:
branches/5.3
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/5.3

  • branches/5.3/src/wp-includes/feed.php

    r46774 r46977  
    650650
    651651/**
    652  * Get the timestamp of the most recently modified post from WP_Query.
    653  *
    654  * If viewing a comment feed, the timestamp of the most recently modified
     652 * Get the UTC time of the most recently modified post from WP_Query.
     653 *
     654 * If viewing a comment feed, the time of the most recently modified
    655655 * comment will be returned.
    656656 *
    … …  
    659659 * @since 5.2.0
    660660 *
    661  * @param string $format Format of the timestamp to return, passed to mysql2date.
    662  *
    663  * @return string The timestamp.
     661 * @param string $format Date format string to return the time in.
     662 * @return string|false The time in requested format, or false on failure.
    664663 */
    665664function get_feed_build_date( $format ) {
    666665        global $wp_query;
    667666
    668         if ( empty( $wp_query ) || ! $wp_query->have_posts() ) {
    669                 // Fallback to last time any post was modified or published.
    670                 return get_lastpostmodified( 'GMT' );
    671         }
    672 
    673         // Extract the post modified times from the posts.
    674         $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' );
    675 
    676         // If this is a comment feed, check those objects too.
    677         if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) {
    678                 // Extract the comment modified times from the comments.
    679                 $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' );
    680 
    681                 // Add the comment times to the post times for comparison.
    682                 $modified_times = array_merge( $modified_times, $comment_times );
    683         }
    684 
    685         // Determine the maximum modified time.
    686         $datetime = date_create_immutable_from_format(
    687                 'Y-m-d H:i:s',
    688                 max( $modified_times ),
    689                 new DateTimeZone( 'UTC' )
    690         );
    691 
    692         $max_modified_time = $datetime->format( $format );
     667        $datetime          = false;
     668        $max_modified_time = false;
     669        $utc               = new DateTimeZone( 'UTC' );
     670
     671        if ( ! empty( $wp_query ) && $wp_query->have_posts() ) {
     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( 'Y-m-d H:i:s', max( $modified_times ), $utc );
     686        }
     687
     688        if ( false === $datetime ) {
     689                // Fall back to last time any post was modified or published.
     690                $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', get_lastpostmodified( 'GMT' ), $utc );
     691        }
     692
     693        if ( false !== $datetime ) {
     694                $max_modified_time = $datetime->format( $format );
     695        }
    693696
    694697        /**
    … …  
    697700         * @since 5.2.0
    698701         *
    699          * @param string $max_modified_time Date the last post or comment was modified in the query.
    700          * @param string $format            The date format requested in get_feed_build_date.
     702         * @param string|false $max_modified_time Date the last post or comment was modified in the query, in UTC.
     703         *                                        False on failure.
     704         * @param string       $format            The date format requested in get_feed_build_date().
    701705         */
    702706        return apply_filters( 'get_feed_build_date', $max_modified_time, $format );
  • branches/5.3/src/wp-includes/post.php

    r46975 r46977  
    63876387 *                          Default 'server'.
    63886388 * @param string $post_type Optional. The post type to check. Default 'any'.
    6389  * @return string The date of the last post.
     6389 * @return string The date of the last post, or false on failure.
    63906390 */
    63916391function get_lastpostdate( $timezone = 'server', $post_type = 'any' ) {
    … …  
    63956395         * @since 2.3.0
    63966396         *
    6397          * @param string $date     Date the last post was published.
    6398          * @param string $timezone Location to use for getting the post published date.
    6399          *                         See get_lastpostdate() for accepted `$timezone` values.
     6397         * @param string|false $date     Date the last post was published. False on failure.
     6398         * @param string       $timezone Location to use for getting the post published date.
     6399         *                               See get_lastpostdate() for accepted `$timezone` values.
    64006400         */
    64016401        return apply_filters( 'get_lastpostdate', _get_last_post_time( $timezone, 'date', $post_type ), $timezone );
    … …  
    64166416 *                          Default 'server'.
    64176417 * @param string $post_type Optional. The post type to check. Default 'any'.
    6418  * @return string The timestamp in 'Y-m-d H:i:s' format.
     6418 * @return string The timestamp in 'Y-m-d H:i:s' format, or false on failure.
    64196419 */
    64206420function get_lastpostmodified( $timezone = 'server', $post_type = 'any' ) {
    … …  
    64476447         * @since 2.3.0
    64486448         *
    6449          * @param string $lastpostmodified The most recent time that a post was modified, in 'Y-m-d H:i:s' format.
    6450          * @param string $timezone         Location to use for getting the post modified date.
    6451          *                                 See get_lastpostdate() for accepted `$timezone` values.
     6449         * @param string|false $lastpostmodified The most recent time that a post was modified, in 'Y-m-d H:i:s' format.
     6450         *                                       False on failure.
     6451         * @param string       $timezone         Location to use for getting the post modified date.
     6452         *                                       See get_lastpostdate() for accepted `$timezone` values.
    64526453         */
    64536454        return apply_filters( 'get_lastpostmodified', $lastpostmodified, $timezone );
    … …  
    64676468 * @param string $field     Post field to check. Accepts 'date' or 'modified'.
    64686469 * @param string $post_type Optional. The post type to check. Default 'any'.
    6469  * @return string|false The timestamp in 'Y-m-d H:i:s' format, or false on error.
     6470 * @return string|false The timestamp in 'Y-m-d H:i:s' format, or false on failure.
    64706471 */
    64716472function _get_last_post_time( $timezone, $field, $post_type = 'any' ) {
  • branches/5.3/tests/phpunit/tests/date/getFeedBuildDate.php

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