Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Add TimezoneChange XML doc #1731

Merged
merged 2 commits into from
Jun 4, 2022
Merged

Docs: Add TimezoneChange XML doc #1731

merged 2 commits into from
Jun 4, 2022

Conversation

GaryJones
Copy link
Member

See #1722.

]]>
</standard>
<code_comparison>
<code title="Valid: Using WP internal timezone support.">
Copy link
Member Author

Choose a reason for hiding this comment

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

The description doesn't match up with the example. The description says WP, but the example is pure PHP!

(Pulled from the unit test file.)

Copy link
Member

Choose a reason for hiding this comment

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

I've done some tracing back of this and it looks like the sniff has not had any significant changes (other than sniff technical improvements) since it was first added to the library:

The issue and the inline docs refer to the following links as relevant:

Based on the information there, the more recent issue around the use of gmdate() instead of date() - #1713 - is very much related to this as well.

Now there are two things which are confusing here:

  1. The unit test "good" case.
    That case shouldn't really be there as it doesn't test the sniff at all.
    The sniff is not looking for anything in the code of the "good" case, so would never trigger on it.
    It could be replaced with something like My_Class::date_default_timezone_set( 'Foo/Bar' ); which would be testing the proper functioning of the sniff against false positives.
  2. The error message refers to "WP internal timezone support" which is an unclear phrase to begin with.
    This is IMO where the docs you are creating come in and can help hugely to clarify what is meant by this, though if someone can come up with a simple phrase to improve the error message, that could be helpful too.
    I think that summarizing the information found in the last two docs links I mention above, to come up with a better description and better code samples would be the way forward.
    I can also imagine some additional issues may need to be opened, sooner rather than later, to get WPCS to detect additional cases of doing it wrong regarding retrieving/displaying date/time information. /cc @Rarst

On a related note - PR #1714 added a check for the use of date() to the WordPress.PHP.RestrictedPHPFunctions sniff.
This change has not yet been released and based on the above, I'm now wondering if we should move that check to this sniff instead.

What do you think ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, gmdate() change is purely to make timezone issue more foolproof, so if it can be here.

Using date_default_timezone_set() and similar isn't allowed, instead use WP internal timezone support.

Now this line is a mess. There is no "similar", there aren't other things that would mess up default time zone. And this doesn't really come up in WordPress context, this comes up when people do PHP in WordPress in incompatible way.

It should be something like this (probably in sniff itself as well?):

Using date_default_timezone_set() isn't allowed, because WP core needs default time zone set to UTC. Use DateTime object or core API functions instead.

PS https://wpvip.com/documentation/vip-go/use-current_time-not-date_default_timezone_set/ this is highly outdated rec, local timestamps are a huge problem (I am close to getting rid of current_time('timestamp') in core) and timezone_string is highly preferable to gmt_offset if available (that mess is about to get abstracted as wp_timezone() in core).

@jrfnl
Copy link
Member

jrfnl commented Oct 30, 2019

@GaryJones Now there is clarity about the future of the sniff - this sniff has been deprecated and the check moved to the WordPress.DateTime.RestrictedFunctions sniff, would you like to update this PR to cover the new WordPress.DateTime.RestrictedFunctions sniff instead ?

@GaryJones
Copy link
Member Author

I'm not going to get to this any time soon - happy for someone else to take it over.

@GaryJones GaryJones removed their assignment Nov 2, 2019
@jrfnl
Copy link
Member

jrfnl commented Nov 2, 2019

Keeping my fingers crossed that there might be someone at contributor day WCUS who'd like to.

@GaryJones
Copy link
Member Author

Noting that I've refreshed the PR on my local branch, but my account is having difficulty pushing to this repo at the moment.

@GaryJones
Copy link
Member Author

GaryJones commented Mar 27, 2022

Manually copying it here for visibility:

WordPress/Docs/DateTime/RestrictedFunctionsStandard.xml
<documentation title="Restricted Date and Time Functions">
    <standard>
    <![CDATA[
      The restricted functions date_default_timezone_set() and date() should not be used.

      Using date_default_timezone_set() isn't allowed, because WordPress core needs default time zone set to UTC. Use DateTime object or WP core API functions instead.

      Using date() isn't allowed, as it is affected by runtime timezone changes which can cause date/time to be incorrectly displayed. Use gmdate() instead.
    ]]>
    </standard>
    <code_comparison>
        <code title="Valid: Using DateTime object.">
        <![CDATA[
$date = new DateTime();
$date->setTimezone(
    new DateTimeZone( 'Europe/Amsterdam' )
);
        ]]>
        </code>
        <code title="Invalid: Using date_default_timezone_set().">
        <![CDATA[
date_default_timezone_set( 'Europe/Amsterdam' );
        ]]>
        </code>
    </code_comparison>
    <code_comparison>
        <code title="Valid: Using gmdate().">
            <![CDATA[
$last_updated = gmdate(
    'Y-m-d\TH:i:s',
    strtotime( $plugin['last_updated'] )
);
        ]]>
        </code>
        <code title="Invalid: Using date().">
            <![CDATA[
$last_updated = date(
    'Y-m-d\TH:i:s',
    strtotime( $plugin['last_updated'] )
);
        ]]>
        </code>
    </code_comparison>
