Source for file Ruleset.php
Documentation is available at Ruleset.php
* Stores the rules used to check and fix files.
* A ruleset object directly maps to a ruleset XML file.
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
namespace PHP_CodeSniffer;
use PHP_CodeSniffer\Util;
use PHP_CodeSniffer\Exceptions\RuntimeException;
* The name of the coding standard being used.
* If a top-level standard includes other standards, or sniffs
* from other standards, only the name of the top-level standard
* will be stored in here.
* If multiple top-level standards are being loaded into
* a single ruleset object, this will store a comma separated list
* of the top-level standard names.
* A list of file paths for the ruleset files being used.
* A list of regular expressions used to ignore specific sniffs for files and folders.
* Is also used to set global exclude patterns.
* The key is the regular expression and the value is the type
* of ignore pattern (absolute or relative).
* @var array<string, string>
public $ignorePatterns = array ();
* A list of regular expressions used to include specific sniffs for files and folders.
* The key is the sniff code and the value is an array with
* the key being a regular expression and the value is the type
* of ignore pattern (absolute or relative).
* @var array<string, array<string, string>>
public $includePatterns = array ();
* An array of sniff objects that are being used to check files.
* The key is the fully qualified name of the sniff class
* and the value is the sniff object.
* @var array<string, \PHP_CodeSniffer\Sniff>
public $sniffs = array ();
* A mapping of sniff codes to fully qualified class names.
* The key is the sniff code and the value
* is the fully qualified name of the sniff class.
* @var array<string, string>
public $sniffCodes = array ();
* An array of token types and the sniffs that are listening for them.
* The key is the token name being listened for and the value
* @var array<int, \PHP_CodeSniffer\Sniff>
public $tokenListeners = array ();
* An array of rules from the ruleset.xml file.
* It may be empty, indicating that the ruleset does not override
* any of the default sniff settings.
* @var array<string, mixed>
public $ruleset = array ();
* The directories that the processed rulesets are in.
protected $rulesetDirs = array ();
* The config data for the run.
* @var \PHP_CodeSniffer\Config
* Initialise the ruleset that the run will use.
* @param \PHP_CodeSniffer\Config $config The config data for the run.
public function __construct (Config $config)
// Ignore sniff restrictions if caching is on.
if ($config->cache === false ) {
$restrictions = $config->sniffs;
$exclusions = $config->exclude;
$standardPaths = array ();
foreach ($config->standards as $standard) {
$installed = Util\Standards ::getInstalledStandardPath ($standard);
if ($installed === null ) {
$standard = Util\Common ::realpath ($standard);
if (is_dir($standard) === true
&& is_file(Util\Common ::realpath ($standard.DIRECTORY_SEPARATOR. 'ruleset.xml')) === true
$standard = Util\Common ::realpath ($standard.DIRECTORY_SEPARATOR. 'ruleset.xml');
$standardPaths[] = $standard;
foreach ($standardPaths as $standard) {
if ($ruleset !== false ) {
$standardName = (string) $ruleset['name'];
if ($this->name !== '') {
$this->name .= $standardName;
$this->paths[] = $standard;
// Allow autoloading of custom files inside this standard.
if (isset ($ruleset['namespace']) === true ) {
$namespace = (string) $ruleset['namespace'];
Autoload ::addSearchPath (dirname($standard), $namespace);
if (defined('PHP_CODESNIFFER_IN_TESTS') === true && empty ($restrictions) === false ) {
// Unit tests use one standard and one sniff at a time.
$sniffs = $this->expandRulesetReference ($restrictions[0 ], dirname($standard));
} catch (RuntimeException $e) {
// Sniff reference could not be expanded, which probably means this
// is an installed standard. Let the unit test system take care of
// setting the correct sniff for testing.
if (PHP_CODESNIFFER_VERBOSITY === 1 ) {
echo " Registering sniffs in the $standardName standard... ";
if (count($config->standards ) > 1 || PHP_CODESNIFFER_VERBOSITY > 2 ) {
$sniffs = array_merge($sniffs, $this->processRuleset ($standard));
$sniffRestrictions = array ();
foreach ($restrictions as $sniffCode) {
$sniffName = $parts[0 ]. '\sniffs\\'. $parts[1 ]. '\\'. $parts[2 ]. 'sniff';
$sniffRestrictions[$sniffName] = true;
$sniffExclusions = array ();
foreach ($exclusions as $sniffCode) {
$sniffName = $parts[0 ]. '\sniffs\\'. $parts[1 ]. '\\'. $parts[2 ]. 'sniff';
$sniffExclusions[$sniffName] = true;
$this->registerSniffs ($sniffs, $sniffRestrictions, $sniffExclusions);
$this->populateTokenListeners ();
$numSniffs = count($this->sniffs);
if (PHP_CODESNIFFER_VERBOSITY === 1 ) {
echo " DONE ($numSniffs sniffs registered)".PHP_EOL;
throw new RuntimeException ('No sniffs were registered');
* Prints a report showing the sniffs contained in a standard.
public function explain ()
$sniffCount = count($sniffs);
// Add a dummy entry to the end so we loop
// one last time and clear the output buffer.
echo PHP_EOL." The $this->name standard contains $sniffCount sniffs".PHP_EOL;
foreach ($sniffs as $i => $sniff) {
if ($i === $sniffCount) {
if ($lastStandard === null ) {
$lastStandard = $currentStandard;
if ($currentStandard !== $lastStandard) {
echo PHP_EOL. $lastStandard. ' ('. $lastCount. ' sniff';
$lastStandard = $currentStandard;
if ($currentStandard === null ) {
* Processes a single ruleset and returns a list of the sniffs it represents.
* Rules founds within the ruleset are processed immediately, but sniff classes
* are not registered by this method.
* @param string $rulesetPath The path to a ruleset XML file.
* @param int $depth How many nested processing steps we are in. This
* is only used for debug output.
* @throws RuntimeException If the ruleset path is invalid.
public function processRuleset ($rulesetPath, $depth=0 )
$rulesetPath = Util\Common ::realpath ($rulesetPath);
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo 'Processing ruleset '.Util\Common ::stripBasepath ($rulesetPath, $this->config->basepath ).PHP_EOL;
if ($ruleset === false ) {
throw new RuntimeException (" Ruleset $rulesetPath is not valid" );
$includedSniffs = array ();
$excludedSniffs = array ();
$rulesetDir = dirname($rulesetPath);
$this->rulesetDirs[] = $rulesetDir;
$sniffDir = $rulesetDir.DIRECTORY_SEPARATOR. 'Sniffs';
if (is_dir($sniffDir) === true ) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\tAdding sniff files from ".Util\Common ::stripBasepath ($sniffDir, $this->config->basepath ). ' directory'.PHP_EOL;
$ownSniffs = $this->expandSniffDirectory ($sniffDir, $depth);
// Included custom autoloaders.
foreach ($ruleset->{'autoload'} as $autoload) {
if ($this->shouldProcessElement ($autoload) === false ) {
$autoloadPath = (string) $autoload;
if (is_file($autoloadPath) === false ) {
$autoloadPath = Util\Common ::realPath (dirname($rulesetPath).DIRECTORY_SEPARATOR. $autoloadPath);
if ($autoloadPath === false ) {
throw new RuntimeException ('The specified autoload file "'. $autoload. '" does not exist');
include_once $autoloadPath;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo " \t=> included autoloader $autoloadPath".PHP_EOL;
// Process custom sniff config settings.
foreach ($ruleset->{'config'} as $config) {
if ($this->shouldProcessElement ($config) === false ) {
Config ::setConfigData ((string) $config['name'], (string) $config['value'], true );
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t=> set config value ".(string) $config['name']. ': '.(string) $config['value'].PHP_EOL;
foreach ($ruleset->rule as $rule) {
if (isset ($rule['ref']) === false
|| $this->shouldProcessElement ($rule) === false
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\tProcessing rule \"". $rule['ref']. '"'.PHP_EOL;
$expandedSniffs = $this->expandRulesetReference ((string) $rule['ref'], $rulesetDir, $depth);
$newSniffs = array_diff($expandedSniffs, $includedSniffs);
$includedSniffs = array_merge($includedSniffs, $expandedSniffs);
$parts = explode('.', $rule['ref']);
if (count($parts) === 4 ) {
$sniffCode = $parts[0 ]. '.'. $parts[1 ]. '.'. $parts[2 ];
if (isset ($this->ruleset [$sniffCode]['severity']) === true
&& $this->ruleset [$sniffCode]['severity'] === 0
// This sniff code has already been turned off, but now
// it is being explicitly included again, so turn it back on.
$this->ruleset [(string) $rule['ref']]['severity'] = 5;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t* disabling sniff exclusion for specific message code *".PHP_EOL;
echo "\t\t=> severity set to 5".PHP_EOL;
} else if (empty ($newSniffs) === false ) {
$newSniff = $newSniffs[0 ];
if (in_array($newSniff, $ownSniffs) === false ) {
// Including a sniff that hasn't been included higher up, but
// only including a single message from it. So turn off all messages in
// the sniff, except this one.
$this->ruleset [$sniffCode]['severity'] = 0;
$this->ruleset [(string) $rule['ref']]['severity'] = 5;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\tExcluding sniff \"". $sniffCode. '" except for "'. $parts[3 ]. '"'.PHP_EOL;
if (isset ($rule->exclude ) === true ) {
foreach ($rule->exclude as $exclude) {
if (isset ($exclude['name']) === false ) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t* ignoring empty exclude rule *".PHP_EOL;
echo "\t\t\t=> ". $exclude->asXML ().PHP_EOL;
if ($this->shouldProcessElement ($exclude) === false ) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\tExcluding rule \"". $exclude['name']. '"'.PHP_EOL;
// Check if a single code is being excluded, which is a shortcut
// for setting the severity of the message to 0.
$parts = explode('.', $exclude['name']);
if (count($parts) === 4 ) {
$this->ruleset [(string) $exclude['name']]['severity'] = 0;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> severity set to 0".PHP_EOL;
$this->expandRulesetReference ($exclude['name'], $rulesetDir, ($depth + 1 ))
$this->processRule ($rule, $newSniffs, $depth);
// Process custom command line arguments.
foreach ($ruleset->{'arg'} as $arg) {
if ($this->shouldProcessElement ($arg) === false ) {
if (isset ($arg['name']) === true ) {
$argString = '--'.(string) $arg['name'];
if (isset ($arg['value']) === true ) {
$argString .= '='.(string) $arg['value'];
$argString = '-'.(string) $arg['value'];
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo " \t=> set command line value $argString".PHP_EOL;
// Set custom php ini values as CLI args.
foreach ($ruleset->{'ini'} as $arg) {
if ($this->shouldProcessElement ($arg) === false ) {
if (isset ($arg['name']) === false ) {
$name = (string) $arg['name'];
if (isset ($arg['value']) === true ) {
$value = (string) $arg['value'];
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo " \t=> set PHP ini value $name to $value".PHP_EOL;
if (empty ($this->config ->files ) === true ) {
// Process hard-coded file paths.
foreach ($ruleset->{'file'} as $file) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo " \t=> added \"$file\" to the file list".PHP_EOL;
if (empty ($cliArgs) === false ) {
// Change the directory so all relative paths are worked
// out based on the location of the ruleset instead of
// the location of the user.
$inPhar = Util\Common ::isPharFile ($rulesetDir);
$this->config ->setCommandLineValues ($cliArgs);
// Process custom ignore pattern rules.
foreach ($ruleset->{'exclude-pattern'} as $pattern) {
if ($this->shouldProcessElement ($pattern) === false ) {
if (isset ($pattern['type']) === false ) {
$pattern['type'] = 'absolute';
$this->ignorePatterns [(string) $pattern] = (string) $pattern['type'];
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t=> added global ".(string) $pattern['type']. ' ignore pattern: '.(string) $pattern.PHP_EOL;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
$included = count($includedSniffs);
$excluded = count($excludedSniffs);
echo " => Ruleset processing complete; included $included sniffs and excluded $excluded".PHP_EOL;
// Merge our own sniff list with our externally included
// sniff list, but filter out any excluded sniffs.
foreach ($includedSniffs as $sniff) {
if (in_array($sniff, $excludedSniffs) === true ) {
$files[] = Util\Common ::realpath ($sniff);
* Expands a directory into a list of sniff files within.
* @param string $directory The path to a directory.
* @param int $depth How many nested processing steps we are in. This
* is only used for debug output.
private function expandSniffDirectory ($directory, $depth=0 )
$rdi = new \RecursiveDirectoryIterator ($directory, \RecursiveDirectoryIterator ::FOLLOW_SYMLINKS );
$di = new \RecursiveIteratorIterator ($rdi, 0 , \RecursiveIteratorIterator ::CATCH_GET_CHILD );
$filename = $file->getFilename ();
if (substr($filename, 0 , 1 ) === '.') {
// We are only interested in PHP and sniff files.
$fileParts = explode('.', $filename);
$basename = basename($filename, '.php');
if (substr($basename, -5 ) !== 'Sniff') {
$path = $file->getPathname ();
// Skip files in hidden directories within the Sniffs directory of this
// standard. We use the offset with strpos() to allow hidden directories
// before, valid example:
// /home/foo/.composer/vendor/squiz/custom_tool/MyStandard/Sniffs/...
if (strpos($path, DIRECTORY_SEPARATOR. '.', $dirLen) !== false ) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> ".Util\Common ::stripBasepath ($path, $this->config ->basepath ).PHP_EOL;
}//end expandSniffDirectory()
* Expands a ruleset reference into a list of sniff files.
* @param string $ref The reference from the ruleset XML file.
* @param string $rulesetDir The directory of the ruleset XML file, used to
* evaluate relative paths.
* @param int $depth How many nested processing steps we are in. This
* is only used for debug output.
* @throws RuntimeException If the reference is invalid.
private function expandRulesetReference ($ref, $rulesetDir, $depth=0 )
// Ignore internal sniffs codes as they are used to only
// hide and change internal messages.
if (substr($ref, 0 , 9 ) === 'Internal.') {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t* ignoring internal sniff code *".PHP_EOL;
// As sniffs can't begin with a full stop, assume references in
// this format are relative paths and attempt to convert them
// to absolute paths. If this fails, let the reference run through
// the normal checks and have it fail as normal.
if (substr($ref, 0 , 1 ) === '.') {
$realpath = Util\Common ::realpath ($rulesetDir. '/'. $ref);
if ($realpath !== false ) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> ".Util\Common ::stripBasepath ($ref, $this->config ->basepath ).PHP_EOL;
// As sniffs can't begin with a tilde, assume references in
// this format are relative to the user's home directory.
if (substr($ref, 0 , 2 ) === '~/') {
$realpath = Util\Common ::realpath ($ref);
if ($realpath !== false ) {
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> ".Util\Common ::stripBasepath ($ref, $this->config ->basepath ).PHP_EOL;
if (substr($ref, -9 ) === 'Sniff.php') {
// A single external sniff.
// See if this is a whole standard being referenced.
$path = Util\Standards ::getInstalledStandardPath ($ref);
if (Util\Common ::isPharFile ($path) === true && strpos($path, 'ruleset.xml') === false ) {
// If the ruleset exists inside the phar file, use it.
if (file_exists($path.DIRECTORY_SEPARATOR. 'ruleset.xml') === true ) {
$path = $path.DIRECTORY_SEPARATOR. 'ruleset.xml';
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> ".Util\Common ::stripBasepath ($ref, $this->config ->basepath ).PHP_EOL;
} else if (is_dir($ref) === false ) {
// Work out the sniff path.
$sepPos = strpos($ref, DIRECTORY_SEPARATOR );
$stdName = substr($ref, 0 , $sepPos);
$path = substr($ref, $sepPos);
if (count($parts) === 1 ) {
} else if (count($parts) === 2 ) {
// A directory of sniffs?
$path = DIRECTORY_SEPARATOR. 'Sniffs'.DIRECTORY_SEPARATOR. $parts[1 ];
$path = DIRECTORY_SEPARATOR. 'Sniffs'.DIRECTORY_SEPARATOR. $parts[1 ].DIRECTORY_SEPARATOR. $parts[2 ]. 'Sniff.php';
$stdPath = Util\Standards ::getInstalledStandardPath ($stdName);
if ($stdPath !== null && $path !== '') {
if (Util\Common ::isPharFile ($stdPath) === true
&& strpos($stdPath, 'ruleset.xml') === false
// Phar files can only return the directory,
// since ruleset can be omitted if building one standard.
$newRef = Util\Common ::realpath ($stdPath. $path);
$newRef = Util\Common ::realpath (dirname($stdPath). $path);
// The sniff is not locally installed, so check if it is being
// referenced as a remote sniff outside the install. We do this
// by looking through all directories where we have found ruleset
// files before, looking for ones for this particular standard,
// and seeing if it is in there.
foreach ($this->rulesetDirs as $dir) {
$newRef = Util\Common ::realpath ($dir. $path);
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> ".Util\Common ::stripBasepath ($ref, $this->config ->basepath ).PHP_EOL;
if (is_file($ref.DIRECTORY_SEPARATOR. 'ruleset.xml') === true ) {
// We are referencing an external coding standard.
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t* rule is referencing a standard using directory name; processing *".PHP_EOL;
return $this->processRuleset ($ref.DIRECTORY_SEPARATOR. 'ruleset.xml', ($depth + 2 ));
// We are referencing a whole directory of sniffs.
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t* rule is referencing a directory of sniffs *".PHP_EOL;
echo "\t\tAdding sniff files from directory".PHP_EOL;
return $this->expandSniffDirectory ($ref, ($depth + 1 ));
$error = " Referenced sniff \"$ref\" does not exist";
throw new RuntimeException ($error);
if (substr($ref, -9 ) === 'Sniff.php') {
// Assume an external ruleset.xml file.
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t* rule is referencing a standard using ruleset path; processing *".PHP_EOL;
return $this->processRuleset ($ref, ($depth + 2 ));
}//end expandRulesetReference()
* Processes a rule from a ruleset XML file, overriding built-in defaults.
* @param SimpleXMLElement $rule The rule object from a ruleset XML file.
* @param string[] $newSniffs An array of sniffs that got included by this rule.
* @param int $depth How many nested processing steps we are in.
* This is only used for debug output.
* @throws RuntimeException If rule settings are invalid.
private function processRule ($rule, $newSniffs, $depth=0 )
$ref = (string) $rule['ref'];
if (count($parts) <= 2 ) {
// We are processing a standard or a category of sniffs.
foreach ($newSniffs as $sniffFile) {
$parts = explode(DIRECTORY_SEPARATOR , $sniffFile);
$todo[] = $sniffStandard. '.'. $sniffCategory. '.'. substr($sniffName, 0 , -9 );
foreach ($todo as $code) {
if (isset ($rule->severity ) === true
&& $this->shouldProcessElement ($rule->severity ) === true
if (isset ($this->ruleset [$code]) === false ) {
$this->ruleset [$code] = array ();
$this->ruleset [$code]['severity'] = (int) $rule->severity;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> severity set to ".(int) $rule->severity;
if (isset ($rule->type ) === true
&& $this->shouldProcessElement ($rule->type ) === true
if (isset ($this->ruleset [$code]) === false ) {
$this->ruleset [$code] = array ();
if ($type !== 'error' && $type !== 'warning') {
throw new RuntimeException (" Message type \"$type\" is invalid; must be \"error\" or \"warning\"" );
$this->ruleset [$code]['type'] = $type;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> message type set to ".(string) $rule->type;
if (isset ($rule->message ) === true
&& $this->shouldProcessElement ($rule->message ) === true
if (isset ($this->ruleset [$code]) === false ) {
$this->ruleset [$code] = array ();
$this->ruleset [$code]['message'] = (string) $rule->message;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> message set to ".(string) $rule->message;
if (isset ($rule->properties ) === true
&& $this->shouldProcessElement ($rule->properties ) === true
foreach ($rule->properties ->property as $prop) {
if ($this->shouldProcessElement ($prop) === false ) {
if (isset ($this->ruleset [$code]) === false ) {
$this->ruleset [$code] = array (
} else if (isset ($this->ruleset [$code]['properties']) === false ) {
$this->ruleset [$code]['properties'] = array ();
$name = (string) $prop['name'];
if (isset ($prop['type']) === true
&& (string) $prop['type'] === 'array'
$value = (string) $prop['value'];
foreach (explode(',', $value) as $val) {
list ($k,$v) = explode('=>', $val. '=>');
$this->ruleset [$code]['properties'][$name] = $values;
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo " \t\t=> array property \"$name\" set to \"$value\"";
$this->ruleset [$code]['properties'][$name] = (string) $prop['value'];
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo " \t\t=> property \"$name\" set to \"".(string) $prop['value']. '"';
foreach ($rule->{'exclude-pattern'} as $pattern) {
if ($this->shouldProcessElement ($pattern) === false ) {
if (isset ($this->ignorePatterns [$code]) === false ) {
$this->ignorePatterns [$code] = array ();
if (isset ($pattern['type']) === false ) {
$pattern['type'] = 'absolute';
$this->ignorePatterns [$code][(string) $pattern] = (string) $pattern['type'];
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> added rule-specific ".(string) $pattern['type']. ' ignore pattern';
echo ': '.(string) $pattern.PHP_EOL;
foreach ($rule->{'include-pattern'} as $pattern) {
if ($this->shouldProcessElement ($pattern) === false ) {
if (isset ($this->includePatterns [$code]) === false ) {
$this->includePatterns [$code] = array ();
if (isset ($pattern['type']) === false ) {
$pattern['type'] = 'absolute';
$this->includePatterns [$code][(string) $pattern] = (string) $pattern['type'];
if (PHP_CODESNIFFER_VERBOSITY > 1 ) {
echo "\t\t=> added rule-specific ".(string) $pattern['type']. ' include pattern';
echo ': '.(string) $pattern.PHP_EOL;
* Determine if an element should be processed or ignored.
* @param SimpleXMLElement $element An object from a ruleset XML file.
private function shouldProcessElement ($element)
if (isset ($element['phpcbf-only']) === false
&& isset ($element['phpcs-only']) === false
// No exceptions are being made.
if (PHP_CODESNIFFER_CBF === true
&& isset ($element['phpcbf-only']) === true
&& (string) $element['phpcbf-only'] === 'true'
if (PHP_CODESNIFFER_CBF === false
&& isset ($element['phpcs-only']) === true
&& (string) $element['phpcs-only'] === 'true'
}//end shouldProcessElement()
* Loads and stores sniffs objects used for sniffing files.
* @param array $files Paths to the sniff files to register.
* @param array $restrictions The sniff class names to restrict the allowed
* @param array $exclusions The sniff class names to exclude from the
public function registerSniffs ($files, $restrictions, $exclusions)
foreach ($files as $file) {
// Work out where the position of /StandardName/Sniffs/... is
// so we can determine what the class will be called.
$sniffPos = strrpos($file, DIRECTORY_SEPARATOR. 'Sniffs'.DIRECTORY_SEPARATOR );
if ($sniffPos === false ) {
$slashPos = strrpos(substr($file, 0 , $sniffPos), DIRECTORY_SEPARATOR );
if ($slashPos === false ) {
$className = Autoload ::loadFile ($file);
$compareName = Util\Common ::cleanSniffClass ($className);
// If they have specified a list of sniffs to restrict to, check
// to see if this sniff is allowed.
if (empty ($restrictions) === false
&& isset ($restrictions[$compareName]) === false
// If they have specified a list of sniffs to exclude, check
// to see if this sniff is allowed.
if (empty ($exclusions) === false
&& isset ($exclusions[$compareName]) === true
// Skip abstract classes.
$reflection = new \ReflectionClass ($className);
if ($reflection->isAbstract () === true ) {
$listeners[$className] = $className;
if (PHP_CODESNIFFER_VERBOSITY > 2 ) {
echo " Registered $className".PHP_EOL;
$this->sniffs = $listeners;
* Populates the array of PHP_CodeSniffer_Sniff's for this file.
* @throws RuntimeException If sniff registration fails.
public function populateTokenListeners ()
// Construct a list of listeners indexed by token being listened for.
$this->tokenListeners = array ();
foreach ($this->sniffs as $sniffClass => $sniffObject) {
$this->sniffs [$sniffClass] = null;
$this->sniffs [$sniffClass] = new $sniffClass();
$sniffCode = Util\Common ::getSniffCode ($sniffClass);
$this->sniffCodes [$sniffCode] = $sniffClass;
// Set custom properties.
if (isset ($this->ruleset [$sniffCode]['properties']) === true ) {
foreach ($this->ruleset [$sniffCode]['properties'] as $name => $value) {
$this->setSniffProperty ($sniffClass, $name, $value);
if (isset ($vars['supportedTokenizers']) === true ) {
foreach ($vars['supportedTokenizers'] as $tokenizer) {
$tokenizers[$tokenizer] = $tokenizer;
$tokenizers = array ('PHP' => 'PHP');
$tokens = $this->sniffs [$sniffClass]->register ();
$msg = " Sniff $sniffClass register() method must return an array";
throw new RuntimeException ($msg);
$ignorePatterns = array ();
$patterns = $this->getIgnorePatterns ($sniffCode);
foreach ($patterns as $pattern => $type) {
$ignorePatterns[] = strtr($pattern, $replacements);
$includePatterns = array ();
$patterns = $this->getIncludePatterns ($sniffCode);
foreach ($patterns as $pattern => $type) {
$includePatterns[] = strtr($pattern, $replacements);
foreach ($tokens as $token) {
if (isset ($this->tokenListeners [$token]) === false ) {
$this->tokenListeners [$token] = array ();
if (isset ($this->tokenListeners [$token][$sniffClass]) === false ) {
$this->tokenListeners [$token][$sniffClass] = array (
'tokenizers' => $tokenizers,
'ignore' => $ignorePatterns,
'include' => $includePatterns,
}//end populateTokenListeners()
* Set a single property for a sniff.
* @param string $sniffClass The class name of the sniff.
* @param string $name The name of the property to change.
* @param string $value The new value of the property.
public function setSniffProperty ($sniffClass, $name, $value)
// Setting a property for a sniff we are not using.
if (isset ($this->sniffs [$sniffClass]) === false ) {
// Special case for booleans.
} else if ($value === 'false') {
$this->sniffs [$sniffClass]->$name = $value;
}//end setSniffProperty()
* Gets the array of ignore patterns.
* Optionally takes a listener to get ignore patterns specified
* @param string $listener The listener to get patterns for. If NULL, all
public function getIgnorePatterns ($listener=null )
if ($listener === null ) {
return $this->ignorePatterns;
if (isset ($this->ignorePatterns [$listener]) === true ) {
return $this->ignorePatterns [$listener];
}//end getIgnorePatterns()
* Gets the array of include patterns.
* Optionally takes a listener to get include patterns specified
* @param string $listener The listener to get patterns for. If NULL, all
public function getIncludePatterns ($listener=null )
if ($listener === null ) {
return $this->includePatterns;
if (isset ($this->includePatterns [$listener]) === true ) {
return $this->includePatterns [$listener];
}//end getIncludePatterns()
Documentation generated on Mon, 11 Mar 2019 15:27:43 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|