Skip to content

2.x Add compatibility for Twig date functionality#2135

Merged
jarednova merged 24 commits into2.xfrom
2.x-twig-date-compat
Jan 8, 2020
Merged

2.x Add compatibility for Twig date functionality#2135
jarednova merged 24 commits into2.xfrom
2.x-twig-date-compat

Conversation

@gchtr
Copy link
Copy Markdown
Member

@gchtr gchtr commented Jan 2, 2020

Ticket: #2104, #2127

Whew, yet another journey where I learnt lots about the inner workings of WordPress and dates and time in general 🤪.

Issue

WordPress handles dates differently than most PHP applications. It’s no suprise that there a Twig compatibility issues.

Solution

As of WordPress 5.3, there we a lot of updates to the Date/Time component. This pull request builds on top of that new functionality.

Add compatibility with Twig Date functionality

Instead of creating a separate filter function for the Twig date filter, I figured the best way to avoid confusion would be to try to add compatibility with Twig.

I first replicated the tests from Twig to ensure the date filter as well as the date() function work properly. I then tried to add compatibility by:

  • Updating the Twig defaults to use the date format and timezone set in the WordPress settings. This makes Timber compatible with Twig’s date function.
  • Overwriting the date filter with a custom implementation in Twig::twig_date_format_filter().

The test results indicate that now everything works. And there’s the added benefit that we also have support for DateInterval in the date filter.

Add new DateTimeHelper class

I’ve figured that the new wrapper for wp_date() could be used in other places and that the proper place isn’t in the Timber\Twig class. That’s why I created a new DateTimeHelper class for all date related helper functions.

  • Deprecated Twig::intl_date() and moved it to DateTimeHelper::wp_date().
  • Deprecated Twig::time_ago() and moved it to DateTimeHelper::time_ago().
  • Added support for \DateTimeImmutable by checking for \DateTimeInterface instead of \DateTime.

Impact

This pull request relies on a lot of Date/Time functionality that was introduced in WordPress 5.3, which would mean, that we would have to bump the minimum required WordPress version for Timber 2.0 to 5.3. Otherwise, we’d have to add backwards compatibility.

Usage Changes

Apart from the functions that were moved to the DateTimeHelper class, I guess there are none.

Considerations

Adding backwards compatibility for WordPress < 5.3 would require more work. I didn’t check yet how much, but it would surely require us to basically replicate some of the functionality added in WordPress 5.3. Would there be benefits for adding that backward compatibility?

When we make use of the new Date/Time functions introduced in WordPress 5.3, we can also update {{ post.date }} and {{ post.modified }}. See separate pull request.

Testing

Yes, there’s lots of testing included.

I also added a new Timber\Date group to run tests that check date functionality with the --group="Timber\Date" parameter.

Todo

@gchtr gchtr added the 2.0 label Jan 2, 2020
@gchtr gchtr self-assigned this Jan 2, 2020
This was referenced Jan 2, 2020
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 2, 2020

Codecov Report

❗ No coverage uploaded for pull request base (2.x@1f61181). Click here to learn what that means.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff           @@
##             2.x    #2135   +/-   ##
======================================
  Coverage       ?   95.72%           
  Complexity     ?     1539           
======================================
  Files          ?       50           
  Lines          ?     3949           
  Branches       ?        0           
======================================
  Hits           ?     3780           
  Misses         ?      169           
  Partials       ?        0
Impacted Files Coverage Δ Complexity Δ
lib/Helper.php 90.68% <100%> (ø) 78 <0> (?)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1f61181...301f0e8. Read the comment docs.

@gchtr gchtr marked this pull request as ready for review January 2, 2020 12:47
gchtr and others added 2 commits January 2, 2020 13:49
…ocs-datetime

# Conflicts:
#	lib/DateTimeHelper.php
#	lib/Twig.php
#	tests/test-timber-dates.php
@jarednova
Copy link
Copy Markdown
Member

Holy moly. And here I thought dates would be simple? Thanks for your work thus far @gchtr I'll give this a spin this along with #2136 to see how things work

@jarednova
Copy link
Copy Markdown
Member

@gchtr this is fantastic. I LOVE the idea of just stealing Twig's tests — makes sure we match their functionality AND lazy.

Obviously, the big Q is whether to support versions prior to 5.3 in 2.x. I'm definitely partial to dropping support. Currently the WordPress.org Stats have version 5.3 at 29% after about 6 weeks of its release. I think new Timber users for 2.x (who will no longer be able to download from WP.org and have to use Composer) are highly likely to be using fresh installs with the newest version.

