Skip to content

Commit

Permalink
Copy in the PregReplaceEModifierSniff from the PHPCompatibility Sniff…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
jrfnl committed Jul 16, 2016
1 parent 1ba41c9 commit 3781c68
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 0 deletions.
4 changes: 4 additions & 0 deletions WordPress-Core/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,9 @@
<rule ref="WordPress.WP.I18n"/>

<rule ref="WordPress.PHP.POSIXFunctions" />
<rule ref="WordPress.PHPCompatibility.PregReplaceEModifier">
<message>Never use preg_replace() with the /e switch, use preg_replace_callback instead.</message>
<type>error</type>
</rule>

</ruleset>
108 changes: 108 additions & 0 deletions WordPress/Sniffs/PHPCompatibility/PregReplaceEModifierSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php
/**
* PHPCompatibility_Sniffs_PHP_PregReplaceEModifierSniff.
*
* PHP version 5.6
*
* @category PHP
* @package PHPCompatibility
* @author Wim Godden <[email protected]>
* @copyright 2014 Cu.be Solutions bvba
*/

/**
* PHPCompatibility_Sniffs_PHP_PregReplaceEModifierSniff.
*
* @category PHP
* @package PHPCompatibility
* @author Wim Godden <[email protected]>
* @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
24 changes: 24 additions & 0 deletions WordPress/Sniffs/PHPCompatibility/README.md
Original file line number Diff line number Diff line change
@@ -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
106 changes: 106 additions & 0 deletions WordPress/Sniffs/PHPCompatibility/Sniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php
/**
* PHPCompatibility_Sniff.
*
* PHP version 5.6
*
* @category PHP
* @package PHPCompatibility
* @author Wim Godden <[email protected]>
* @copyright 2014 Cu.be Solutions bvba
*/

/**
* PHPCompatibility_Sniff.
*
* @category PHP
* @package PHPCompatibility
* @author Wim Godden <[email protected]>
* @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
2 changes: 2 additions & 0 deletions bin/phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<ruleset name="WordPress Coding Standards">
<description>The Coding standard for the WordPress Coding Standards itself.</description>

<exclude-pattern>*/Sniffs/PHPCompatibility/*</exclude-pattern>

<rule ref="WordPress-Core">
<exclude name="Generic.Files.LowercasedFilename" />
<exclude name="WordPress.NamingConventions.ValidVariableName" />
Expand Down

0 comments on commit 3781c68

Please sign in to comment.