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

New "DateTime.RestrictedFunctions" sniff #1807

Merged
merged 1 commit into from
Oct 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions WordPress-Core/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,8 @@
<!-- Check for correct spelling of WordPress. -->
<rule ref="WordPress.WP.CapitalPDangit"/>

<!-- Use the appropriate DateTime functions.
See: https://github.com/WordPress/WordPress-Coding-Standards/issues/1713 -->
<rule ref="WordPress.DateTime.RestrictedFunctions"/>

</ruleset>
1 change: 0 additions & 1 deletion WordPress-Extra/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@
<rule ref="WordPress.Security.PluginMenuSlug"/>
<rule ref="WordPress.WP.CronInterval"/>
<rule ref="WordPress.WP.PostsPerPage"/>
<rule ref="WordPress.WP.TimezoneChange"/>

<!-- Verify some regex best practices.
https://github.com/WordPress/WordPress-Coding-Standards/issues/1371 -->
Expand Down
62 changes: 62 additions & 0 deletions WordPress/Sniffs/DateTime/RestrictedFunctionsSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

namespace WordPressCS\WordPress\Sniffs\DateTime;

use WordPressCS\WordPress\AbstractFunctionRestrictionsSniff;

/**
* Forbids the use of various native DateTime related PHP/WP functions and suggests alternatives.
*
* @package WPCS\WordPressCodingStandards
*
* @since 2.2.0
*/
class RestrictedFunctionsSniff extends AbstractFunctionRestrictionsSniff {

/**
* Groups of functions to restrict.
*
* @return array
*/
public function getGroups() {
return array(

/*
* Disallow the changing the timezone.
*
* @link https://vip.wordpress.com/documentation/vip-go/code-review-blockers-warnings-notices/#manipulating-the-timezone-server-side
*/
'timezone_change' => array(
'type' => 'error',
'message' => 'Using %s() and similar isn\'t allowed, instead use WP internal timezone support.',
'functions' => array(
'date_default_timezone_set',
),
),

/*
* Use gmdate(), not date().
* Don't rely on the current PHP time zone as it might have been changed by third party code.
*
* @link https://make.wordpress.org/core/2019/09/23/date-time-improvements-wp-5-3/
* @link https://core.trac.wordpress.org/ticket/46438
* @link https://github.com/WordPress/WordPress-Coding-Standards/issues/1713
*/
'date' => array(
'type' => 'error',
'message' => '%s() is affected by runtime timezone changes which can cause date/time to be incorrectly displayed. Use gmdate() instead.',
'functions' => array(
'date',
),
),
);
}

}
8 changes: 0 additions & 8 deletions WordPress/Sniffs/PHP/RestrictedPHPFunctionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* @package WPCS\WordPressCodingStandards
*
* @since 0.14.0
* @since 2.2.0 New group `date` added.
*/
class RestrictedPHPFunctionsSniff extends AbstractFunctionRestrictionsSniff {

Expand All @@ -43,13 +42,6 @@ public function getGroups() {
'create_function',
),
),
'date' => array(
'type' => 'error',
'message' => '%s() is affected by runtime timezone changes which can cause date/time to be incorrectly displayed. Use gmdate() instead.',
'functions' => array(
'date',
),
),
);
}

Expand Down
72 changes: 53 additions & 19 deletions WordPress/Sniffs/WP/TimezoneChangeSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace WordPressCS\WordPress\Sniffs\WP;

use WordPressCS\WordPress\AbstractFunctionRestrictionsSniff;
use WordPressCS\WordPress\Sniffs\DateTime\RestrictedFunctionsSniff;

