From b6ce4e283080332525bb276e2bacaf566c4a9b5c Mon Sep 17 00:00:00 2001 From: James Nylen Date: Tue, 21 Feb 2017 18:18:45 +0000 Subject: [PATCH] REST API: Fix multiple issues with setting dates of posts and comments. This commit modifies the `rest_get_date_with_gmt` function to correctly parse local and UTC timestamps with or without timezone information. It also ensures that the REST API can edit the dates of draft posts by setting the `edit_date` flag to `wp_update_post`. Overall this commit ensures that post and comment dates can be set and updated as expected. Fixes #39256. Built from https://develop.svn.wordpress.org/trunk@40101 git-svn-id: http://core.svn.wordpress.org/trunk@40038 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/rest-api.php | 28 ++++++++++++++----- .../class-wp-rest-posts-controller.php | 2 ++ wp-includes/version.php | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php index d5d76386cd..e6cdc3a959 100644 --- a/wp-includes/rest-api.php +++ b/wp-includes/rest-api.php @@ -780,26 +780,40 @@ function rest_parse_date( $date, $force_utc = false ) { } /** - * Retrieves a local date with its GMT equivalent, in MySQL datetime format. + * Parses a date into both its local and UTC equivalent, in MySQL datetime format. * * @since 4.4.0 * * @see rest_parse_date() * - * @param string $date RFC3339 timestamp. - * @param bool $force_utc Whether a UTC timestamp should be forced. Default false. + * @param string $date RFC3339 timestamp. + * @param bool $is_utc Whether the provided date should be interpreted as UTC. Default false. * @return array|null Local and UTC datetime strings, in MySQL datetime format (Y-m-d H:i:s), * null on failure. */ -function rest_get_date_with_gmt( $date, $force_utc = false ) { - $date = rest_parse_date( $date, $force_utc ); +function rest_get_date_with_gmt( $date, $is_utc = false ) { + // Whether or not the original date actually has a timezone string + // changes the way we need to do timezone conversion. Store this info + // before parsing the date, and use it later. + $has_timezone = preg_match( '#(Z|[+-]\d{2}(:\d{2})?)$#', $date ); + + $date = rest_parse_date( $date ); if ( empty( $date ) ) { return null; } - $utc = date( 'Y-m-d H:i:s', $date ); - $local = get_date_from_gmt( $utc ); + // At this point $date could either be a local date (if we were passed a + // *local* date without a timezone offset) or a UTC date (otherwise). + // Timezone conversion needs to be handled differently between these two + // cases. + if ( ! $is_utc && ! $has_timezone ) { + $local = date( 'Y-m-d H:i:s', $date ); + $utc = get_gmt_from_date( $local ); + } else { + $utc = date( 'Y-m-d H:i:s', $date ); + $local = get_date_from_gmt( $utc ); + } return array( $local, $utc ); } diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 16765a5a5f..3648d9fa07 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php @@ -1004,12 +1004,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { if ( ! empty( $date_data ) ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; + $prepared_post->edit_date = true; } } elseif ( ! empty( $schema['properties']['date_gmt'] ) && ! empty( $request['date_gmt'] ) ) { $date_data = rest_get_date_with_gmt( $request['date_gmt'], true ); if ( ! empty( $date_data ) ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; + $prepared_post->edit_date = true; } } diff --git a/wp-includes/version.php b/wp-includes/version.php index 9e4f3019ad..b4f75980d5 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.8-alpha-40089'; +$wp_version = '4.8-alpha-40101'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.