That said, Travis flagged a ton of errors coming from a lack of the wp_timezone_string(); function. I dropped in stub of it to see if that will restore functionality for WP 4.9.8. If a 5 min fix like that works, I'm persuadable — but I don't think the backwards compatibility right now should be a focus of our efforts.

@gchtr
Copy link
Copy Markdown
Member Author

gchtr commented Jan 4, 2020

I LOVE the idea of just stealing Twig's tests — makes sure we match their functionality AND lazy.

Riiight? It was actually quite rewarding to drop in the tests and then make them work one by one.

I think new Timber users for 2.x (who will no longer be able to download from WP.org and have to use Composer) are highly likely to be using fresh installs with the newest version.

That were my thoughts, too 👍.

If a 5 min fix like that works, I'm persuadable — but I don't think the backwards compatibility right now should be a focus of our efforts.

There would be more new functions to cover in #2133. And there’s wp_date(), which wasn’t even flagged yet. I could check whether copy-pasting these new functions into a new helper class will work to make tests run in 4.9.8.

However, apart from a couple of new functions, there apparently were a lot of changes to WordPress Core in other places. For example, they tried to reduce the amount of times mysql2date() is being used. I wouldn’t want to dare to say that Timber is compatible with WordPress < 5.3 if we only added stubs for missing functions. There could be so many other small errors. 😅

If we wanted to add support, we would probably have to work with the existing functions in WordPress < 5.3, namely date_i18n() etc. And that wouldn’t be a 5 minute fix.

@gchtr gchtr requested a review from jarednova as a code owner January 5, 2020 19:07
@jarednova
Copy link
Copy Markdown
Member

cool, we're on the same page then. The idea of stubbing in that function sounded lovely, but in addition to the issues you flagged (date_i18n() and what not) — it also didn't work.

I updated Travis on this branch to not support/test WP before 5.3.2. Even though right now 5.3.2 and latest are essentially the same, this gives us a range for support going forward

@jarednova
Copy link
Copy Markdown
Member

jarednova commented Jan 6, 2020

@gchtr found a small issue with the tests we might want to resolve. Sometimes we'll get errors on tests like:

1) TestTimberDates::testTimeAgoWithPostDateAndCurrent
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'3 years ago'
+'4 years ago'
/home/travis/build/timber/timber/tests/test-timber-dates.php:50
function testTimeAgoWithPostDateAndCurrent() {
	$pid  = $this->factory->post->create( [
		'post_date' => '2016-07-06 20:03:00',
	] );
	$post = Timber::get_post( $pid );
	$str = DateTimeHelper::time_ago( $post->date() );
	$this->assertEquals(
		sprintf( '%s ago', human_time_diff( strtotime( $post->post_date ) ) ),
		$str
	);
}

Why? In the function we create a post created on July 6, 2016 at ~8pm (or 20:03:00 as some say). But when $post->date() sends the date/time info over it's a human-readable string of July 6, 2016: just the date w/o any time info. When this is compared alter to $post->post_date (which does have time info) you can get diff's in "X days ago" "Y years ago" b/c of the slight time diff. So we should either ...

A) Set all the time stamps to midnight so there's never a diff
B) Send time-inclusive PHP date formats to like $post->date('M j, Y g:i a') so we always get time back
C) Do nothing because this will only be an occasional occurrence.

Which of those is your favorite?

Copy link
Copy Markdown
Member

@jarednova jarednova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found one issue with the tests to take a look at ref'd in this comment here: #2135 (comment)

@gchtr
Copy link
Copy Markdown
Member Author

gchtr commented Jan 6, 2020

So we should either ...

A) Set all the time stamps to midnight so there's never a diff
B) Send time-inclusive PHP date formats to like $post->date('M j, Y g:i a') so we always get time back
C) Do nothing because this will only be an occasional occurrence.

Which of those is your favorite?

@jarednova I guess if we check for time diffs lower than a day (e.g. "5 hours") in other tests, then we can very well go with A).

Will you update the tests, or should I do it?

@jarednova
Copy link
Copy Markdown
Member

jarednova commented Jan 7, 2020 via email

@gchtr
Copy link
Copy Markdown
Member Author

gchtr commented Jan 7, 2020

@jarednova When WordPress versions below 5.3 are not supported anymore, should we add a check when Timber initializes and provide a proper warning?

@jarednova
Copy link
Copy Markdown
Member

@gchtr good call! I'll make a separate issue/PR to track that

@gchtr
Copy link
Copy Markdown
Member Author

gchtr commented Jan 8, 2020

@jarednova Can you approve your requested changes and merge this? Everything seems fine from my side.

@jarednova
Copy link
Copy Markdown
Member

Yup, looks good — great to have this one in!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants