WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 2 years ago

Last modified 2 years ago

#38883 closed defect (bug) (fixed)

Shim post_date_gmt for drafts / empty dates in the REST API

Reported by: joehoyle Owned by: jnylen0
Milestone: 4.7.3 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: has-unit-tests has-patch fixed-major
Focuses: Cc:

Description

For reasons that we won't get into here, post dates for drafts in WordPress only stores the post_date field, but not the date_gmt_field - that one doesn't get set up a post is published. In the context of the REST API the date_gmt field is most useful to show dates in the timezone of the viewer - only having the date field in drafts makes it very difficult for a REST API client to show true dates to their users.

We have thus far opted to set the date_gmt field to null in the case of it being set to an all-zero date in the database. Unfortunately, this is an annoying WordPress inconsistency that affects REST API users.

I'm not sure whether we should be fixing this at the API level, but it's come up a few times with discussion with @jnylen, so this ticket exists as a place to discuss and see if we can solve this for API users.

Attachments (2)

38883.diff (4.9 KB) - added by joehoyle 3 years ago.
38883.2.diff (9.4 KB) - added by jnylen0 2 years ago.
Corrected sign of timezone offset; added more tests; other minor cleanup

Download all attachments as: .zip

Change History (28)

@joehoyle
3 years ago

#1 @peterwilsoncc
3 years ago

  • Keywords needs-patch has-unit-tests added

#2 @joehoyle
3 years ago

As a means of getting the discussion going, I've added a patch that shims the date_gmt value to the UTC "version" of the date field - this means API clients will always have a UTC date to rely on. Currently, if clients want to show dates in the timezone of their users, it's virtually not possible to do that for drafts.

To make it _possible_ we could expose the gmt_offset / timezone on the site's root /wp-json/ so atleast a client could *technically* reverse the date field into a date_gmt value themselves - that's certainly not a pretty solution though.

#3 @joehoyle
3 years ago

Also worth mentioning - I didn't put in any update logic for the shim yet, but I'm not sure if we can, as currently we actually support updating the post_date_gmt field on drafts to something other than zero'd dates.

#4 follow-up: @adamsilverstein
3 years ago

@joehoyle thanks for opening this ticket. I'd love to get this fixed so that drafts have actual gmt data, I see no reason they should not.

According to the original discussion in #5698 The empty post_date_gmt is used as the marker to indicate that post_date should be updated to the current time when saved. This may be the underlying use we need to address before adding actual gmt data to drafts.

#5 in reply to: ↑ 4 @danielbachhuber
3 years ago

Replying to adamsilverstein:

According to the original discussion in #5698 The empty post_date_gmt is used as the marker to indicate that post_date should be updated to the current time when saved. This may be the underlying use we need to address before adding actual gmt data to drafts.

This is exactly why the GMT date is "empty". The expectation is that the date remains a falsy value if it's meant to be set to the current time when the post is published. If the date isn't a falsy value, then WordPress use the value presented as the publication date.

#6 @rmccue
3 years ago

  • Owner set to rmccue
  • Status changed from new to reviewing

#7 follow-up: @jnylen0
3 years ago

  • Keywords has-patch added; needs-patch removed

The expectation is that the date remains a falsy value if it's meant to be set to the current time when the post is published.

This is a silly expectation. The API should both provide and accept a UTC/GMT date.

Two comments on 38883.diff:

  • The comment in the second block should say For drafts, modified_gmt will not be set, instead of date_gmt.
  • Based on the discussion above, updating post_date_gmt for a draft will probably break things. If we make this change, we need to make sure that after sending a draft on a "round-trip" through the API it still has null dates where needed.

#8 in reply to: ↑ 7 @danielbachhuber
3 years ago

Replying to jnylen0:

The expectation is that the date remains a falsy value if it's meant to be set to the current time when the post is published.

This is a silly expectation. The API should both provide and accept a UTC/GMT date.

Could you explain why you think this is a "silly expectation" in greater detail? If a client doesn't want to publish a post at a specified time, but rather the current time of the request handling, how should it make this request?

#9 follow-up: @jnylen0
3 years ago

I don't know what would be a good way to make that request, but "set this other field unrelated to the task at hand to a special magic value" is not the sane way to do it.

I know this is the way WP currently works. I think we should work around it in the API because storing dates in UTC is the only way to write provably correct datetime-handling code, and losing the ability to do that isn't worth it.

#10 in reply to: ↑ 9 @danielbachhuber
3 years ago

Replying to jnylen0:

