From 3781c68c54686422d02866a2f05c8b49ae884073 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 16 Jul 2016 23:00:17 +0200 Subject: [PATCH] Copy in the PregReplaceEModifierSniff from the PHPCompatibility Sniff library. * Copy in the PregReplaceEModifierSniff. * Copy in the related parent class PHPCompatibility_Sniff. * Renamed both class to follow the PSR1 autoloading pattern. * Added a readme to the PHPCompatibility sniff folder about its usage. * Excluded the PHPCompatibility folder from the PHPCS code style checks - this way we can just drop-in replace the file (ok, except for the class renaming) when there is a new version available. --- WordPress-Core/ruleset.xml | 4 + .../PregReplaceEModifierSniff.php | 108 ++++++++++++++++++ WordPress/Sniffs/PHPCompatibility/README.md | 24 ++++ WordPress/Sniffs/PHPCompatibility/Sniff.php | 106 +++++++++++++++++ bin/phpcs.xml | 2 + 5 files changed, 244 insertions(+) create mode 100644 WordPress/Sniffs/PHPCompatibility/PregReplaceEModifierSniff.php create mode 100644 WordPress/Sniffs/PHPCompatibility/README.md create mode 100644 WordPress/Sniffs/PHPCompatibility/Sniff.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index e30f8b59bf..81117f9be8 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -113,5 +113,9 @@ + + Never use preg_replace() with the /e switch, use preg_replace_callback instead. + error + diff --git a/WordPress/Sniffs/PHPCompatibility/PregReplaceEModifierSniff.php b/WordPress/Sniffs/PHPCompatibility/PregReplaceEModifierSniff.php new file mode 100644 index 0000000000..e3f93aacf3 --- /dev/null +++ b/WordPress/Sniffs/PHPCompatibility/PregReplaceEModifierSniff.php @@ -0,0 +1,108 @@ + + * @copyright 2014 Cu.be Solutions bvba + */ + +/** + * PHPCompatibility_Sniffs_PHP_PregReplaceEModifierSniff. + * + * @category PHP + * @package PHPCompatibility + * @author Wim Godden + * @version 1.1.0 + * @copyright 2014 Cu.be Solutions bvba + */ +class WordPress_Sniffs_PHPCompatibility_PregReplaceEModifierSniff extends WordPress_Sniffs_PHPCompatibility_Sniff +{ + + /** + * If true, an error will be thrown; otherwise a warning. + * + * @var bool + */ + public $error = false; + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array(T_STRING); + }//end register() + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + if ($this->supportsAbove('5.5')) { + $tokens = $phpcsFile->getTokens(); + + if ($tokens[$stackPtr]['content'] == "preg_replace") { + $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true); + + if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) { + return; + } + + $firstParam = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($openBracket + 1), null, true); + + /** + * If argument is not a string, then skip test (e.g. if variable passed in). + */ + if ($tokens[$firstParam]['code'] !== T_CONSTANT_ENCAPSED_STRING) { + return; + } + + /** + * Regex is a T_CONSTANT_ENCAPSED_STRING, so we need to remove the quotes + */ + $regex = ""; + while (isset($tokens[$firstParam]) && $tokens[$firstParam]['code'] != T_COMMA) { + if ($tokens[$firstParam]['code'] == T_CONSTANT_ENCAPSED_STRING) { + $regex .= $tokens[$firstParam]['content']; + } + $firstParam++; + } + + $doublesSeparators = array( + '{' => '}', + ); + + $regex = substr($regex, 1, -1); + + $regexFirstChar = substr($regex, 0, 1); + $regexEndPos = (array_key_exists($regexFirstChar, $doublesSeparators)) ? + strrpos($regex, $doublesSeparators[$regexFirstChar]) + : strrpos($regex, $regexFirstChar); + + if($regexEndPos) { + $modifiers = substr($regex, $regexEndPos + 1); + + if (strpos($modifiers, "e") !== false) { + $error = 'preg_replace() - /e modifier is deprecated in PHP 5.5'; + $phpcsFile->addError($error, $stackPtr); + } + } + } + } + + + }//end process() + +}//end class diff --git a/WordPress/Sniffs/PHPCompatibility/README.md b/WordPress/Sniffs/PHPCompatibility/README.md new file mode 100644 index 0000000000..89aad9255f --- /dev/null +++ b/WordPress/Sniffs/PHPCompatibility/README.md @@ -0,0 +1,24 @@ +### Important note about the PHPCompatibility Sniffs folder + +The sniffs in this folder come from another sniff library called [PHPCompatibility]. +Only sniffs which are one-on-one copies from sniffs in that library should be added here. + +To make copied in sniffs from [PHPCompatibility] work within the WordPress Coding Standards library, you need to make the following change: +```php +// Change the class line from: +class PHPCompatibility_Sniffs_PHP_SniffNameSniff extends PHPCompatibility_Sniff + +// to: +class WordPress_Sniffs_PHPCompatibility_SniffNameSniff extends WordPress_Sniffs_PHPCompatibility_Sniff +``` + + +**_If these sniffs are adjusted - other than as outline above -, they should not be placed in this folder._** + + +* Sniffs in this folder are excluded from the WPCS code style check to allow for copy/paste syncing of the files. +* Sniffs in this folder generally do not have unit tests as they are unit tested in the sister-sniff-library [PHPCompatibility]. +* Any issues with these sniffs should be [reported](https://github.com/wimg/PHPCompatibility/issues/new) and solved in the sister-sniff-library [PHPCompatibility], not in WPCS. + + +[PHPCompatibility]: https://github.com/wimg/PHPCompatibility \ No newline at end of file diff --git a/WordPress/Sniffs/PHPCompatibility/Sniff.php b/WordPress/Sniffs/PHPCompatibility/Sniff.php new file mode 100644 index 0000000000..4e2d785671 --- /dev/null +++ b/WordPress/Sniffs/PHPCompatibility/Sniff.php @@ -0,0 +1,106 @@ + + * @copyright 2014 Cu.be Solutions bvba + */ + +/** + * PHPCompatibility_Sniff. + * + * @category PHP + * @package PHPCompatibility + * @author Wim Godden + * @version 1.1.0 + * @copyright 2014 Cu.be Solutions bvba + */ +abstract class WordPress_Sniffs_PHPCompatibility_Sniff implements PHP_CodeSniffer_Sniff +{ + +/* The testVersion configuration variable may be in any of the following formats: + * 1) Omitted/empty, in which case no version is specified. This effectively + * disables all the checks provided by this standard. + * 2) A single PHP version number, e.g. "5.4" in which case the standard checks that + * the code will run on that version of PHP (no deprecated features or newer + * features being used). + * 3) A range, e.g. "5.0-5.5", in which case the standard checks the code will run + * on all PHP versions in that range, and that it doesn't use any features that + * were deprecated by the final version in the list, or which were not available + * for the first version in the list. + * PHP version numbers should always be in Major.Minor format. Both "5", "5.3.2" + * would be treated as invalid, and ignored. + * This standard doesn't support checking against PHP4, so the minimum version that + * is recognised is "5.0". + */ + + private function getTestVersion() + { + /** + * var $testVersion will hold an array containing min/max version of PHP + * that we are checking against (see above). If only a single version + * number is specified, then this is used as both the min and max. + */ + static $arrTestVersions; + + if (!isset($testVersion)) { + $testVersion = PHP_CodeSniffer::getConfigData('testVersion'); + $testVersion = trim($testVersion); + + $arrTestVersions = array(null, null); + if (preg_match('/^\d+\.\d+$/', $testVersion)) { + $arrTestVersions = array($testVersion, $testVersion); + } + elseif (preg_match('/^(\d+\.\d+)\s*-\s*(\d+\.\d+)$/', $testVersion, + $matches)) + { + if (version_compare($matches[1], $matches[2], ">")) { + trigger_error("Invalid range in testVersion setting: '" + . $testVersion . "'", E_USER_WARNING); + } + else { + $arrTestVersions = array($matches[1], $matches[2]); + } + } + elseif (!$testVersion == "") { + trigger_error("Invalid testVersion setting: '" . $testVersion + . "'", E_USER_WARNING); + } + } + + return $arrTestVersions; + } + + public function supportsAbove($phpVersion) + { + $testVersion = $this->getTestVersion(); + $testVersion = $testVersion[1]; + + if (is_null($testVersion) + || version_compare($testVersion, $phpVersion) >= 0 + ) { + return true; + } else { + return false; + } + }//end supportsAbove() + + public function supportsBelow($phpVersion) + { + $testVersion = $this->getTestVersion(); + $testVersion = $testVersion[0]; + + if (!is_null($testVersion) + && version_compare($testVersion, $phpVersion) <= 0 + ) { + return true; + } else { + return false; + } + }//end supportsBelow() + +}//end class diff --git a/bin/phpcs.xml b/bin/phpcs.xml index aa8ec9d7fc..efe80acdd5 100644 --- a/bin/phpcs.xml +++ b/bin/phpcs.xml @@ -2,6 +2,8 @@ The Coding standard for the WordPress Coding Standards itself. + */Sniffs/PHPCompatibility/* +