/**
* Disallow the changing of timezone.
Expand All @@ -23,32 +23,66 @@
* class instead of the upstream `Generic.PHP.ForbiddenFunctions` sniff.
* @since 0.13.0 Class name changed: this class is now namespaced.
* @since 1.0.0 This sniff has been moved from the `VIP` category to the `WP` category.
*
* @deprecated 2.2.0 Use the `WordPress.DateTime.RestrictedFunctions` sniff instead.
* This `WordPress.WP.TimezoneChange` sniff will be removed in WPCS 3.0.0.
*/
class TimezoneChangeSniff extends AbstractFunctionRestrictionsSniff {
class TimezoneChangeSniff extends RestrictedFunctionsSniff {

/**
* Groups of functions to restrict.
* Keep track of whether the warnings have been thrown to prevent
* the messages being thrown for every token triggering the sniff.
*
* Example: groups => array(
* 'lambda' => array(
* 'type' => 'error' | 'warning',
* 'message' => 'Use anonymous functions instead please!',
* 'functions' => array( 'file_get_contents', 'create_function' ),
* )
* )
* @since 2.2.0
*
* @var array
*/
private $thrown = array(
'DeprecatedSniff' => false,
'FoundPropertyForDeprecatedSniff' => false,
);

/**
* Don't use.
*
* @deprecated 2.2.0
*
* @return array
*/
public function getGroups() {
return array(
'timezone_change' => array(
'type' => 'error',
'message' => 'Using %s() and similar isn\'t allowed, instead use WP internal timezone support.',
'functions' => array(
'date_default_timezone_set',
),
),
);
$groups = parent::getGroups();
return array( 'timezone_change' => $groups['timezone_change'] );
}

/**
* Don't use.
*
* @since 2.2.0 Added to allow for throwing the deprecation notices.
* @deprecated 2.2.0
*
* @param int $stackPtr The position of the current token in the stack.
*
* @return void|int
*/
public function process_token( $stackPtr ) {
if ( false === $this->thrown['DeprecatedSniff'] ) {
$this->thrown['DeprecatedSniff'] = $this->phpcsFile->addWarning(
'The "WordPress.WP.TimezoneChange" sniff has been deprecated. Use the "WordPress.DateTime.RestrictedFunctions" sniff instead. Please update your custom ruleset.',
0,
'DeprecatedSniff'
);
}

if ( ! empty( $this->exclude )
&& false === $this->thrown['FoundPropertyForDeprecatedSniff']
) {
$this->thrown['FoundPropertyForDeprecatedSniff'] = $this->phpcsFile->addWarning(
'The "WordPress.WP.TimezoneChange" sniff has been deprecated. Use the "WordPress.DateTime.RestrictedFunctions" sniff instead. "exclude" property setting found. Please update your custom ruleset.',
0,
'FoundPropertyForDeprecatedSniff'
);
}

return parent::process_token( $stackPtr );
}
}
9 changes: 9 additions & 0 deletions WordPress/Tests/DateTime/RestrictedFunctionsUnitTest.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

date_default_timezone_set( 'Foo/Bar' ); // Bad.

$date = new DateTime();
$date->setTimezone( new DateTimeZone( 'America/Toronto' ) ); // Yay!

$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( __( 'F j, Y' ), $now ), date( __( 'g:i a' ), $now ) ); // Error.
$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), gmdate( __( 'F j, Y' ), $now ), gmdate( __( 'g:i a' ), $now ) ); // OK.
44 changes: 44 additions & 0 deletions WordPress/Tests/DateTime/RestrictedFunctionsUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* Unit test class for WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

namespace WordPressCS\WordPress\Tests\DateTime;

use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;

/**
* Unit test class for the DateTime.RestrictedFunctions sniff.
*
* @package WPCS\WordPressCodingStandards
*
* @since 2.2.0
*/
class RestrictedFunctionsUnitTest extends AbstractSniffUnitTest {

/**
* Returns the lines where errors should occur.
*
* @return array <int line number> => <int number of errors>
*/
public function getErrorList() {
return array(
3 => 1,
8 => 2,
);
}

/**
* Returns the lines where warnings should occur.
*
* @return array <int line number> => <int number of warnings>
*/
public function getWarningList() {
return array();
}

}
3 changes: 0 additions & 3 deletions WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@
add_action( 'widgets_init', create_function( '', // Error.
'return register_widget( "time_more_on_time_widget" );'
) );

$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( __( 'F j, Y' ), $now ), date( __( 'g:i a' ), $now ) ); // Error.
$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), gmdate( __( 'F j, Y' ), $now ), gmdate( __( 'g:i a' ), $now ) ); // OK.
1 change: 0 additions & 1 deletion WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class RestrictedPHPFunctionsUnitTest extends AbstractSniffUnitTest {
public function getErrorList() {
return array(
3 => 1,
7 => 2,
);
}

Expand Down
6 changes: 4 additions & 2 deletions WordPress/Tests/WP/TimezoneChangeUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

date_default_timezone_set( 'Foo/Bar' ); // Bad.

$date = new DateTime();
$date->setTimezone( new DateTimeZone( 'America/Toronto' ) ); // Yay!
// phpcs:set WordPress.WP.TimezoneChange exclude[] timezone_change
date_default_timezone_set( 'Foo/Bar' ); // OK.

// phpcs:set WordPress.WP.TimezoneChange exclude[]
7 changes: 6 additions & 1 deletion WordPress/Tests/WP/TimezoneChangeUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
* @since 0.3.0
* @since 0.13.0 Class name changed: this class is now namespaced.
* @since 1.0.0 This sniff has been moved from the `VIP` category to the `WP` category.
* @since 2.2.0 The sniff has been deprecated. This unit test file now
* only tests that the deprecation warnings are correctly thrown
* and that the sniff falls through to the parent correctly.
*/
class TimezoneChangeUnitTest extends AbstractSniffUnitTest {

Expand All @@ -39,7 +42,9 @@ public function getErrorList() {
* @return array <int line number> => <int number of warnings>
*/
public function getWarningList() {
return array();
return array(
1 => 2,
);
}

}
6 changes: 5 additions & 1 deletion WordPress/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<rule ref="WordPress-Core"/>
-->
<rule ref="WordPress-Docs"/>
<rule ref="WordPress-Extra"/>
<rule ref="WordPress-Extra">
<!-- Prevent duplicate messages + deprecation notice from deprecated sniff. -->
<exclude name="WordPress.WP.TimezoneChange.timezone_change_date_default_timezone_set"/>
<exclude name="WordPress.WP.TimezoneChange.DeprecatedSniff"/>
</rule>

</ruleset>