</documentation>

Commit message:

Docs: Refresh restricted datetime functions docs

Kept the descriptions for individual code comparisons simpler, and populated the <standard> element with more description instead.

With:

./vendor/bin/phpcs --standard=WordPress --generator=text --sniffs=WordPress.DateTime.RestrictedFunctions

You get:
Screenshot 2022-03-26 at 15 52 01

@GaryJones
Copy link
Member Author

Fixed my pushing issue, so now rebased onto develop, and it is now ready for review (again).

@Rarst
Copy link
Contributor

Rarst commented Mar 28, 2022

I have no memory of this or mental bandwidth for it, but from quick look at last screenshot I only don't really like gmdate() bit.

It would be a little hard to succinctly document, but gmdate() is kinda "technical" 1:1 replacement, but in many cases code should be written with DateTime anyway. That "wrong" example in practice it should be changed to create from format or something (depending on what's in that input).

Copy link
Member

@jrfnl jrfnl left a comment

Choose a reason for hiding this comment

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

Verified:

  • File is in the right place and uses the correct file name.
  • Displays correctly within character limits when displayed on CLI.
  • Uses space indentation.
  • Code samples comply with WPCS (except for the bit which is being described).
  • Missing: Uses <em> tags to emphasize the "good" vs "bad" code.
  • The start of the "open" and "close" part of the <![CDATA[ markers do not align.

When looking at the docs, I'm wondering if this is one of those where it would be good to have multiple <standard> and <code comparison> blocks.

At this moment, there is one <standard> block at the top with two associated code comparisons, but parts of the text in the <standard> block apply specifically to each code sample, so I'm wondering if a structure like the below would work better ?

<standard>Generic info about the sniff</standard>
<standard>Specific info about the date_default_timezone_set() restriction</standard>
<code_comparison>date_default_timezone_set() code sample</code_comparison>
<standard>Specific info about the date() restriction</standard>
<code_comparison>date() code sample</code_comparison>

<![CDATA[
The restricted functions date_default_timezone_set() and date() should not be used.

Using date_default_timezone_set() isn't allowed, because WordPress core needs default time zone set to UTC. Use DateTime object or WP core API functions instead.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Using date_default_timezone_set() isn't allowed, because WordPress core needs default time zone set to UTC. Use DateTime object or WP core API functions instead.
Using the PHP native date_default_timezone_set() function isn't allowed, because WordPress Core needs the default time zone to be set to UTC for timezone calculations using the WP Core API to work correctly.
Use a DateTime object or use the WP Core API functions instead.


Using date_default_timezone_set() isn't allowed, because WordPress core needs default time zone set to UTC. Use DateTime object or WP core API functions instead.

Using date() isn't allowed, as it is affected by runtime timezone changes which can cause date/time to be incorrectly displayed. Use gmdate() instead.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Using date() isn't allowed, as it is affected by runtime timezone changes which can cause date/time to be incorrectly displayed. Use gmdate() instead.
Using the PHP native date() function isn't allowed, as it is affected by runtime timezone changes which can cause the date/time to be incorrectly displayed. Use gmdate() instead.

<![CDATA[
$date = new DateTime();
$date->setTimezone(
new DateTimeZone( 'Europe/Amsterdam' )
Copy link
Member

Choose a reason for hiding this comment

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

Would it be an idea to "WordPressify" this code sample a little more and use something like get_option() with gmt_offset or timezone_string to retrieve the timezone to be passed to new DateTimeZone() ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the basic PHP example is fine there, people tend to change default time zone to something that is not normal WP time zone.

Again, there is a problem of choice between a technical 1:1 code equivalent and idiomatic rewrite, that is hard to decide on for brief out-of-context example.

@jrfnl jrfnl added this to the 3.0.0 milestone Mar 31, 2022
GaryJones and others added 2 commits June 2, 2022 10:42
Kept the descriptions for individual code comparisons simpler, and populated the <standard> element with more description instead.
@GaryJones GaryJones force-pushed the docs/timezone-change branch from d074fc8 to c6e560b Compare June 2, 2022 10:27
Copy link
Member

@jrfnl jrfnl left a comment

Choose a reason for hiding this comment

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

Thanks for the update @GaryJones ! Looks all good to me! 💯

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

Successfully merging this pull request may close these issues.

4 participants