From e403a8e648dbaec79836ae845d95cea38c37a169 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 10 Sep 2018 20:47:28 +0200 Subject: [PATCH 01/32] ValidHookName: rename unit test case file [1] --- .../{ValidHookNameUnitTest.2.inc => ValidHookNameUnitTest.3.inc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename WordPress/Tests/NamingConventions/{ValidHookNameUnitTest.2.inc => ValidHookNameUnitTest.3.inc} (100%) diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.2.inc b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.3.inc similarity index 100% rename from WordPress/Tests/NamingConventions/ValidHookNameUnitTest.2.inc rename to WordPress/Tests/NamingConventions/ValidHookNameUnitTest.3.inc From 653a89f4fe51f0a4845511347e4f84c1c52f0b28 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 10 Sep 2018 20:48:21 +0200 Subject: [PATCH 02/32] ValidHookName: rename unit test case file [2] --- .../{ValidHookNameUnitTest.1.inc => ValidHookNameUnitTest.2.inc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename WordPress/Tests/NamingConventions/{ValidHookNameUnitTest.1.inc => ValidHookNameUnitTest.2.inc} (100%) diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.2.inc similarity index 100% rename from WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc rename to WordPress/Tests/NamingConventions/ValidHookNameUnitTest.2.inc From bfb7bd6fabddcb61d5c45c0c0e4d0a63527e5b2e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 10 Sep 2018 20:48:45 +0200 Subject: [PATCH 03/32] ValidHookName: rename unit test case file [3] --- ...kNameUnitTest.inc => ValidHookNameUnitTest.1.inc} | 0 .../NamingConventions/ValidHookNameUnitTest.php | 12 ++++++------ 2 files changed, 6 insertions(+), 6 deletions(-) rename WordPress/Tests/NamingConventions/{ValidHookNameUnitTest.inc => ValidHookNameUnitTest.1.inc} (100%) diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.inc b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc similarity index 100% rename from WordPress/Tests/NamingConventions/ValidHookNameUnitTest.inc rename to WordPress/Tests/NamingConventions/ValidHookNameUnitTest.1.inc diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php index 0803b67c7a..eaa60ad06e 100644 --- a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php @@ -27,10 +27,10 @@ class ValidHookNameUnitTest extends AbstractSniffUnitTest { * @param string $testFile The name of the file being tested. * @return array => */ - public function getErrorList( $testFile = 'ValidHookNameUnitTest.inc' ) { + public function getErrorList( $testFile = 'ValidHookNameUnitTest.1.inc' ) { switch ( $testFile ) { - case 'ValidHookNameUnitTest.inc': + case 'ValidHookNameUnitTest.1.inc': return array( 14 => 1, 15 => 1, @@ -70,8 +70,8 @@ public function getErrorList( $testFile = 'ValidHookNameUnitTest.inc' ) { 81 => 1, ); - case 'ValidHookNameUnitTest.1.inc': case 'ValidHookNameUnitTest.2.inc': + case 'ValidHookNameUnitTest.3.inc': default: return array(); } @@ -83,10 +83,10 @@ public function getErrorList( $testFile = 'ValidHookNameUnitTest.inc' ) { * @param string $testFile The name of the file being tested. * @return array => */ - public function getWarningList( $testFile = 'ValidHookNameUnitTest.inc' ) { + public function getWarningList( $testFile = 'ValidHookNameUnitTest.1.inc' ) { switch ( $testFile ) { - case 'ValidHookNameUnitTest.inc': + case 'ValidHookNameUnitTest.1.inc': return array( 8 => 1, 9 => 1, @@ -97,8 +97,8 @@ public function getWarningList( $testFile = 'ValidHookNameUnitTest.inc' ) { 77 => 1, ); - case 'ValidHookNameUnitTest.1.inc': case 'ValidHookNameUnitTest.2.inc': + case 'ValidHookNameUnitTest.3.inc': return array( 12 => 1, 13 => 1, From c3228d74871c6a7a08f425ae3fd381b68672bf1d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 11 Sep 2018 02:11:08 +0200 Subject: [PATCH 04/32] Core ruleset: update inline documentation Sync the inline documentation with the texts as currently in the WP Core handbook. --- WordPress-Core/ruleset.xml | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index e7451c435a..ce2bb7b6fc 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -49,7 +49,8 @@ - @@ -107,9 +108,25 @@ Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#use-elseif-not-else-if ############################################################################# --> + + + + + + + + - + - + @@ -291,7 +310,7 @@ Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#naming-conventions ############################################################################# --> - @@ -360,6 +379,8 @@ constants or literals on the left. --> + + is deprecated in PHP 7.2. ... these must not be used. --> @@ -403,6 +424,8 @@ Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#error-control-operator ############################################################################# --> + From 63a681642ee57fafbe62014885b615bf88bef9c7 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 11 Sep 2018 02:08:47 +0200 Subject: [PATCH 05/32] :sparkles: New sniff to examine type casts This sniff will check that PHP type casts are: - lowercase; - short form, i.e. (bool) not (boolean); - normalized, i.e. (float) not (real). The sniff also discourages the use of the `(unset)` and the `(binary)` casts, including the `b"$string"` binary cast, though it is susceptible to bug squizlabs/PHP_CodeSniffer 1574. The sniff has been added to the `WordPress-Core` ruleset. Once the minimum PHPCS version has gone up to PHPCS 3.3.0+, the lowercase check part of the sniff can be removed in favour of adding the `Generic.PHP.LowerCaseType` sniff to the ruleset instead. Fixes 1481 --- WordPress-Core/ruleset.xml | 1 + WordPress/Sniffs/PHP/TypeCastsSniff.php | 154 ++++++++++++++++++ WordPress/Tests/PHP/TypeCastsUnitTest.inc | 49 ++++++ .../Tests/PHP/TypeCastsUnitTest.inc.fixed | 49 ++++++ WordPress/Tests/PHP/TypeCastsUnitTest.php | 78 +++++++++ 5 files changed, 331 insertions(+) create mode 100644 WordPress/Sniffs/PHP/TypeCastsSniff.php create mode 100644 WordPress/Tests/PHP/TypeCastsUnitTest.inc create mode 100644 WordPress/Tests/PHP/TypeCastsUnitTest.inc.fixed create mode 100644 WordPress/Tests/PHP/TypeCastsUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index e7451c435a..d3058065ba 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -233,6 +233,7 @@ + diff --git a/WordPress/Sniffs/PHP/TypeCastsSniff.php b/WordPress/Sniffs/PHP/TypeCastsSniff.php new file mode 100644 index 0000000000..02cb9d4e28 --- /dev/null +++ b/WordPress/Sniffs/PHP/TypeCastsSniff.php @@ -0,0 +1,154 @@ +tokens[ $stackPtr ]['code']; + $typecast = $this->tokens[ $stackPtr ]['content']; + $typecast_lc = strtolower( $typecast ); + + $this->phpcsFile->recordMetric( $stackPtr, 'Typecast encountered', $typecast ); + + switch ( $token_code ) { + case \T_BOOL_CAST: + if ( '(bool)' !== $typecast_lc ) { + $fix = $this->phpcsFile->addFixableError( + 'Short form type keywords must be used; expected "(bool)" but found "%s"', + $stackPtr, + 'LongBoolFound', + array( $typecast ) + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->replaceToken( $stackPtr, '(bool)' ); + } + } + break; + + case \T_INT_CAST: + if ( '(int)' !== $typecast_lc ) { + $fix = $this->phpcsFile->addFixableError( + 'Short form type keywords must be used; expected "(int)" but found "%s"', + $stackPtr, + 'LongIntFound', + array( $typecast ) + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->replaceToken( $stackPtr, '(int)' ); + } + } + break; + + case \T_DOUBLE_CAST: + if ( '(float)' !== $typecast_lc ) { + $fix = $this->phpcsFile->addFixableError( + 'Normalized type keywords must be used; expected "(float)" but found "%s"', + $stackPtr, + 'DoubleRealFound', + array( $typecast ) + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->replaceToken( $stackPtr, '(float)' ); + } + } + break; + + case \T_UNSET_CAST: + $this->phpcsFile->addWarning( + 'Using the "(unset)" cast is strongly discouraged. Use the "unset()" language construct or assign "null" as the value to the variable instead.', + $stackPtr, + 'UnsetFound' + ); + break; + + case \T_STRING_CAST: + case \T_BINARY_CAST: + if ( \T_STRING_CAST === $token_code && '(binary)' !== $typecast_lc ) { + break; + } + + $this->phpcsFile->addWarning( + 'Using binary casting is strongly discouraged. Found: "%s"', + $stackPtr, + 'BinaryFound', + array( $typecast ) + ); + break; + } + + /* + * {@internal Once the minimum PHPCS version has gone up to PHPCS 3.3.0+, the lowercase + * check below can be removed in favour of adding the `Generic.PHP.LowerCaseType` sniff + * to the ruleset. + * Note: the `register()` function also needs adjusting in that case to only register the + * targetted type casts above and the metrics recording should probably be adjusted as well. + * The above mentioned Generic sniff records metrics about the case of typecasts, so we + * don't need to worry about those no longer being recorded. They will be, just slightly + * differently.}} + */ + if ( $typecast_lc !== $typecast ) { + $data = array( + $typecast_lc, + $typecast, + ); + + $fix = $this->phpcsFile->addFixableError( + 'PHP type casts must be lowercase; expected "%s" but found "%s"', + $stackPtr, + 'NonLowercaseFound', + $data + ); + if ( true === $fix ) { + $this->phpcsFile->fixer->replaceToken( $stackPtr, $typecast_lc ); + } + } + } + +} diff --git a/WordPress/Tests/PHP/TypeCastsUnitTest.inc b/WordPress/Tests/PHP/TypeCastsUnitTest.inc new file mode 100644 index 0000000000..c89bd4d359 --- /dev/null +++ b/WordPress/Tests/PHP/TypeCastsUnitTest.inc @@ -0,0 +1,49 @@ + => + */ + public function getErrorList() { + return array( + 12 => 1, + 13 => 1, + 14 => 1, + 15 => 1, + 24 => 1, + 25 => 2, + 26 => 1, + 27 => 2, + 28 => 1, + 29 => 2, + 30 => 2, + 31 => 1, + 32 => 1, + 33 => 1, + 34 => 1, + 35 => 1, + 38 => 1, + 39 => 2, + 40 => 1, + 41 => 2, + 42 => 1, + 43 => 2, + 44 => 2, + 45 => 1, + 46 => 1, + 47 => 1, + 48 => 1, + 49 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 18 => 1, + 19 => 1, + // 20 => 1, + 21 => 1, + 34 => 1, + 35 => 1, + 48 => 1, + 49 => 1, + ); + } +} From 31541fb3dae7789edd4450a7c1827174bbf51bd8 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 16 Sep 2018 16:16:28 +0200 Subject: [PATCH 06/32] Composer: various tweaks This commit adds two additional scripts and adjusts the existing one. The additional scripts are just shortcuts to run `phpcs` and `phpcbf`. The more important change is how the scripts are run - using the `@php` prefix ensures that the scripts are run against the same PHP version as with which Composer is called, instead of against the system default PHP version. This is important if - as a WPCS dev - you change the PHP version for Composer to be able to test things against different PHP versions. Ref: https://github.com/composer/composer/issues/7645 --- composer.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 7ea713b4e1..fa097aac8c 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,10 @@ }, "type" : "phpcodesniffer-standard", "scripts" : { - "install-codestandards": "\"vendor/bin/phpcs\" --config-set installed_paths ../../..,../../phpcompatibility/php-compatibility", - "post-install-cmd": "@install-codestandards", - "post-update-cmd" : "@install-codestandards" + "install-codestandards": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --config-set installed_paths ../../..,../../phpcompatibility/php-compatibility", + "check-cs" : "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", + "fix-cs" : "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf", + "post-install-cmd" : "@install-codestandards", + "post-update-cmd" : "@install-codestandards" } } From 4219a45a1a2847dcecd90f551e546643db866132 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Mon, 17 Sep 2018 09:44:07 +0100 Subject: [PATCH 07/32] Composer: Normalize composer.json Uses localheinz/composer-normalize to normalize the order and whitespace inside the `composer.json`. No functional differences. --- composer.json | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index fa097aac8c..027b7a5b0d 100644 --- a/composer.json +++ b/composer.json @@ -1,37 +1,40 @@ { - "name" : "wp-coding-standards/wpcs", + "name": "wp-coding-standards/wpcs", + "type": "phpcodesniffer-standard", "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords" : ["phpcs", "standards", "WordPress"], - "license" : "MIT", - "authors" : [ + "keywords": [ + "phpcs", + "standards", + "WordPress" + ], + "license": "MIT", + "authors": [ { - "name" : "Contributors", + "name": "Contributors", "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors" - } ], - "require" : { - "php" : ">=5.3", + "require": { + "php": ">=5.3", "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" }, - "require-dev" : { + "require-dev": { "phpcompatibility/php-compatibility": "*" }, - "suggest" : { + "suggest": { "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." }, - "minimum-stability" : "RC", - "support" : { + "minimum-stability": "RC", + "scripts": { + "post-install-cmd": "@install-codestandards", + "post-update-cmd": "@install-codestandards", + "check-cs": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", + "fix-cs": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf", + "install-codestandards": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --config-set installed_paths ../../..,../../phpcompatibility/php-compatibility" + }, + "support": { "issues": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues", - "wiki" : "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki", + "wiki": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki", "source": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards" - }, - "type" : "phpcodesniffer-standard", - "scripts" : { - "install-codestandards": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --config-set installed_paths ../../..,../../phpcompatibility/php-compatibility", - "check-cs" : "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", - "fix-cs" : "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf", - "post-install-cmd" : "@install-codestandards", - "post-update-cmd" : "@install-codestandards" } } From 600d5c718a069e0f8bffd68d63062f9602d20617 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 23 Sep 2018 01:20:14 +0200 Subject: [PATCH 08/32] Sniff::get_declared_namespace_name(): improve code-style independence A namespace declaration can contain whitespace and comments and PHP will just ignore the whitespace and comments when reading the code. Also see: squizlabs/PHP_CodeSniffer 2150 While it is rare to encounter such code, this utility method should handle it correctly. As for the `$namespaceName` to be returned by the method, this should not contain any whitespace or comments encountered. That way the namespace name will be "clean" for examination by sniffs. Includes unit test via the `GlobalVariablesOverride` sniff. --- WordPress/Sniff.php | 14 ++++++++------ .../Tests/WP/GlobalVariablesOverrideUnitTest.4.inc | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.4.inc diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 24d599da3a..f6cfec7462 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2369,12 +2369,12 @@ public function get_declared_namespace_name( $stackPtr ) { return false; } - if ( \T_NS_SEPARATOR === $this->tokens[ ( $stackPtr + 1 ) ]['code'] ) { + $nextToken = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + if ( \T_NS_SEPARATOR === $this->tokens[ $nextToken ]['code'] ) { // Not a namespace declaration, but use of, i.e. `namespace\someFunction();`. return false; } - $nextToken = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); if ( \T_OPEN_CURLY_BRACKET === $this->tokens[ $nextToken ]['code'] ) { // Declaration for global namespace when using multiple namespaces in a file. // I.e.: `namespace {}`. @@ -2382,16 +2382,18 @@ public function get_declared_namespace_name( $stackPtr ) { } // Ok, this should be a namespace declaration, so get all the parts together. - $validTokens = array( + $acceptedTokens = array( \T_STRING => true, \T_NS_SEPARATOR => true, - \T_WHITESPACE => true, ); + $validTokens = $acceptedTokens + Tokens::$emptyTokens; $namespaceName = ''; while ( isset( $validTokens[ $this->tokens[ $nextToken ]['code'] ] ) ) { - $namespaceName .= trim( $this->tokens[ $nextToken ]['content'] ); - $nextToken++; + if ( isset( $acceptedTokens[ $this->tokens[ $nextToken ]['code'] ] ) ) { + $namespaceName .= trim( $this->tokens[ $nextToken ]['content'] ); + } + ++$nextToken; } return $namespaceName; diff --git a/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.4.inc b/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.4.inc new file mode 100644 index 0000000000..02817b7ba0 --- /dev/null +++ b/WordPress/Tests/WP/GlobalVariablesOverrideUnitTest.4.inc @@ -0,0 +1,14 @@ + Date: Sun, 23 Sep 2018 13:59:50 +0200 Subject: [PATCH 09/32] Sniff::has_whitelist_comment(): ignore CS settings change comments The whitelist comment for a sniff will often be (part of) the sniff name. This causes issues with inline coding standards setting changes which mention the sniff name and can therefore be confused with whitelist comments. While this is mainly an issue for the unit tests, the `has_whitelist_comment()` method should handle this correctly and ignore coding standards setting change comments. Loosely related to 1492 / e1026802fe1dc5a4b7ed7b1b15d0ed1331008b58 --- WordPress/Sniff.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 24d599da3a..188efaa590 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1182,7 +1182,7 @@ protected function has_whitelist_comment( $comment, $stackPtr ) { $regex = '#\b' . preg_quote( $comment, '#' ) . '\b#i'; // There is a findEndOfStatement() method, but it considers more tokens than - // we need to here. + // we need to consider here. $end_of_statement = $this->phpcsFile->findNext( array( \T_CLOSE_TAG, \T_SEMICOLON ), $stackPtr ); if ( false !== $end_of_statement ) { @@ -1194,8 +1194,10 @@ protected function has_whitelist_comment( $comment, $stackPtr ) { $lastPtr = $this->phpcsFile->findPrevious( \T_WHITESPACE, ( $end_of_statement - 1 ), null, true ); } - if ( ( \T_COMMENT === $this->tokens[ $lastPtr ]['code'] - || isset( $this->phpcsCommentTokens[ $this->tokens[ $lastPtr ]['type'] ] ) ) + if ( ( ( \T_COMMENT === $this->tokens[ $lastPtr ]['code'] + && strpos( $this->tokens[ $lastPtr ]['content'], '@codingStandardsChangeSetting' ) === false ) + || ( isset( $this->phpcsCommentTokens[ $this->tokens[ $lastPtr ]['type'] ] ) + && T_PHPCS_SET !== $this->tokens[ $lastPtr ]['type'] ) ) && $this->tokens[ $lastPtr ]['line'] === $this->tokens[ $end_of_statement ]['line'] && preg_match( $regex, $this->tokens[ $lastPtr ]['content'] ) === 1 ) { @@ -1208,8 +1210,10 @@ protected function has_whitelist_comment( $comment, $stackPtr ) { $end_of_line = $this->get_last_ptr_on_line( $stackPtr ); $lastPtr = $this->phpcsFile->findPrevious( \T_WHITESPACE, $end_of_line, null, true ); - if ( ( \T_COMMENT === $this->tokens[ $lastPtr ]['code'] - || isset( $this->phpcsCommentTokens[ $this->tokens[ $lastPtr ]['type'] ] ) ) + if ( ( ( \T_COMMENT === $this->tokens[ $lastPtr ]['code'] + && strpos( $this->tokens[ $lastPtr ]['content'], '@codingStandardsChangeSetting' ) === false ) + || ( isset( $this->phpcsCommentTokens[ $this->tokens[ $lastPtr ]['type'] ] ) + && T_PHPCS_SET !== $this->tokens[ $lastPtr ]['type'] ) ) && $this->tokens[ $lastPtr ]['line'] === $this->tokens[ $stackPtr ]['line'] && preg_match( $regex, $this->tokens[ $lastPtr ]['content'] ) === 1 ) { From b2e9f984b2006ce2a3eef637dbb300bfd51eded3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 8 Oct 2018 02:03:39 +0200 Subject: [PATCH 10/32] Update for PHPCompatibility 9.0.0 [PHPCompatibility 9.0.0](https://github.com/PHPCompatibility/PHPCompatibility/releases/tag/9.0.0) has just been released and renames all sniffs. * Updated the version restrictions in `composer.json`. As the sniff names have changed, set minimum version. Note: PHPCompatibility 9.0.0 is still compatible with PHPCS 2.3.0 up to current, so this doesn't make a difference for running the sniffs. * Updated the WPCS native PHPCS ruleset for the new PHPCompatibility sniff codes. * Updated the inline annotations for the new PHPCompatibility sniff codes. * Updated the `phpcs.xml.dist.sample` to favour the `PHPCompatibilityWP` ruleset (was missed in PR 1426). * Updated a few more links to the PHPCompatibility repo for the move to an organisation (which were missed in PR 1426). --- .phpcs.xml.dist | 20 +++++++++---------- CHANGELOG.md | 2 +- WordPress/Sniff.php | 10 +++++----- .../PrefixAllGlobalsSniff.php | 2 +- composer.json | 2 +- phpcs.xml.dist.sample | 8 +++++--- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 3153fcd76b..ec29a1708c 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -38,18 +38,18 @@ - - - - - - - - - + + + + + + + + + - + diff --git a/CHANGELOG.md b/CHANGELOG.md index f4d6bb8ca8..94e731cc59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -539,7 +539,7 @@ You are also encouraged to check the file history of any WPCS classes you extend - Ability to use a whitelist comment for tax queries for the `WordPress.VIP.SlowDBQuery` sniff. - Instructions on how to use WPCS with Atom and SublimeLinter to the Readme. - Reference to the [wiki](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki) to the Readme. -- Recommendation to also use the [PHPCompatibility](https://github.com/wimg/PHPCompatibility) ruleset to the Readme. +- Recommendation to also use the [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) ruleset to the Readme. ### Changed - The minimum required PHP_CodeSniffer version to 2.6.0. diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 24d599da3a..8af58bd0fe 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2015,8 +2015,8 @@ public function strip_interpolated_variables( $string ) { * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer, it * will detect whether the array has values or is empty. * - * @link https://github.com/wimg/PHPCompatibility/issues/120 - * @link https://github.com/wimg/PHPCompatibility/issues/152 + * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/120 + * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/152 * * @since 0.11.0 * @@ -2082,9 +2082,9 @@ public function does_function_call_have_parameters( $stackPtr ) { * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer, * it will return the number of values in the array. * - * @link https://github.com/wimg/PHPCompatibility/issues/111 - * @link https://github.com/wimg/PHPCompatibility/issues/114 - * @link https://github.com/wimg/PHPCompatibility/issues/151 + * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/111 + * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/114 + * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/151 * * @since 0.11.0 * diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index dd37c1e455..d9ff2b02a8 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -328,7 +328,7 @@ public function process_token( $stackPtr ) { break; case 'T_TRAIT': - // phpcs:ignore PHPCompatibility.PHP.NewFunctions.trait_existsFound + // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.trait_existsFound if ( function_exists( '\trait_exists' ) && trait_exists( '\\' . $item_name, false ) ) { // Backfill for PHP native trait. return; diff --git a/composer.json b/composer.json index 027b7a5b0d..db2f784258 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" }, "require-dev": { - "phpcompatibility/php-compatibility": "*" + "phpcompatibility/php-compatibility": "^9.0" }, "suggest": { "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." diff --git a/phpcs.xml.dist.sample b/phpcs.xml.dist.sample index 411d59a9a2..4563369602 100644 --- a/phpcs.xml.dist.sample +++ b/phpcs.xml.dist.sample @@ -48,14 +48,16 @@ + + + + Date: Mon, 5 Nov 2018 01:38:01 +0100 Subject: [PATCH 21/32] :sparkles: New `I18nTextDomainFixer` utility sniff This sniff can replace the text-domain used in a code-base. The sniff will fix the text-domains in both I18n function calls as well as in a plugin/theme header. The sniff is disabled by default. Passing the following properties will activate the sniff: - `old_text_domain`: an array with one or more (old) text-domain names which need to be replaced; - `new_text_domain`: the correct (new) text-domain as a string. Notes: * The sniff will do a comprehensive find & replace for the text-domains in *all* internationalization related functions, including deprecated/internal use functions and the `load_text_domain()` functions. * The sniff will add the (new) text-domain if it is missing and all the preceding function call arguments are in place. If any of the preceding function call arguments is (also) missing, the sniff will throw a warning, but will not run the fixer. * For a scaffold plugin/theme which doesn't use placeholder text-domains to use this sniff to add the text-domain, the `old_text_domain` property *does* still need to be passed. In that case, just putting anything in it, will do, i.e. ``. * The `default` text-domain is not allowed as the "new" text-domain as it is reserved for WP Core. * The sniff will search for the plugin/theme header and fix the `Text Domain: ...` header if found, or add it, if it is missing. For a comment to be recognized as the plugin/theme header: - At least one required header has to be present. - At least three of the possible headers have to be present. * The sniff will examine all comments to find the plugin/theme header, with these caveats: - For CSS, It will only examine the file if it is called `style.css`. - It will keep track of whether or not the plugin/theme header has been found already and bow out from examining further comments as soon as it has found the header. This is an efficiency mechanism as examining all comments in a code base while we're only looking for one particular one, would make the sniff unnecessarily slow. This also means that running this sniff over two or more plugins/themes in one go will not work, at least not for the fixing of the plugin/theme header. - The sniff does not know in advance whether a plugin or a theme is being examined, so it will look for the header in every file (save non-`style.css` CSS files). - For the unit test files, an exception is build in to prevent us having to have 20+ unit test files just to test the recognition of the headers. Fixes 1174 --- README.md | 16 + .../Sniffs/Utils/I18nTextDomainFixerSniff.php | 725 ++++++++++++++++++ .../Utils/I18nTextDomainFixerUnitTest.1.inc | 6 + .../Utils/I18nTextDomainFixerUnitTest.2.inc | 6 + .../Utils/I18nTextDomainFixerUnitTest.3.inc | 119 +++ .../I18nTextDomainFixerUnitTest.3.inc.fixed | 121 +++ .../Utils/I18nTextDomainFixerUnitTest.4.inc | 199 +++++ .../I18nTextDomainFixerUnitTest.4.inc.fixed | 203 +++++ .../Utils/I18nTextDomainFixerUnitTest.css | 159 ++++ .../I18nTextDomainFixerUnitTest.css.fixed | 164 ++++ .../Utils/I18nTextDomainFixerUnitTest.php | 204 +++++ 11 files changed, 1922 insertions(+) create mode 100644 WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.1.inc create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.2.inc create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed create mode 100644 WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php diff --git a/README.md b/README.md index 5992a758ef..b65c479d05 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ * [Running your code through WPCS automatically using CI tools](#running-your-code-through-wpcs-automatically-using-ci-tools) + [Travis CI](#travis-ci) * [Fixing errors or whitelisting them](#fixing-errors-or-whitelisting-them) + + [Tools shipped with WPCS](#tools-shipped-with-wpcs) * [Contributing](#contributing) * [License](#license) @@ -269,6 +270,21 @@ More examples and advice about integrating PHPCS in your Travis build tests can You can find information on how to deal with some of the more frequent issues in the [wiki](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki). +### Tools shipped with WPCS + +Since version 1.2.0, WPCS has a special sniff category `Utils`. + +This sniff category contains some tools which, generally speaking, will only be needed to be run once over a codebase and for which the fixers can be considered _risky_, i.e. very careful review by a developer is needed before accepting the fixes made by these sniffs. + +The sniffs in this category are disabled by default and can only be activated by adding some properties for each sniff via a custom ruleset. + +At this moment, WPCS offer the following tools: +* `WordPress.Utils.I18nTextDomainFixer` - This sniff can replace the text-domain used in a code-base. + The sniff will fix the text-domains in both I18n function calls as well as in a plugin/theme header. + Passing the following properties will activate the sniff: + - `old_text_domain`: an array with one or more (old) text-domain names which need to be replaced; + - `new_text_domain`: the correct (new) text-domain as a string. + ## Contributing diff --git a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php new file mode 100644 index 0000000000..425c302397 --- /dev/null +++ b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php @@ -0,0 +1,725 @@ + => + */ + protected $target_functions = array( + 'load_textdomain' => 1, + 'load_plugin_textdomain' => 1, + 'load_muplugin_textdomain' => 1, + 'load_theme_textdomain' => 1, + 'load_child_theme_textdomain' => 1, + 'unload_textdomain' => 1, + + '__' => 2, + '_e' => 2, + '_x' => 3, + '_ex' => 3, + '_n' => 4, + '_nx' => 5, + '_n_noop' => 3, + '_nx_noop' => 4, + 'translate_nooped_plural' => 3, + '_c' => 2, // Deprecated. + + 'esc_html__' => 2, + 'esc_html_e' => 2, + 'esc_html_x' => 3, + 'esc_attr__' => 2, + 'esc_attr_e' => 2, + 'esc_attr_x' => 3, + + 'is_textdomain_loaded' => 1, + 'get_translations_for_domain' => 1, + + // Shouldn't be used by plugins/themes. + 'translate' => 2, + 'translate_with_gettext_context' => 3, + + // WP private functions. Shouldn't be used by plugins/themes. + '_load_textdomain_just_in_time' => 1, + '_get_path_to_translation_from_lang_dir' => 1, + '_get_path_to_translation' => 1, + ); + + /** + * Whether a valid new text-domain was found. + * + * @since 1.2.0 + * + * @var string + */ + private $is_valid = false; + + /** + * The new text-domain as validated. + * + * @since 1.2.0 + * + * @var string + */ + private $validated_textdomain = ''; + + /** + * Whether the plugin/theme header has been seen and fixed yet. + * + * @since 1.2.0 + * + * @var string + */ + private $header_found = false; + + /** + * Possible headers for a theme. + * + * @link https://developer.wordpress.org/themes/basics/main-stylesheet-style-css/ + * + * @since 1.2.0 + * + * @var array Array key is the header name, the value indicated whether it is a + * required (true) or optional (false) header. + */ + private $theme_headers = array( + 'Theme Name' => true, + 'Theme URI' => false, + 'Author' => true, + 'Author URI' => false, + 'Description' => true, + 'Version' => true, + 'License' => true, + 'License URI' => true, + 'Tags' => false, + 'Text Domain' => true, + 'Domain Path' => false, + ); + + /** + * Possible headers for a plugin. + * + * @link https://developer.wordpress.org/plugins/the-basics/header-requirements/ + * + * @since 1.2.0 + * + * @var array Array key is the header name, the value indicated whether it is a + * required (true) or optional (false) header. + */ + private $plugin_headers = array( + 'Plugin Name' => true, + 'Plugin URI' => false, + 'Description' => false, + 'Version' => false, + 'Author' => false, + 'Author URI' => false, + 'License' => false, + 'License URI' => false, + 'Text Domain' => false, + 'Domain Path' => false, + 'Network' => false, + ); + + /** + * Regex template to match theme/plugin headers. + * + * @since 1.2.0 + * + * @var string + */ + private $header_regex_template = '`^(?:\s*(?:(?:\*|//)\s*)?)?(%s)\s*:\s*([^\r\n]+)`'; + + /** + * Regex to match theme headers. + * + * Set from within the register() method. + * + * @since 1.2.0 + * + * @var string + */ + private $theme_header_regex; + + /** + * Regex to match plugin headers. + * + * Set from within the register() method. + * + * @since 1.2.0 + * + * @var string + */ + private $plugin_header_regex; + + /** + * The --tab-width CLI value that is being used. + * + * @since 1.2.0 + * + * @var integer + */ + private $tab_width = null; + + /** + * Returns an array of tokens this test wants to listen for. + * + * @since 1.2.0 + * + * @return array + */ + public function register() { + $headers = array_map( + 'preg_quote', + array_keys( $this->theme_headers ), + array_fill( 0, \count( $this->theme_headers ), '`' ) + ); + $this->theme_header_regex = sprintf( $this->header_regex_template, implode( '|', $headers ) ); + + $headers = array_map( + 'preg_quote', + array_keys( $this->plugin_headers ), + array_fill( 0, \count( $this->plugin_headers ), '`' ) + ); + $this->plugin_header_regex = sprintf( $this->header_regex_template, implode( '|', $headers ) ); + + $targets = parent::register(); + + $targets[] = \T_DOC_COMMENT_OPEN_TAG; + $targets[] = \T_COMMENT; + + return $targets; + } + + /** + * Processes this test, when one of its tokens is encountered. + * + * @since 1.2.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return int|void Integer stack pointer to skip forward or void to continue + * normal file processing. + */ + public function process_token( $stackPtr ) { + if ( \T_COMMENT === $this->tokens[ $stackPtr ]['code'] + && strpos( $this->tokens[ $stackPtr ]['content'], '@codingStandardsChangeSetting' ) !== false + ) { + return; + } + + // Check if the old/new properties are correctly set. If not, bow out. + if ( ! is_string( $this->new_text_domain ) + || '' === $this->new_text_domain + ) { + return ( $this->phpcsFile->numTokens + 1 ); + } + + if ( isset( $this->old_text_domain ) ) { + $this->old_text_domain = $this->merge_custom_array( $this->old_text_domain, array(), false ); + + if ( ! is_array( $this->old_text_domain ) + || array() === $this->old_text_domain + ) { + return ( $this->phpcsFile->numTokens + 1 ); + } + } + + // Only validate and throw warning about the text domain once. + if ( $this->new_text_domain !== $this->validated_textdomain ) { + $this->is_valid = false; + $this->validated_textdomain = $this->new_text_domain; + $this->header_found = false; + + if ( 'default' === $this->new_text_domain ) { + $this->phpcsFile->addWarning( + 'The "default" text-domain is reserved for WordPress core use and should not be used by plugins or themes', + 0, + 'ReservedNewDomain', + array( $this->new_text_domain ) + ); + + return ( $this->phpcsFile->numTokens + 1 ); + } + + if ( preg_match( '`^[a-z0-9-]+$`', $this->new_text_domain ) !== 1 ) { + $this->phpcsFile->addWarning( + 'The text-domain should be a simple lowercase text string with words separated by dashes. "%s" appears invalid', + 0, + 'InvalidNewDomain', + array( $this->new_text_domain ) + ); + + return ( $this->phpcsFile->numTokens + 1 ); + } + + // If the text-domain passed both validations, it should be considered valid. + $this->is_valid = true; + + } elseif ( false === $this->is_valid ) { + return ( $this->phpcsFile->numTokens + 1 ); + } + + if ( isset( $this->tab_width ) === false ) { + if ( isset( $this->phpcsFile->config->tabWidth ) === false + || 0 === $this->phpcsFile->config->tabWidth + ) { + // We have no idea how wide tabs are, so assume 4 spaces for fixing. + $this->tab_width = 4; + } else { + $this->tab_width = $this->phpcsFile->config->tabWidth; + } + } + + if ( \T_DOC_COMMENT_OPEN_TAG === $this->tokens[ $stackPtr ]['code'] + || \T_COMMENT === $this->tokens[ $stackPtr ]['code'] + ) { + // Examine for plugin/theme file header. + return $this->process_comments( $stackPtr ); + + } elseif ( 'CSS' !== $this->phpcsFile->tokenizerType ) { + // Examine a T_STRING token in a PHP file as a function call. + return parent::process_token( $stackPtr ); + } + } + + + /** + * Process the parameters of a matched function. + * + * @since 1.2.0 + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. + * @param string $matched_content The token content (function name) which was matched. + * @param array $parameters Array with information about the parameters. + * + * @return void + */ + public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) { + $target_param = $this->target_functions[ $matched_content ]; + + if ( isset( $parameters[ $target_param ] ) === false && 1 !== $target_param ) { + $error_msg = 'Missing $domain arg'; + $error_code = 'MissingArgDomain'; + + if ( isset( $parameters[ ( $target_param - 1 ) ] ) ) { + $fix = $this->phpcsFile->addFixableError( $error_msg, $stackPtr, $error_code ); + + if ( true === $fix ) { + $start_previous = $parameters[ ( $target_param - 1 ) ]['start']; + $end_previous = $parameters[ ( $target_param - 1 ) ]['end']; + if ( \T_WHITESPACE === $this->tokens[ $start_previous ]['code'] + && $this->tokens[ $start_previous ]['content'] === $this->phpcsFile->eolChar + ) { + // Replicate the new line + indentation of the previous item. + $replacement = ','; + for ( $i = $start_previous; $i <= $end_previous; $i++ ) { + if ( \T_WHITESPACE !== $this->tokens[ $i ]['code'] ) { + break; + } + + if ( isset( $this->tokens[ $i ]['orig_content'] ) ) { + $replacement .= $this->tokens[ $i ]['orig_content']; + } else { + $replacement .= $this->tokens[ $i ]['content']; + } + } + + $replacement .= "'{$this->new_text_domain}'"; + } else { + $replacement = ", '{$this->new_text_domain}'"; + } + + if ( \T_WHITESPACE === $this->tokens[ $end_previous ]['code'] ) { + $this->phpcsFile->fixer->addContentBefore( $end_previous, $replacement ); + } else { + $this->phpcsFile->fixer->addContent( $end_previous, $replacement ); + } + } + } else { + $error_msg .= ' and preceding argument(s)'; + $error_code = 'MissingArgs'; + + // Expected preceeding param also missing, just throw the warning. + $this->phpcsFile->addWarning( $error_msg, $stackPtr, $error_code ); + } + + return; + } + + // Target parameter found. Let's examine it. + $domain_param_start = $parameters[ $target_param ]['start']; + $domain_param_end = $parameters[ $target_param ]['end']; + $domain_token = null; + + for ( $i = $domain_param_start; $i <= $domain_param_end; $i++ ) { + if ( isset( Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { + continue; + } + + if ( \T_CONSTANT_ENCAPSED_STRING !== $this->tokens[ $i ]['code'] ) { + // Unexpected token found, not our concern. This is handled by the I18n sniff. + return; + } + + if ( isset( $domain_token ) ) { + // More than one T_CONSTANT_ENCAPSED_STRING found, not our concern. This is handled by the I18n sniff. + return; + } + + $domain_token = $i; + } + + // If we're still here, this means only one T_CONSTANT_ENCAPSED_STRING was found. + $old_domain = $this->strip_quotes( $this->tokens[ $domain_token ]['content'] ); + + if ( ! \in_array( $old_domain, $this->old_text_domain, true ) ) { + // Not a text-domain targetted for replacement, ignore. + return; + } + + $fix = $this->phpcsFile->addFixableError( + 'Mismatched text domain. Expected \'%s\' but found \'%s\'', + $domain_token, + 'TextDomainMismatch', + array( $this->new_text_domain, $old_domain ) + ); + + if ( true === $fix ) { + $replacement = str_replace( $old_domain, $this->new_text_domain, $this->tokens[ $domain_token ]['content'] ); + $this->phpcsFile->fixer->replaceToken( $domain_token, $replacement ); + } + } + + /** + * Process the function if no parameters were found. + * + * @since 1.2.0 + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. + * @param string $matched_content The token content (function name) which was matched. + * + * @return void + */ + public function process_no_parameters( $stackPtr, $group_name, $matched_content ) { + + $target_param = $this->target_functions[ $matched_content ]; + + if ( 1 !== $target_param ) { + // Only process the no param case as fixable if the text-domain is expected to be the first parameter. + $this->phpcsFile->addWarning( 'Missing $domain arg and preceding argument(s)', $stackPtr, 'MissingArgs' ); + return; + } + + $opener = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + if ( \T_OPEN_PARENTHESIS !== $this->tokens[ $opener ]['code'] + || isset( $this->tokens[ $opener ]['parenthesis_closer'] ) === false + ) { + // Parse error or live coding. + return; + } + + $fix = $this->phpcsFile->addFixableError( 'Missing $domain arg', $stackPtr, 'MissingArgDomain' ); + if ( true === $fix ) { + $closer = $this->tokens[ $opener ]['parenthesis_closer']; + $replacement = " '{$this->new_text_domain}' "; + + if ( $this->tokens[ $opener ]['line'] !== $this->tokens[ $closer ]['line'] ) { + $replacement = trim( $replacement ); + $addBefore = ( $closer - 1 ); + if ( \T_WHITESPACE === $this->tokens[ ( $closer - 1 ) ]['code'] + && $this->tokens[ $closer - 1 ]['line'] === $this->tokens[ $closer ]['line'] + ) { + if ( isset( $this->tokens[ ( $closer - 1 ) ]['orig_content'] ) ) { + $replacement = $this->tokens[ ( $closer - 1 ) ]['orig_content'] + . "\t" + . $replacement; + } else { + $replacement = $this->tokens[ ( $closer - 1 ) ]['content'] + . str_repeat( ' ', $this->tab_width ) + . $replacement; + } + + --$addBefore; + } else { + // We don't know whether the code uses tabs or spaces, so presume WPCS, i.e. tabs. + $replacement = "\t" . $replacement; + } + + $replacement = $this->phpcsFile->eolChar . $replacement; + + $this->phpcsFile->fixer->addContentBefore( $addBefore, $replacement ); + + } elseif ( \T_WHITESPACE === $this->tokens[ ( $closer - 1 ) ]['code'] ) { + $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), $replacement ); + } else { + $this->phpcsFile->fixer->addContentBefore( $closer, $replacement ); + } + } + } + + + /** + * Process comments to find the plugin/theme headers. + * + * @since 1.2.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return void + */ + public function process_comments( $stackPtr ) { + if ( true === $this->header_found && ! defined( 'PHP_CODESNIFFER_IN_TESTS' ) ) { + return; + } + + $regex = $this->plugin_header_regex; + $headers = $this->plugin_headers; + $type = 'plugin'; + $skip_to = $stackPtr; + + $file = $this->strip_quotes( $this->phpcsFile->getFileName() ); + if ( 'STDIN' === $file ) { + return; + } + + $file_name = basename( $file ); + if ( 'CSS' === $this->phpcsFile->tokenizerType ) { + if ( 'style.css' !== $file_name && ! defined( 'PHP_CODESNIFFER_IN_TESTS' ) ) { + // CSS files only need to be examined for the file header. + return ( $this->phpcsFile->numTokens + 1 ); + } + + $regex = $this->theme_header_regex; + $headers = $this->theme_headers; + $type = 'theme'; + } + + $comment_details = array( + 'required_header_found' => false, + 'headers_found' => 0, + 'text_domain_ptr' => false, + 'text_domain_found' => '', + 'last_header_ptr' => false, + 'last_header_matches' => array(), + ); + + if ( \T_COMMENT === $this->tokens[ $stackPtr ]['code'] ) { + $block_comment = false; + if ( substr( $this->tokens[ $stackPtr ]['content'], 0, 2 ) === '/*' ) { + $block_comment = true; + } + + $current = $stackPtr; + do { + if ( false === $comment_details['text_domain_ptr'] + || false === $comment_details['required_header_found'] + || $comment_details['headers_found'] < 3 + ) { + $comment_details = $this->examine_comment_line( $current, $regex, $headers, $comment_details ); + } + + if ( true === $block_comment && substr( $this->tokens[ $current ]['content'], -2 ) === '*/' ) { + ++$current; + break; + } + + ++$current; + } while ( isset( $this->tokens[ $current ] ) && \T_COMMENT === $this->tokens[ $current ]['code'] ); + + $skip_to = $current; + + } else { + if ( ! isset( $this->tokens[ $stackPtr ]['comment_closer'] ) ) { + return; + } + + $closer = $this->tokens[ $stackPtr ]['comment_closer']; + $current = $stackPtr; + + while ( ( $current = $this->phpcsFile->findNext( \T_DOC_COMMENT_STRING, ( $current + 1 ), $closer ) ) !== false ) { + $comment_details = $this->examine_comment_line( $current, $regex, $headers, $comment_details ); + + if ( false !== $comment_details['text_domain_ptr'] + && true === $comment_details['required_header_found'] + && $comment_details['headers_found'] >= 3 + ) { + // No need to look at the rest of the docblock. + break; + } + } + + $skip_to = $closer; + } + + // So, was this the plugin/theme header ? + if ( true === $comment_details['required_header_found'] + && $comment_details['headers_found'] >= 3 + ) { + $this->header_found = true; + + $text_domain_ptr = $comment_details['text_domain_ptr']; + $text_domain_found = $comment_details['text_domain_found']; + + if ( false !== $text_domain_ptr ) { + if ( $this->new_text_domain !== $text_domain_found + && ( \in_array( $text_domain_found, $this->old_text_domain, true ) ) + ) { + $fix = $this->phpcsFile->addFixableError( + 'Mismatched text domain in %s header. Expected \'%s\' but found \'%s\'', + $text_domain_ptr, + 'TextDomainHeaderMismatch', + array( + $type, + $this->new_text_domain, + $text_domain_found, + ) + ); + + if ( true === $fix ) { + $replacement = str_replace( + $text_domain_found, + $this->new_text_domain, + $this->tokens[ $text_domain_ptr ]['content'] + ); + + $this->phpcsFile->fixer->replaceToken( $text_domain_ptr, $replacement ); + } + } + } else { + $last_header_ptr = $comment_details['last_header_ptr']; + $last_header_matches = $comment_details['last_header_matches']; + + $fix = $this->phpcsFile->addFixableError( + 'Missing "Text Domain" in %s header', + $last_header_ptr, + 'MissingTextDomainHeader', + array( $type ) + ); + + if ( true === $fix ) { + $replacement = $this->tokens[ $last_header_ptr ]['content']; + $replacement = str_replace( $last_header_matches[1], 'Text Domain', $replacement ); + $replacement = str_replace( $last_header_matches[2], $this->new_text_domain, $replacement ); + + if ( \T_DOC_COMMENT_OPEN_TAG === $this->tokens[ $stackPtr ]['code'] ) { + for ( $i = ( $last_header_ptr - 1 ); ; $i-- ) { + if ( $this->tokens[ $i ]['line'] !== $this->tokens[ $last_header_ptr ]['line'] ) { + ++$i; + break; + } + } + + $replacement = $this->phpcsFile->eolChar + . $this->phpcsFile->getTokensAsString( $i, ( $last_header_ptr - $i ), true ) + . $replacement; + } + + $this->phpcsFile->fixer->addContent( $comment_details['last_header_ptr'], $replacement ); + } + } + } + + return $skip_to; + } + + /** + * Examine an individual token in a larger comment for plugin/theme headers. + * + * @since 1.2.0 + * + * @param int $stackPtr The position of the current token in the stack. + * @param string $regex The regex to use to examine the comment line. + * @param array $headers Valid headers for a plugin or theme. + * @param array $comment_details The information collected so far. + * + * @return array Adjusted $comment_details array + */ + protected function examine_comment_line( $stackPtr, $regex, $headers, $comment_details ) { + if ( preg_match( $regex, $this->tokens[ $stackPtr ]['content'], $matches ) === 1 ) { + ++$comment_details['headers_found']; + + if ( true === $headers[ $matches[1] ] ) { + $comment_details['required_header_found'] = true; + } + + if ( 'Text Domain' === $matches[1] ) { + $comment_details['text_domain_ptr'] = $stackPtr; + $comment_details['text_domain_found'] = trim( $matches[2] ); + } + + $comment_details['last_header_ptr'] = $stackPtr; + $comment_details['last_header_matches'] = $matches; + } + + return $comment_details; + } +} diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.1.inc b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.1.inc new file mode 100644 index 0000000000..08665c16f5 --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.1.inc @@ -0,0 +1,6 @@ + + * @link https://github.com/jrfnl/Debug-Bar-Constants + * @version 2.0.0 + * + * @copyright 2013-2018 Juliette Reinders Folmer + * @license http://creativecommons.org/licenses/GPL/2.0/ GNU General Public License, version 2 or higher + * + * @wordpress-plugin + * Plugin Name: Debug Bar Constants + * Plugin URI: https://wordpress.org/plugins/debug-bar-constants/ + * Description: Debug Bar Constants adds new panels to Debug Bar that display all the defined constants for the current request. Requires "Debug Bar" plugin. + * Version: 2.0.0 + * Author: Juliette Reinders Folmer + * Author URI: http://www.adviesenzo.nl/ + * Depends: Debug Bar + * Text Domain: debug-bar-constants + * Domain Path: /languages + * Copyright: 2013-2018 Juliette Reinders Folmer + */ + +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain a2-optimized + +// Plugin Name: Text domain which should be fixed, multi-line //-style comment. +// Plugin URI: https://wordpress.org/plugins/a2-optimized/ +// Version: 2.0.1 +// Author: A2 Hosting +// Author URI: https://www.a2hosting.com/ +// Description: A2 Optimized - WordPress Optimization Plugin +// Text Domain: a2-optimized +// License: GPLv2 or Later + +// Plugin Name: Not enough headers to verify this is the header. +// Plugin URI: https://wordpress.org/plugins/a2-optimized/ + +/** + * Plugin Name: Missing text domain, docblock format. + * Plugin URI: http://www.bigvoodoo.com + * Description: Ensures the Git repositories are kept current and up to date with uploads made within WordPress. + * Author: Big Voodoo Interactive + * Version: 0.1.0 + * Author URI: http://www.bigvoodoo.com + * @author Big Voodoo Interactive + * @TODO error reporting + */ + +// Plugin Name: Missing text domain, multi-line //-style comment, minimal headers. +// Plugin URI: https://wordpress.org/plugins/a2-optimized/ +// Version: 2.0.1 + +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed new file mode 100644 index 0000000000..5c6388ef07 --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed @@ -0,0 +1,121 @@ + + * @link https://github.com/jrfnl/Debug-Bar-Constants + * @version 2.0.0 + * + * @copyright 2013-2018 Juliette Reinders Folmer + * @license http://creativecommons.org/licenses/GPL/2.0/ GNU General Public License, version 2 or higher + * + * @wordpress-plugin + * Plugin Name: Debug Bar Constants + * Plugin URI: https://wordpress.org/plugins/debug-bar-constants/ + * Description: Debug Bar Constants adds new panels to Debug Bar that display all the defined constants for the current request. Requires "Debug Bar" plugin. + * Version: 2.0.0 + * Author: Juliette Reinders Folmer + * Author URI: http://www.adviesenzo.nl/ + * Depends: Debug Bar + * Text Domain: something-else + * Domain Path: /languages + * Copyright: 2013-2018 Juliette Reinders Folmer + */ + +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain a2-optimized + +// Plugin Name: Text domain which should be fixed, multi-line //-style comment. +// Plugin URI: https://wordpress.org/plugins/a2-optimized/ +// Version: 2.0.1 +// Author: A2 Hosting +// Author URI: https://www.a2hosting.com/ +// Description: A2 Optimized - WordPress Optimization Plugin +// Text Domain: something-else +// License: GPLv2 or Later + +// Plugin Name: Not enough headers to verify this is the header. +// Plugin URI: https://wordpress.org/plugins/a2-optimized/ + +/** + * Plugin Name: Missing text domain, docblock format. + * Plugin URI: http://www.bigvoodoo.com + * Description: Ensures the Git repositories are kept current and up to date with uploads made within WordPress. + * Author: Big Voodoo Interactive + * Version: 0.1.0 + * Author URI: http://www.bigvoodoo.com + * Text Domain: something-else + * @author Big Voodoo Interactive + * @TODO error reporting + */ + +// Plugin Name: Missing text domain, multi-line //-style comment, minimal headers. +// Plugin URI: https://wordpress.org/plugins/a2-optimized/ +// Version: 2.0.1 +// Text Domain: something-else + +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc new file mode 100644 index 0000000000..938f7bf529 --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc @@ -0,0 +1,199 @@ +translate( $text, 'third-text-domain' ); +self::translate( $text, 'third-text-domain' ); +MyNameSpace\Second\translate( $text, 'third-text-domain' ); + +__( $text, "a $interpolated string" ); +_e( $text, 'concatenated' . 'string' ); +_x( $text, $context, $variableTextdomain ); +_ex( $text, $context, CONSTANT_TEXTDOMAIN ); + +/* + * Text domains *not* in the whitelisted "old" domain list should be ignored. + */ +load_plugin_textdomain( 'tgmpa', false, '/languages/' ); +_e( $text, 'default' ); +is_textdomain_loaded( 'some-other-plugin' ); + +/* + * Incorrect text-domain, should be replaced. + */ +load_textdomain( 'text-domain', '/path/to/file.mo' ); +load_plugin_textdomain( 'text-domain', false, '/languages/' ); +load_muplugin_textdomain( 'other-text-domain', '/languages/' ); +load_theme_textdomain( 'third-text-domain', '/path/to/languages/' ); +load_child_theme_textdomain( 'text-domain', '/path/to/languages/' ); +unload_textdomain( 'text-domain' ); + +__( $text, 'text-domain' ); +_e( $text, 'text-domain' ); +_x( $text, $context, 'text-domain' ); +_ex( $text, $context, 'third-text-domain' ); +_n($single,$plural,$number,'text-domain'); +_nx( $single, $plural, $number, $context, 'text-domain' ); +_n_noop( $singular, $plural, 'other-text-domain' ); +_nx_noop( $singular, + $plural, + $context, 'text-domain' ); +translate_nooped_plural( $nooped_plural, $count, "text-domain" ); +_c( $text, 'text-domain' ); + +esc_html__( $text, 'third-text-domain' ); +esc_html_e( $text, 'text-domain' ); +esc_html_x($text, $context, 'text-domain'); +esc_attr__( $text, 'text-domain' ); +esc_attr_e( $text, 'other-text-domain' ); +esc_attr_x( + $text, + $context, + 'text-domain' +); + +is_textdomain_loaded( 'text-domain' ); +get_translations_for_domain( 'other-text-domain' ); + +translate( $text, 'third-text-domain' ); +translate_with_gettext_context( + $text, + $context, + 'text-domain', +); + +_load_textdomain_just_in_time( 'third-text-domain' ); +_get_path_to_translation_from_lang_dir( 'text-domain' ); +_get_path_to_translation( 'other-text-domain', true ); + +/* + * Missing text-domain, should be added. + */ +load_textdomain(); +load_plugin_textdomain( /* everything missing, but has a comment */ ); +load_muplugin_textdomain( ); +load_theme_textdomain(); + load_child_theme_textdomain( + ); +unload_textdomain(); + +__( $text ); +_e( $text ); +_x( $text, $context, ); // PHP 7.3 trailing comma in function call. +_ex( $text, $context ); +_n( $single, $plural, $number ); +_nx( $single, $plural, $number, $context ); +_n_noop( $singular, $plural ); +_nx_noop( $singular, $plural, $context ); +translate_nooped_plural( $nooped_plural, $count ); +_c( $text ); + +esc_html__($text); +esc_html_e( $text ); +esc_html_x( + $text, + $context, +); // PHP 7.3 trailing comma in multi-line function call. +esc_attr__( $text); +esc_attr_e($text ); +esc_attr_x( + $text, + $context ); + +is_textdomain_loaded( +); +get_translations_for_domain(); + +translate( $text); +translate_with_gettext_context( $text, $context); + +_load_textdomain_just_in_time(); +_get_path_to_translation_from_lang_dir(); +_get_path_to_translation(); + +/* + * Missing text-domain and preceeding args, only throw warning. + */ +__(); +_e( /* comment */ ); +_x( ); +_ex(); +_n( $single, $plural ); +_nx( $single, $plural ); +_n_noop($singular); +_nx_noop( +); +translate_nooped_plural( $nooped_plural ); +_c(); + +esc_html__(); +esc_html_e( ); +esc_html_x( + $text, +); // PHP 7.3 trailing comma in multi-line function call. +esc_attr__(); +esc_attr_e(); +esc_attr_x( + $text, +); + +translate(); +translate_with_gettext_context( $text); + +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed new file mode 100644 index 0000000000..478c99838b --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed @@ -0,0 +1,203 @@ +translate( $text, 'third-text-domain' ); +self::translate( $text, 'third-text-domain' ); +MyNameSpace\Second\translate( $text, 'third-text-domain' ); + +__( $text, "a $interpolated string" ); +_e( $text, 'concatenated' . 'string' ); +_x( $text, $context, $variableTextdomain ); +_ex( $text, $context, CONSTANT_TEXTDOMAIN ); + +/* + * Text domains *not* in the whitelisted "old" domain list should be ignored. + */ +load_plugin_textdomain( 'tgmpa', false, '/languages/' ); +_e( $text, 'default' ); +is_textdomain_loaded( 'some-other-plugin' ); + +/* + * Incorrect text-domain, should be replaced. + */ +load_textdomain( 'something-else', '/path/to/file.mo' ); +load_plugin_textdomain( 'something-else', false, '/languages/' ); +load_muplugin_textdomain( 'something-else', '/languages/' ); +load_theme_textdomain( 'something-else', '/path/to/languages/' ); +load_child_theme_textdomain( 'something-else', '/path/to/languages/' ); +unload_textdomain( 'something-else' ); + +__( $text, 'something-else' ); +_e( $text, 'something-else' ); +_x( $text, $context, 'something-else' ); +_ex( $text, $context, 'something-else' ); +_n($single,$plural,$number,'something-else'); +_nx( $single, $plural, $number, $context, 'something-else' ); +_n_noop( $singular, $plural, 'something-else' ); +_nx_noop( $singular, + $plural, + $context, 'something-else' ); +translate_nooped_plural( $nooped_plural, $count, "something-else" ); +_c( $text, 'something-else' ); + +esc_html__( $text, 'something-else' ); +esc_html_e( $text, 'something-else' ); +esc_html_x($text, $context, 'something-else'); +esc_attr__( $text, 'something-else' ); +esc_attr_e( $text, 'something-else' ); +esc_attr_x( + $text, + $context, + 'something-else' +); + +is_textdomain_loaded( 'something-else' ); +get_translations_for_domain( 'something-else' ); + +translate( $text, 'something-else' ); +translate_with_gettext_context( + $text, + $context, + 'something-else', +); + +_load_textdomain_just_in_time( 'something-else' ); +_get_path_to_translation_from_lang_dir( 'something-else' ); +_get_path_to_translation( 'something-else', true ); + +/* + * Missing text-domain, should be added. + */ +load_textdomain( 'something-else' ); +load_plugin_textdomain( /* everything missing, but has a comment */ 'something-else' ); +load_muplugin_textdomain( 'something-else' ); +load_theme_textdomain( 'something-else' ); + load_child_theme_textdomain( + 'something-else' + ); +unload_textdomain( 'something-else' ); + +__( $text, 'something-else' ); +_e( $text, 'something-else' ); +_x( $text, $context, 'something-else', ); // PHP 7.3 trailing comma in function call. +_ex( $text, $context, 'something-else' ); +_n( $single, $plural, $number, 'something-else' ); +_nx( $single, $plural, $number, $context, 'something-else' ); +_n_noop( $singular, $plural, 'something-else' ); +_nx_noop( $singular, $plural, $context, 'something-else' ); +translate_nooped_plural( $nooped_plural, $count, 'something-else' ); +_c( $text, 'something-else' ); + +esc_html__($text, 'something-else'); +esc_html_e( $text, 'something-else' ); +esc_html_x( + $text, + $context, + 'something-else', +); // PHP 7.3 trailing comma in multi-line function call. +esc_attr__( $text, 'something-else'); +esc_attr_e($text, 'something-else' ); +esc_attr_x( + $text, + $context, + 'something-else' ); + +is_textdomain_loaded( + 'something-else' +); +get_translations_for_domain( 'something-else' ); + +translate( $text, 'something-else'); +translate_with_gettext_context( $text, $context, 'something-else'); + +_load_textdomain_just_in_time( 'something-else' ); +_get_path_to_translation_from_lang_dir( 'something-else' ); +_get_path_to_translation( 'something-else' ); + +/* + * Missing text-domain and preceeding args, only throw warning. + */ +__(); +_e( /* comment */ ); +_x( ); +_ex(); +_n( $single, $plural ); +_nx( $single, $plural ); +_n_noop($singular); +_nx_noop( +); +translate_nooped_plural( $nooped_plural ); +_c(); + +esc_html__(); +esc_html_e( ); +esc_html_x( + $text, +); // PHP 7.3 trailing comma in multi-line function call. +esc_attr__(); +esc_attr_e(); +esc_attr_x( + $text, +); + +translate(); +translate_with_gettext_context( $text); + +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false +// @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css new file mode 100644 index 0000000000..69885b795d --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css @@ -0,0 +1,159 @@ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain twentyeleven */ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain twentyten */ + +/* +Theme Name: Correct text-domain. +Theme URI: https://wordpress.org/themes/twentyten/ +Description: The 2010 theme for WordPress is stylish, customizable, simple, and readable -- make it yours with a custom menu, header image, and background. Twenty Ten supports six widgetized areas (two in the sidebar, four in the footer) and featured images (thumbnails for gallery posts and custom header images for posts and pages). It includes stylesheets for print and the admin Visual Editor, special styles for posts in the "Asides" and "Gallery" categories, and has an optional one-column page template that removes the sidebar. +Author: the WordPress team +Author URI: https://wordpress.org/ +Version: 2.5 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Tags: blog, two-columns, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu, flexible-header, featured-images, footer-widgets, featured-image-header +Text Domain: twentyten +*/ + +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain _s */ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain something-else */ + +/*! +Theme Name: Text domain which should be fixed and checking that consecutive comments don't get mixed up. +Theme URI: https://underscores.me/ +Author: Automattic +Author URI: https://automattic.com/ +Description: Hi. I'm a starter theme called _s, or underscores, if you like. I'm a theme meant for hacking so don't use me as a Parent Theme. Instead try turning me into the next, most awesome, WordPress theme out there. That's what I'm here for. +Version: 1.0.0 +License: GNU General Public License v2 or later +License URI: LICENSE +Text Domain: _s +Tags: custom-background, custom-logo, custom-menu, featured-images, threaded-comments, translation-ready + +This theme, like WordPress, is licensed under the GPL. +Use it to make something cool, have fun, and share what you've learned with others. + +_s is based on Underscores https://underscores.me/, (C) 2012-2017 Automattic, Inc. +Underscores is distributed under the terms of the GNU GPL v2 or later. + +Normalizing styles have been helped along thanks to the fine work of +Nicolas Gallagher and Jonathan Neal https://necolas.github.io/normalize.css/ +*/ +/*-------------------------------------------------------------- +>>> TABLE OF CONTENTS: +---------------------------------------------------------------- +# Normalize +# Typography +# Elements +# Forms +# Navigation + ## Links + ## Menus +# Accessibility +# Alignments +# Clearings +# Widgets +# Content + ## Posts and pages + ## Comments +# Infinite scroll +# Media + ## Captions + ## Galleries +--------------------------------------------------------------*/ +/*-------------------------------------------------------------- +# Normalize +--------------------------------------------------------------*/ +/* normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain twentyseventeen */ + +/* +Theme Name: Missing text domain. +Theme URI: https://wordpress.org/themes/twentyseventeen/ +Author: the WordPress team +Author URI: https://wordpress.org/ +Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. +Version: 1.6 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Tags: one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready + +This theme, like WordPress, is licensed under the GPL. +Use it to make something cool, have fun, and share what you've learned with others. +*/ + +/* + * Theme Name : Missing text domain, different comment format. + * Theme URI : https://wordpress.org/themes/twentyseventeen/ + * Author : the WordPress team + * Author URI : https://wordpress.org/ + * Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. + * Version : 1.6 + * License : GNU General Public License v2 or later + * License URI: http://www.gnu.org/licenses/gpl-2.0.html + * Tags : one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready + * + * This theme, like WordPress, is licensed under the GPL. + * Use it to make something cool, have fun, and share what you've learned with others. + */ + +/* + * Theme Name: Not the theme header (not enough headers found. + */ + +/* +Theme Name: Missing text domain. Minimum headers. +Theme URI: http://protected +Description: http://thisshouldntbeaurl +*/ + +/* + Theme Name: Missing text domain, different comment format, additional non-standard headers. + Theme URI: https://protected + Author: Lacy Morrow + Author URI: http://protected + Description: A Ghost-like WordPress theme. Casper (for WordPress) is a simple yet beautiful theme for bloggers. Inspired by the Ghost blogging platform, Casper is a WordPress port of the default theme by the same name. The goal of this project is to emulate the gorgeous theme while taking advantage of features exclusive to the WordPress framework. There are plenty of customization options included, accessible through the WordPress Customizer. Already included are hooks to serve responsive images appropriately and media queries to provide a fast and seamless experience from desktop to mobile. For questions, support, development instructions, or to contribute to the project visit [https://github.com/lacymorrow/casper] + Version: 1.1.5 + License: GNU General Public License v2.0 + License URI: http://www.gnu.org/licenses/gpl-2.0.html + Domain Path: /languages/ + Tags: responsive-layout, black, white, one-column, fluid-layout, custom-header, custom-menu, editor-style + GitHub Theme URI: https://github.com/protected + GitHub Branch: master + Casper is based on Underscores http://underscores.me/, (C) 2012-2014 Automattic, Inc. +*/ + +/** + * Theme Name: Missing text domain. Docblock format. + * Theme URI: https://github.com/WordPress/twentynineteen + * Author: the WordPress team + * Author URI: https://wordpress.org/ + * Description: A new Gutenberg-ready theme. + * Requires at least: WordPress 4.9.6 + * Version: 1.0 + * License: GNU General Public License v2 or later + * License URI: LICENSE + * Tags: custom-background, custom-logo, custom-menu, featured-images, threaded-comments, translation-ready + * This theme, like WordPress, is licensed under the GPL. + * Use it to make something cool, have fun, and share what you've learned with others. + * Twenty Nineteen is based on Underscores https://underscores.me/, (C) 2012-2018 Automattic, Inc. + * Underscores is distributed under the terms of the GNU GPL v2 or later. + * Normalizing styles have been helped along thanks to the fine work of + * Nicolas Gallagher and Jonathan Neal https://necolas.github.io/normalize.css/ + */ + +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false */ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false */ diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed new file mode 100644 index 0000000000..7bd3c83e69 --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed @@ -0,0 +1,164 @@ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain twentyeleven */ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain twentyten */ + +/* +Theme Name: Correct text-domain. +Theme URI: https://wordpress.org/themes/twentyten/ +Description: The 2010 theme for WordPress is stylish, customizable, simple, and readable -- make it yours with a custom menu, header image, and background. Twenty Ten supports six widgetized areas (two in the sidebar, four in the footer) and featured images (thumbnails for gallery posts and custom header images for posts and pages). It includes stylesheets for print and the admin Visual Editor, special styles for posts in the "Asides" and "Gallery" categories, and has an optional one-column page template that removes the sidebar. +Author: the WordPress team +Author URI: https://wordpress.org/ +Version: 2.5 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Tags: blog, two-columns, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu, flexible-header, featured-images, footer-widgets, featured-image-header +Text Domain: twentyten +*/ + +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain _s */ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain something-else */ + +/*! +Theme Name: Text domain which should be fixed and checking that consecutive comments don't get mixed up. +Theme URI: https://underscores.me/ +Author: Automattic +Author URI: https://automattic.com/ +Description: Hi. I'm a starter theme called _s, or underscores, if you like. I'm a theme meant for hacking so don't use me as a Parent Theme. Instead try turning me into the next, most awesome, WordPress theme out there. That's what I'm here for. +Version: 1.0.0 +License: GNU General Public License v2 or later +License URI: LICENSE +Text Domain: something-else +Tags: custom-background, custom-logo, custom-menu, featured-images, threaded-comments, translation-ready + +This theme, like WordPress, is licensed under the GPL. +Use it to make something cool, have fun, and share what you've learned with others. + +_s is based on Underscores https://underscores.me/, (C) 2012-2017 Automattic, Inc. +Underscores is distributed under the terms of the GNU GPL v2 or later. + +Normalizing styles have been helped along thanks to the fine work of +Nicolas Gallagher and Jonathan Neal https://necolas.github.io/normalize.css/ +*/ +/*-------------------------------------------------------------- +>>> TABLE OF CONTENTS: +---------------------------------------------------------------- +# Normalize +# Typography +# Elements +# Forms +# Navigation + ## Links + ## Menus +# Accessibility +# Alignments +# Clearings +# Widgets +# Content + ## Posts and pages + ## Comments +# Infinite scroll +# Media + ## Captions + ## Galleries +--------------------------------------------------------------*/ +/*-------------------------------------------------------------- +# Normalize +--------------------------------------------------------------*/ +/* normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain twentyseventeen */ + +/* +Theme Name: Missing text domain. +Theme URI: https://wordpress.org/themes/twentyseventeen/ +Author: the WordPress team +Author URI: https://wordpress.org/ +Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. +Version: 1.6 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Tags: one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready +Text Domain: twentyseventeen + +This theme, like WordPress, is licensed under the GPL. +Use it to make something cool, have fun, and share what you've learned with others. +*/ + +/* + * Theme Name : Missing text domain, different comment format. + * Theme URI : https://wordpress.org/themes/twentyseventeen/ + * Author : the WordPress team + * Author URI : https://wordpress.org/ + * Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. + * Version : 1.6 + * License : GNU General Public License v2 or later + * License URI: http://www.gnu.org/licenses/gpl-2.0.html + * Tags : one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready + * Text Domain : twentyseventeen + * + * This theme, like WordPress, is licensed under the GPL. + * Use it to make something cool, have fun, and share what you've learned with others. + */ + +/* + * Theme Name: Not the theme header (not enough headers found. + */ + +/* +Theme Name: Missing text domain. Minimum headers. +Theme URI: http://protected +Description: http://thisshouldntbeaurl +Text Domain: twentyseventeen +*/ + +/* + Theme Name: Missing text domain, different comment format, additional non-standard headers. + Theme URI: https://protected + Author: Lacy Morrow + Author URI: http://protected + Description: A Ghost-like WordPress theme. Casper (for WordPress) is a simple yet beautiful theme for bloggers. Inspired by the Ghost blogging platform, Casper is a WordPress port of the default theme by the same name. The goal of this project is to emulate the gorgeous theme while taking advantage of features exclusive to the WordPress framework. There are plenty of customization options included, accessible through the WordPress Customizer. Already included are hooks to serve responsive images appropriately and media queries to provide a fast and seamless experience from desktop to mobile. For questions, support, development instructions, or to contribute to the project visit [https://github.com/lacymorrow/casper] + Version: 1.1.5 + License: GNU General Public License v2.0 + License URI: http://www.gnu.org/licenses/gpl-2.0.html + Domain Path: /languages/ + Tags: responsive-layout, black, white, one-column, fluid-layout, custom-header, custom-menu, editor-style + Text Domain: twentyseventeen + GitHub Theme URI: https://github.com/protected + GitHub Branch: master + Casper is based on Underscores http://underscores.me/, (C) 2012-2014 Automattic, Inc. +*/ + +/** + * Theme Name: Missing text domain. Docblock format. + * Theme URI: https://github.com/WordPress/twentynineteen + * Author: the WordPress team + * Author URI: https://wordpress.org/ + * Description: A new Gutenberg-ready theme. + * Requires at least: WordPress 4.9.6 + * Version: 1.0 + * License: GNU General Public License v2 or later + * License URI: LICENSE + * Tags: custom-background, custom-logo, custom-menu, featured-images, threaded-comments, translation-ready + * Text Domain: twentyseventeen + * This theme, like WordPress, is licensed under the GPL. + * Use it to make something cool, have fun, and share what you've learned with others. + * Twenty Nineteen is based on Underscores https://underscores.me/, (C) 2012-2018 Automattic, Inc. + * Underscores is distributed under the terms of the GNU GPL v2 or later. + * Normalizing styles have been helped along thanks to the fine work of + * Nicolas Gallagher and Jonathan Neal https://necolas.github.io/normalize.css/ + */ + +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false */ +/* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false */ diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php new file mode 100644 index 0000000000..840ca8c116 --- /dev/null +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php @@ -0,0 +1,204 @@ +tab_width ); + } + + return array(); + } + + /** + * Set CLI values before the file is tested. + * + * Used by PHPCS 3.x. + * + * @param string $testFile The name of the file being tested. + * @param \PHP_CodeSniffer\Config $config The config data for the test run. + * + * @return void + */ + public function setCliValues( $testFile, $config ) { + // Tab width setting is only needed for the file with the function calls. + if ( 'I18nTextDomainFixerUnitTest.4.inc' === $testFile ) { + $config->tabWidth = $this->tab_width; + } else { + $config->tabWidth = 0; + } + } + + /** + * Returns the lines where errors should occur. + * + * @param string $testFile The name of the file being tested. + * @return array => + */ + public function getErrorList( $testFile = '' ) { + + switch ( $testFile ) { + case 'I18nTextDomainFixerUnitTest.css': + return array( + 29 => 1, + 92 => 1, + 107 => 1, + 120 => 1, + 133 => 1, + 149 => 1, + ); + + case 'I18nTextDomainFixerUnitTest.3.inc': + return array( + 32 => 1, + 42 => 1, + 84 => 1, + 97 => 1, + 109 => 1, + 116 => 1, + ); + + case 'I18nTextDomainFixerUnitTest.4.inc': + return array( + 79 => 1, + 80 => 1, + 81 => 1, + 82 => 1, + 83 => 1, + 84 => 1, + 86 => 1, + 87 => 1, + 88 => 1, + 89 => 1, + 90 => 1, + 91 => 1, + 92 => 1, + 95 => 1, + 96 => 1, + 97 => 1, + 99 => 1, + 100 => 1, + 101 => 1, + 102 => 1, + 103 => 1, + 107 => 1, + 110 => 1, + 111 => 1, + 113 => 1, + 117 => 1, + 120 => 1, + 121 => 1, + 122 => 1, + 127 => 1, + 128 => 1, + 129 => 1, + 130 => 1, + 131 => 1, + 133 => 1, + 135 => 1, + 136 => 1, + 137 => 1, + 138 => 1, + 139 => 1, + 140 => 1, + 141 => 1, + 142 => 1, + 143 => 1, + 144 => 1, + 146 => 1, + 147 => 1, + 148 => 1, + 152 => 1, + 153 => 1, + 154 => 1, + 158 => 1, + 160 => 1, + 162 => 1, + 163 => 1, + 165 => 1, + 166 => 1, + 167 => 1, + ); + + default: + return array(); + } + } + + /** + * Returns the lines where warnings should occur. + * + * @param string $testFile The name of the file being tested. + * @return array => + */ + public function getWarningList( $testFile = '' ) { + switch ( $testFile ) { + case 'I18nTextDomainFixerUnitTest.1.inc': + case 'I18nTextDomainFixerUnitTest.2.inc': + return array( + 1 => 1, + ); + + case 'I18nTextDomainFixerUnitTest.4.inc': + return array( + 172 => 1, + 173 => 1, + 174 => 1, + 175 => 1, + 176 => 1, + 177 => 1, + 178 => 1, + 179 => 1, + 181 => 1, + 182 => 1, + 184 => 1, + 185 => 1, + 186 => 1, + 189 => 1, + 190 => 1, + 191 => 1, + 195 => 1, + 196 => 1, + ); + + default: + return array(); + } + } + +} From b693b690071c7a9677b2a9f9310d199a8c6646ea Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 6 Nov 2018 13:26:23 +0100 Subject: [PATCH 22/32] I18nTextDomainFixer: add support for additional deprecated functions --- WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php | 4 ++++ WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc | 8 ++++++++ .../Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed | 8 ++++++++ WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php index 425c302397..cf2ffceca9 100644 --- a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php +++ b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php @@ -91,6 +91,10 @@ class I18nTextDomainFixerSniff extends AbstractFunctionParameterSniff { '_nx_noop' => 4, 'translate_nooped_plural' => 3, '_c' => 2, // Deprecated. + '_nc' => 4, // Deprecated. + '__ngettext' => 4, // Deprecated. + '__ngettext_noop' => 3, // Deprecated. + 'translate_with_context' => 2, // Deprecated. 'esc_html__' => 2, 'esc_html_e' => 2, diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc index 938f7bf529..fd5a37bcef 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc @@ -195,5 +195,13 @@ esc_attr_x( translate(); translate_with_gettext_context( $text); +/* + * Additional deprecated functions. + */ +_nc( $single, $plural ); // Warning. +__ngettext( $singular, $plural, $number ); // Error. +__ngettext_noop( $singular, $plural, 'other-text-domain' ); // Error. +translate_with_context( $text, 'third-text-domain' ); // Error. + // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed index 478c99838b..96619dff99 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed @@ -199,5 +199,13 @@ esc_attr_x( translate(); translate_with_gettext_context( $text); +/* + * Additional deprecated functions. + */ +_nc( $single, $plural ); // Warning. +__ngettext( $singular, $plural, $number, 'something-else' ); // Error. +__ngettext_noop( $singular, $plural, 'something-else' ); // Error. +translate_with_context( $text, 'something-else' ); // Error. + // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain false // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain false diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php index 840ca8c116..58d450a282 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.php @@ -153,6 +153,9 @@ public function getErrorList( $testFile = '' ) { 165 => 1, 166 => 1, 167 => 1, + 202 => 1, + 203 => 1, + 204 => 1, ); default: @@ -194,6 +197,7 @@ public function getWarningList( $testFile = '' ) { 191 => 1, 195 => 1, 196 => 1, + 201 => 1, ); default: From 613a28f8d65009782f28e0af2c318324495bfa51 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 6 Nov 2018 13:29:00 +0100 Subject: [PATCH 23/32] I18nTextDomainFixer: minor documentation touch up --- WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php | 10 +++++----- .../Tests/Utils/I18nTextDomainFixerUnitTest.4.inc | 8 ++++---- .../Utils/I18nTextDomainFixerUnitTest.4.inc.fixed | 8 ++++---- WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css | 2 +- .../Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php index cf2ffceca9..5daf98c65f 100644 --- a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php +++ b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php @@ -117,7 +117,7 @@ class I18nTextDomainFixerSniff extends AbstractFunctionParameterSniff { ); /** - * Whether a valid new text-domain was found. + * Whether a valid new text domain was found. * * @since 1.2.0 * @@ -126,7 +126,7 @@ class I18nTextDomainFixerSniff extends AbstractFunctionParameterSniff { private $is_valid = false; /** - * The new text-domain as validated. + * The new text domain as validated. * * @since 1.2.0 * @@ -323,7 +323,7 @@ public function process_token( $stackPtr ) { return ( $this->phpcsFile->numTokens + 1 ); } - // If the text-domain passed both validations, it should be considered valid. + // If the text domain passed both validations, it should be considered valid. $this->is_valid = true; } elseif ( false === $this->is_valid ) { @@ -445,7 +445,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p $old_domain = $this->strip_quotes( $this->tokens[ $domain_token ]['content'] ); if ( ! \in_array( $old_domain, $this->old_text_domain, true ) ) { - // Not a text-domain targetted for replacement, ignore. + // Not a text domain targetted for replacement, ignore. return; } @@ -478,7 +478,7 @@ public function process_no_parameters( $stackPtr, $group_name, $matched_content $target_param = $this->target_functions[ $matched_content ]; if ( 1 !== $target_param ) { - // Only process the no param case as fixable if the text-domain is expected to be the first parameter. + // Only process the no param case as fixable if the text domain is expected to be the first parameter. $this->phpcsFile->addWarning( 'Missing $domain arg and preceding argument(s)', $stackPtr, 'MissingArgs' ); return; } diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc index fd5a37bcef..6a3d0dd42f 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc @@ -11,7 +11,7 @@ */ /* - * Correct text-domain, no replacement needed. + * Correct text domain, no replacement needed. */ load_textdomain( 'something-else', '/path/to/file.mo' ); load_plugin_textdomain( 'something-else', false, '/languages/' ); @@ -74,7 +74,7 @@ _e( $text, 'default' ); is_textdomain_loaded( 'some-other-plugin' ); /* - * Incorrect text-domain, should be replaced. + * Incorrect text domain, should be replaced. */ load_textdomain( 'text-domain', '/path/to/file.mo' ); load_plugin_textdomain( 'text-domain', false, '/languages/' ); @@ -122,7 +122,7 @@ _get_path_to_translation_from_lang_dir( 'text-domain' ); _get_path_to_translation( 'other-text-domain', true ); /* - * Missing text-domain, should be added. + * Missing text domain, should be added. */ load_textdomain(); load_plugin_textdomain( /* everything missing, but has a comment */ ); @@ -167,7 +167,7 @@ _get_path_to_translation_from_lang_dir(); _get_path_to_translation(); /* - * Missing text-domain and preceeding args, only throw warning. + * Missing text domain and preceeding args, only throw warning. */ __(); _e( /* comment */ ); diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed index 96619dff99..6de97bc125 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.4.inc.fixed @@ -11,7 +11,7 @@ */ /* - * Correct text-domain, no replacement needed. + * Correct text domain, no replacement needed. */ load_textdomain( 'something-else', '/path/to/file.mo' ); load_plugin_textdomain( 'something-else', false, '/languages/' ); @@ -74,7 +74,7 @@ _e( $text, 'default' ); is_textdomain_loaded( 'some-other-plugin' ); /* - * Incorrect text-domain, should be replaced. + * Incorrect text domain, should be replaced. */ load_textdomain( 'something-else', '/path/to/file.mo' ); load_plugin_textdomain( 'something-else', false, '/languages/' ); @@ -122,7 +122,7 @@ _get_path_to_translation_from_lang_dir( 'something-else' ); _get_path_to_translation( 'something-else', true ); /* - * Missing text-domain, should be added. + * Missing text domain, should be added. */ load_textdomain( 'something-else' ); load_plugin_textdomain( /* everything missing, but has a comment */ 'something-else' ); @@ -171,7 +171,7 @@ _get_path_to_translation_from_lang_dir( 'something-else' ); _get_path_to_translation( 'something-else' ); /* - * Missing text-domain and preceeding args, only throw warning. + * Missing text domain and preceeding args, only throw warning. */ __(); _e( /* comment */ ); diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css index 69885b795d..a95d6322cf 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css @@ -2,7 +2,7 @@ /* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain twentyten */ /* -Theme Name: Correct text-domain. +Theme Name: Correct text domain. Theme URI: https://wordpress.org/themes/twentyten/ Description: The 2010 theme for WordPress is stylish, customizable, simple, and readable -- make it yours with a custom menu, header image, and background. Twenty Ten supports six widgetized areas (two in the sidebar, four in the footer) and featured images (thumbnails for gallery posts and custom header images for posts and pages). It includes stylesheets for print and the admin Visual Editor, special styles for posts in the "Asides" and "Gallery" categories, and has an optional one-column page template that removes the sidebar. Author: the WordPress team diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed index 7bd3c83e69..94c39c3dc1 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed @@ -2,7 +2,7 @@ /* @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer new_text_domain twentyten */ /* -Theme Name: Correct text-domain. +Theme Name: Correct text domain. Theme URI: https://wordpress.org/themes/twentyten/ Description: The 2010 theme for WordPress is stylish, customizable, simple, and readable -- make it yours with a custom menu, header image, and background. Twenty Ten supports six widgetized areas (two in the sidebar, four in the footer) and featured images (thumbnails for gallery posts and custom header images for posts and pages). It includes stylesheets for print and the admin Visual Editor, special styles for posts in the "Asides" and "Gallery" categories, and has an optional one-column page template that removes the sidebar. Author: the WordPress team From ec5403e40733d8554f9098da840dd6c2110b5b24 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 6 Nov 2018 13:43:47 +0100 Subject: [PATCH 24/32] I18nTextDomainFixer: improve handling of whitespace in headers While WPCS does not allow for inline tab alignment, this sniff should respect the tab vs space choice made in the original code. This was already handled correctly for the function call parts of the sniff. This commit improves this for the plugin/theme header part of the sniff. Includes unit tests. --- .../Sniffs/Utils/I18nTextDomainFixerSniff.php | 19 +++++++++++----- .../Utils/I18nTextDomainFixerUnitTest.3.inc | 22 +++++++++---------- .../I18nTextDomainFixerUnitTest.3.inc.fixed | 22 +++++++++---------- .../Utils/I18nTextDomainFixerUnitTest.css | 18 +++++++-------- .../I18nTextDomainFixerUnitTest.css.fixed | 20 ++++++++--------- 5 files changed, 54 insertions(+), 47 deletions(-) diff --git a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php index 5daf98c65f..936798f0ab 100644 --- a/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php +++ b/WordPress/Sniffs/Utils/I18nTextDomainFixerSniff.php @@ -649,11 +649,13 @@ public function process_comments( $stackPtr ) { ); if ( true === $fix ) { - $replacement = str_replace( - $text_domain_found, - $this->new_text_domain, - $this->tokens[ $text_domain_ptr ]['content'] - ); + if ( isset( $this->tokens[ $text_domain_ptr ]['orig_content'] ) ) { + $replacement = $this->tokens[ $text_domain_ptr ]['orig_content']; + } else { + $replacement = $this->tokens[ $text_domain_ptr ]['content']; + } + + $replacement = str_replace( $text_domain_found, $this->new_text_domain, $replacement ); $this->phpcsFile->fixer->replaceToken( $text_domain_ptr, $replacement ); } @@ -670,7 +672,12 @@ public function process_comments( $stackPtr ) { ); if ( true === $fix ) { - $replacement = $this->tokens[ $last_header_ptr ]['content']; + if ( isset( $this->tokens[ $last_header_ptr ]['orig_content'] ) ) { + $replacement = $this->tokens[ $last_header_ptr ]['orig_content']; + } else { + $replacement = $this->tokens[ $last_header_ptr ]['content']; + } + $replacement = str_replace( $last_header_matches[1], 'Text Domain', $replacement ); $replacement = str_replace( $last_header_matches[2], $this->new_text_domain, $replacement ); diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc index f3476df258..a3b1fd6c9c 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc @@ -63,7 +63,7 @@ class Debug_Bar { // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain debug-bar-constants /** - * Text domain which should be fixed, docblock format with PHP doc tags. + * Text domain which should be fixed, docblock format with PHP doc tags and tab aligned. * * @package WordPress\Plugins\Debug Bar Constants * @author Juliette Reinders Folmer @@ -74,16 +74,16 @@ class Debug_Bar { * @license http://creativecommons.org/licenses/GPL/2.0/ GNU General Public License, version 2 or higher * * @wordpress-plugin - * Plugin Name: Debug Bar Constants - * Plugin URI: https://wordpress.org/plugins/debug-bar-constants/ - * Description: Debug Bar Constants adds new panels to Debug Bar that display all the defined constants for the current request. Requires "Debug Bar" plugin. - * Version: 2.0.0 - * Author: Juliette Reinders Folmer - * Author URI: http://www.adviesenzo.nl/ - * Depends: Debug Bar - * Text Domain: debug-bar-constants - * Domain Path: /languages - * Copyright: 2013-2018 Juliette Reinders Folmer + * Plugin Name : Debug Bar Constants + * Plugin URI : https://wordpress.org/plugins/debug-bar-constants/ + * Description : Debug Bar Constants adds new panels to Debug Bar that display all the defined constants for the current request. Requires "Debug Bar" plugin. + * Version : 2.0.0 + * Author : Juliette Reinders Folmer + * Author URI : http://www.adviesenzo.nl/ + * Depends : Debug Bar + * Text Domain : debug-bar-constants + * Domain Path : /languages + * Copyright : 2013-2018 Juliette Reinders Folmer */ // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain a2-optimized diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed index 5c6388ef07..4561666706 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.3.inc.fixed @@ -63,7 +63,7 @@ class Debug_Bar { // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain debug-bar-constants /** - * Text domain which should be fixed, docblock format with PHP doc tags. + * Text domain which should be fixed, docblock format with PHP doc tags and tab aligned. * * @package WordPress\Plugins\Debug Bar Constants * @author Juliette Reinders Folmer @@ -74,16 +74,16 @@ class Debug_Bar { * @license http://creativecommons.org/licenses/GPL/2.0/ GNU General Public License, version 2 or higher * * @wordpress-plugin - * Plugin Name: Debug Bar Constants - * Plugin URI: https://wordpress.org/plugins/debug-bar-constants/ - * Description: Debug Bar Constants adds new panels to Debug Bar that display all the defined constants for the current request. Requires "Debug Bar" plugin. - * Version: 2.0.0 - * Author: Juliette Reinders Folmer - * Author URI: http://www.adviesenzo.nl/ - * Depends: Debug Bar - * Text Domain: something-else - * Domain Path: /languages - * Copyright: 2013-2018 Juliette Reinders Folmer + * Plugin Name : Debug Bar Constants + * Plugin URI : https://wordpress.org/plugins/debug-bar-constants/ + * Description : Debug Bar Constants adds new panels to Debug Bar that display all the defined constants for the current request. Requires "Debug Bar" plugin. + * Version : 2.0.0 + * Author : Juliette Reinders Folmer + * Author URI : http://www.adviesenzo.nl/ + * Depends : Debug Bar + * Text Domain : something-else + * Domain Path : /languages + * Copyright : 2013-2018 Juliette Reinders Folmer */ // @codingStandardsChangeSetting WordPress.Utils.I18nTextDomainFixer old_text_domain a2-optimized diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css index a95d6322cf..14bbd7e26d 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css @@ -96,15 +96,15 @@ Use it to make something cool, have fun, and share what you've learned with othe */ /* - * Theme Name : Missing text domain, different comment format. - * Theme URI : https://wordpress.org/themes/twentyseventeen/ - * Author : the WordPress team - * Author URI : https://wordpress.org/ - * Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. - * Version : 1.6 - * License : GNU General Public License v2 or later - * License URI: http://www.gnu.org/licenses/gpl-2.0.html - * Tags : one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready + * Theme Name : Missing text domain, different comment format, tab aligned. + * Theme URI : https://wordpress.org/themes/twentyseventeen/ + * Author : the WordPress team + * Author URI : https://wordpress.org/ + * Description : Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. + * Version : 1.6 + * License : GNU General Public License v2 or later + * License URI : http://www.gnu.org/licenses/gpl-2.0.html + * Tags : one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready * * This theme, like WordPress, is licensed under the GPL. * Use it to make something cool, have fun, and share what you've learned with others. diff --git a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed index 94c39c3dc1..05534342a0 100644 --- a/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed +++ b/WordPress/Tests/Utils/I18nTextDomainFixerUnitTest.css.fixed @@ -97,16 +97,16 @@ Use it to make something cool, have fun, and share what you've learned with othe */ /* - * Theme Name : Missing text domain, different comment format. - * Theme URI : https://wordpress.org/themes/twentyseventeen/ - * Author : the WordPress team - * Author URI : https://wordpress.org/ - * Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. - * Version : 1.6 - * License : GNU General Public License v2 or later - * License URI: http://www.gnu.org/licenses/gpl-2.0.html - * Tags : one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready - * Text Domain : twentyseventeen + * Theme Name : Missing text domain, different comment format, tab aligned. + * Theme URI : https://wordpress.org/themes/twentyseventeen/ + * Author : the WordPress team + * Author URI : https://wordpress.org/ + * Description : Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. + * Version : 1.6 + * License : GNU General Public License v2 or later + * License URI : http://www.gnu.org/licenses/gpl-2.0.html + * Tags : one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready + * Text Domain : twentyseventeen * * This theme, like WordPress, is licensed under the GPL. * Use it to make something cool, have fun, and share what you've learned with others. From 146aef7aa5e1443fae28f6f5f1620322c6f61914 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Tue, 21 Aug 2018 11:20:47 +0100 Subject: [PATCH 25/32] Create issue templates See #1454 --- .github/ISSUE_TEMPLATE/bug_report.md | 29 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/dependency-change.md | 17 ++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 14 ++++++++++ 3 files changed, 60 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/dependency-change.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..0f2fe83cb1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +## Bug Summary + + +## Minimal Code Snippet + + +## Error Code + + +## Versions + +| Item | Version +| ----------------| ------- +| WPCS | x.y.z +| PHP_CodeSniffer | x.y.z +| PHP | x.y.z + + +## Additional Context (optional) + + +## Possible Workaround (optional) + diff --git a/.github/ISSUE_TEMPLATE/dependency-change.md b/.github/ISSUE_TEMPLATE/dependency-change.md new file mode 100644 index 0000000000..2e5d2afb71 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/dependency-change.md @@ -0,0 +1,17 @@ +--- +name: Dependency Change +about: A reminder to take action when a WPCS dependency changes + +--- + + + +## Dependency Version + +When the ... dependency is at least version ..., then take the actions below. + +## Action checklist + +- [ ] ... diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..a3c52371af --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +## Is your feature request related to a problem? + + +## Describe the solution you'd like + + +## Additional context + From 0fc737de9ba9432c32a9af35a3687391e56e643d Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Wed, 22 Aug 2018 22:19:13 +0100 Subject: [PATCH 26/32] Issue Templates: Update based on feedback See #1454. --- .github/CONTRIBUTING.md | 2 ++ .github/ISSUE_TEMPLATE/bug_report.md | 40 ++++++++++++++++------- .github/ISSUE_TEMPLATE/feature_request.md | 9 +++-- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2cdbc0eec0..a497a78486 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,6 +2,8 @@ Hi, thank you for your interest in contributing to the WordPress Coding Standard # Reporting Bugs +Please search the repo to see if your issue has been reported already and if so, comment in that issue instead of opening a new one. + Before reporting a bug, you should check what sniff an error is coming from. Running `phpcs` with the `-s` flag will show the name of the sniff with each error. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0f2fe83cb1..eca63a8755 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,26 +4,42 @@ about: Create a report to help us improve --- -## Bug Summary - +## Bug Description + ## Minimal Code Snippet - + + +``` +// Place your code sample here. +``` ## Error Code - + -## Versions +## Environment -| Item | Version -| ----------------| ------- -| WPCS | x.y.z -| PHP_CodeSniffer | x.y.z -| PHP | x.y.z +| Question | Answer +| ------------------------| ------- +| PHP version | x.y.z +| PHP_CodeSniffer version | x.y.z +| WPCS version | x.y.z +| WPCS install type | e.g. Composer global, Composer project local, git clone, other (please expand) +| IDE (if relevant) | Name and version e.g. PhpStorm 2018.2.2 ## Additional Context (optional) -## Possible Workaround (optional) - +## Tested Against `develop` branch? +- [ ] I have verified the issue still exists in the `develop` branch of WPCS. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index a3c52371af..37e3ef86ea 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -5,10 +5,15 @@ about: Suggest an idea for this project --- ## Is your feature request related to a problem? - + ## Describe the solution you'd like - + ## Additional context From 667f5b75313fa71e37a727d5f6f75b3533f78197 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Wed, 12 Sep 2018 15:13:43 +0100 Subject: [PATCH 27/32] Templates: Update Dependency Change per feedback --- .github/ISSUE_TEMPLATE/dependency-change.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/dependency-change.md b/.github/ISSUE_TEMPLATE/dependency-change.md index 2e5d2afb71..8f36c7c418 100644 --- a/.github/ISSUE_TEMPLATE/dependency-change.md +++ b/.github/ISSUE_TEMPLATE/dependency-change.md @@ -4,14 +4,18 @@ about: A reminder to take action when a WPCS dependency changes --- - + -## Dependency Version - -When the ... dependency is at least version ..., then take the actions below. +## Rationale -## Action checklist + + +## References + + + + - ... + +## Action Checklist - [ ] ... From 9efc5d26aad9119eb4b9a09fb7e4fefbfd5adb47 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Thu, 13 Sep 2018 08:02:20 +0100 Subject: [PATCH 28/32] Template: Add code block language --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index eca63a8755..dfe249022b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -16,7 +16,7 @@ For bugs with fixers: How the code was fixed? How did you expect the code to be ## Minimal Code Snippet -``` +```php // Place your code sample here. ``` From d32f7afe466b614538600cc0ad822c128df00a84 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Tue, 6 Nov 2018 13:51:52 +0000 Subject: [PATCH 29/32] Template: Update issue templates per feedback See #1454 --- .github/ISSUE_TEMPLATE/bug_report.md | 6 ++++-- .github/ISSUE_TEMPLATE/dependency-change.md | 4 ++-- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dfe249022b..5fec9e2c30 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,8 +9,6 @@ about: Create a report to help us improve Please provide a clear and concise description of what the bug is. What did you expect to happen? What actually happened? - -For bugs with fixers: How the code was fixed? How did you expect the code to be fixed? --> ## Minimal Code Snippet @@ -20,11 +18,15 @@ For bugs with fixers: How the code was fixed? How did you expect the code to be // Place your code sample here. ``` +For bugs with fixers: How was the code fixed? How did you expect the code to be fixed? + ## Error Code ## Environment diff --git a/.github/ISSUE_TEMPLATE/dependency-change.md b/.github/ISSUE_TEMPLATE/dependency-change.md index 8f36c7c418..740abf51ad 100644 --- a/.github/ISSUE_TEMPLATE/dependency-change.md +++ b/.github/ISSUE_TEMPLATE/dependency-change.md @@ -8,11 +8,11 @@ about: A reminder to take action when a WPCS dependency changes ## Rationale - + ## References - + - ... diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 37e3ef86ea..34b43e7bf8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -15,5 +15,5 @@ Any (sniff) feature request/suggestion should be accompanied by code samples of And preferably also code samples of code which shouldn't be flagged. --> -## Additional context +## Additional context (optional) From 48ea0e302719e2722a84f73e4d57edbf63a617c8 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Wed, 10 Oct 2018 14:41:07 +0100 Subject: [PATCH 30/32] Docs: Remove and update VIP link references The WordPress.com VIP team moved their coding standards documentation around, since they now have different documents for their different platforms: - [WPCOM platform](https://lobby.vip.wordpress.com/wordpress-com-documentation/code-review-what-we-look-for/) (only available to those with VIP Lobby access) - [VIP-Go platform](https://vip.wordpress.com/documentation/vip-go/code-review-blockers-warnings-notices/) Many of the existing link references were out of date and pointed to pages or page anchors that didn't exist. Since our `WordPress-VIP` standard is deprecated, and will be removed in `2.0.0`, it's easier to remove all of the link references in the `VIP` category ruleset and sniffs. The only ones that remain are ones that are used as references for sniffs typically found in `WordPress-Extra` (outside of the `VIP` category). They have been updated as necessary. --- README.md | 2 +- WordPress-VIP/ruleset.xml | 41 ++----------------- .../Sniffs/DB/DirectDatabaseQuerySniff.php | 3 +- WordPress/Sniffs/DB/SlowDBQuerySniff.php | 2 +- WordPress/Sniffs/PHP/StrictInArraySniff.php | 2 +- .../Sniffs/Security/PluginMenuSlugSniff.php | 2 +- WordPress/Sniffs/VIP/AdminBarRemovalSniff.php | 2 +- WordPress/Sniffs/VIP/CronIntervalSniff.php | 2 +- .../Sniffs/VIP/DirectDatabaseQuerySniff.php | 5 +-- .../VIP/FileSystemWritesDisallowSniff.php | 2 +- WordPress/Sniffs/VIP/OrderByRandSniff.php | 2 +- WordPress/Sniffs/VIP/PluginMenuSlugSniff.php | 2 +- WordPress/Sniffs/VIP/PostsPerPageSniff.php | 2 +- .../Sniffs/VIP/RestrictedFunctionsSniff.php | 17 +++++--- .../Sniffs/VIP/RestrictedVariablesSniff.php | 6 +-- .../Sniffs/VIP/SessionFunctionsUsageSniff.php | 2 +- .../Sniffs/VIP/SessionVariableUsageSniff.php | 2 +- WordPress/Sniffs/VIP/SlowDBQuerySniff.php | 2 +- WordPress/Sniffs/VIP/TimezoneChangeSniff.php | 2 +- WordPress/Sniffs/WP/CronIntervalSniff.php | 2 +- WordPress/Sniffs/WP/PostsPerPageSniff.php | 2 +- WordPress/Sniffs/WP/TimezoneChangeSniff.php | 2 +- 22 files changed, 37 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 5992a758ef..4c38e4cae7 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ You can use the following as standard names when invoking `phpcs` to select snif - `WordPress-Extra` - extended ruleset for recommended best practices, not sufficiently covered in the WordPress core coding standards - includes `WordPress-Core` -**Notes:** This WPCS package contains the sniffs for another ruleset, `WordPress-VIP`. This ruleset was originally intended to aid with the [WordPress.com VIP coding requirements](https://vip.wordpress.com/documentation/code-review-what-we-look-for/), but this is no longer used or recommended by the WordPress.com VIP team or their clients, since they prefer to use their [official VIP coding standards](https://github.com/Automattic/VIP-Coding-Standards) ruleset instead. +**Notes:** This WPCS package contains the sniffs for another ruleset, `WordPress-VIP`. This ruleset was originally intended to aid with the [WordPress.com VIP coding requirements](https://vip.wordpress.com/documentation/vip-go/code-review-blockers-warnings-notices/), but this is no longer used or recommended by the WordPress.com VIP team or their clients, since they prefer to use their [official VIP coding standards](https://github.com/Automattic/VIP-Coding-Standards) ruleset instead. Before WPCS `1.0.0`, the WordPress-VIP ruleset was included as part of the complete `WordPress` ruleset. **As of `1.0.0` the `WordPress-VIP` ruleset is not part of the WordPress ruleset, and it is deprecated**. The remaining `WordPress-VIP` sniffs may still be referenced in custom rulesets, so to maintain some backwards compatibility, they will remain in WPCS until `2.0.0`. See [#1309](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/1309) for more information. diff --git a/WordPress-VIP/ruleset.xml b/WordPress-VIP/ruleset.xml index 9b30824f6e..202b3bc872 100644 --- a/WordPress-VIP/ruleset.xml +++ b/WordPress-VIP/ruleset.xml @@ -1,73 +1,50 @@ - Deprecated WordPress.com VIP Coding Standards, use the official VIP coding standards instead, these can be found at https://github.com/Automattic/VIP-Coding-Standards + Deprecated WordPress.com VIP Coding Standards. Use the official VIP coding standards instead which can be found at https://github.com/Automattic/VIP-Coding-Standards + + + ./../WordPress/PHPCSAliases.php - - - - - - - - - - error - error - error - - - - - @@ -77,11 +54,8 @@ %s() is highly discouraged, please use vip_safe_wp_remote_get() instead. - - - error @@ -92,27 +66,21 @@ Usage of a direct database call without caching is prohibited on the VIP platform. Use wp_cache_get / wp_cache_set or wp_cache_delete. - - error - error Scheduling crons at %s sec ( less than %s minutes ) is prohibited. - - - error @@ -121,7 +89,6 @@ error -