I don't know what would be a good way to make that request, but "set this other field unrelated to the task at hand to a special magic value" is not the sane way to do it.

I know this is the way WP currently works. I think we should work around it in the API because storing dates in UTC is the only way to write provably correct datetime-handling code, and losing the ability to do that isn't worth it.

How do APIs for other publishing platforms handle this particular use case?

This ticket was mentioned in Slack in #core-restapi by joehoyle. View the logs.


3 years ago

#12 @adamsilverstein
3 years ago

"The empty post_date_gmt is used as the marker to indicate that post_date should be updated to the current time when saved."

Why not use the post status to determine if post_date gets updated? if the post is in a draft state we would update the post_date on every update?

#13 follow-up: @jnylen0
3 years ago

Why not use the post status to determine if post_date gets updated? if the post is in a draft state we would update the post_date on every update?

This seems pretty reasonable to me.

If a GMT date is updated for a draft, we can either assume or verify that the corresponding post_*_gmt field is all zeroes, then make the requested change to the non-GMT field instead (backing out the site's timezone offset).

If both date and date_gmt are specified in an update, and it's a draft, and this would lead to different values for the date... I guess that should probably be an error.

#14 @jnylen0
2 years ago

  • Milestone changed from Awaiting Review to 4.7.3
  • Version set to 4.7

I'm going to try to handle this in 4.7.3.

This ticket was mentioned in Slack in #core by jnylen. View the logs.


2 years ago

This ticket was mentioned in Slack in #core-restapi by kadamwhite. View the logs.


2 years ago

This ticket was mentioned in Slack in #core by jnylen. View the logs.


2 years ago

This ticket was mentioned in Slack in #core-restapi by jnylen. View the logs.


2 years ago

@jnylen0
2 years ago

Corrected sign of timezone offset; added more tests; other minor cleanup

#19 in reply to: ↑ 13 @jnylen0
2 years ago

  • Keywords commit added
  • Owner changed from rmccue to jnylen0
  • Status changed from reviewing to accepted

Replying to jnylen0:

If a GMT date is updated for a draft, we can either assume or verify that the corresponding post_*_gmt field is all zeroes, then make the requested change to the non-GMT field instead (backing out the site's timezone offset).

I've since changed my mind about this. For 4.7.3 we should preserve the existing behavior: updating either date or date_gmt represents the client's explicit intent to set the date rather than have WP update it based on a zero post_date_gmt field.

If the behavior to determine whether a draft has a zero post_date_gmt is missed, we can add a new field for this later on (#39953).

If both date and date_gmt are specified in an update, and it's a draft, and this would lead to different values for the date... I guess that should probably be an error.

This should be a separate ticket as well (#39954).

Other changes in 38883.2.diff:

  • Fix the sign of the timezone offset
  • Add better, more direct tests including a non-zero timezone offset
  • Clean up comments and tests (remove some duplicate test logic)

So I think this is pretty much ready to go. If anyone has any feedback please leave it ASAP because this needs to land in 4.7.3.

This ticket was mentioned in Slack in #core-restapi by jnylen. View the logs.


2 years ago

#21 @jnylen0
2 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 40108:

REST API: Shim post_date_gmt for drafts / empty dates in the REST API.

Internally, WordPress uses a special post_date_gmt value of 0000-00-00 00:00:00 to indicate that a draft's date is "floating" and should be updated whenever the post is saved. This makes it much more difficult for API clients to know the correct date of a draft post.

This commit provides a best guess at a date_gmt value for draft posts in this situation using the date field and the site's current timezone offset.

Props joehoyle.
Fixes #38883.

#22 @jnylen0
2 years ago

  • Keywords fixed-major added; commit removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening for backport to 4.7 branch.

#23 @SergeyBiryukov
2 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 40115:

REST API: Shim post_date_gmt for drafts / empty dates in the REST API.

Internally, WordPress uses a special post_date_gmt value of 0000-00-00 00:00:00 to indicate that a draft's date is "floating" and should be updated whenever the post is saved. This makes it much more difficult for API clients to know the correct date of a draft post.

This commit provides a best guess at a date_gmt value for draft posts in this situation using the date field and the site's current timezone offset.

Props joehoyle, jnylen0.
Merges [40108] to the 4.7 branch.
Fixes #38883.

This ticket was mentioned in Slack in #core-restapi by nerrad. View the logs.


2 years ago

This ticket was mentioned in Slack in #core by nerrad. View the logs.


2 years ago

#26 @jnylen0
2 years ago

See also #40136 as a follow-up bugfix here.

Note: See TracTickets for help on using tickets.