PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file Ruleset.php

Documentation is available at Ruleset.php

  1. <?php
  2. /**
  3.  * Stores the rules used to check and fix files.
  4.  *
  5.  * A ruleset object directly maps to a ruleset XML file.
  6.  *
  7.  * @author    Greg Sherwood <gsherwood@squiz.net>
  8.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  9.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  10.  */
  11.  
  12. namespace PHP_CodeSniffer;
  13.  
  14. use PHP_CodeSniffer\Util;
  15. use PHP_CodeSniffer\Exceptions\RuntimeException;
  16.  
  17. class Ruleset
  18. {
  19.  
  20.     /**
  21.      * The name of the coding standard being used.
  22.      *
  23.      * If a top-level standard includes other standards, or sniffs
  24.      * from other standards, only the name of the top-level standard
  25.      * will be stored in here.
  26.      *
  27.      * If multiple top-level standards are being loaded into
  28.      * a single ruleset object, this will store a comma separated list
  29.      * of the top-level standard names.
  30.      *
  31.      * @var string 
  32.      */
  33.     public $name '';
  34.  
  35.     /**
  36.      * A list of file paths for the ruleset files being used.
  37.      *
  38.      * @var string[] 
  39.      */
  40.     public $paths = array();
  41.  
  42.     /**
  43.      * A list of regular expressions used to ignore specific sniffs for files and folders.
  44.      *
  45.      * Is also used to set global exclude patterns.
  46.      * The key is the regular expression and the value is the type
  47.      * of ignore pattern (absolute or relative).
  48.      *
  49.      * @var array<string, string>
  50.      */
  51.     public $ignorePatterns = array();
  52.  
  53.     /**
  54.      * A list of regular expressions used to include specific sniffs for files and folders.
  55.      *
  56.      * The key is the sniff code and the value is an array with
  57.      * the key being a regular expression and the value is the type
  58.      * of ignore pattern (absolute or relative).
  59.      *
  60.      * @var array<string, array<string, string>>
  61.      */
  62.     public $includePatterns = array();
  63.  
  64.     /**
  65.      * An array of sniff objects that are being used to check files.
  66.      *
  67.      * The key is the fully qualified name of the sniff class
  68.      * and the value is the sniff object.
  69.      *
  70.      * @var array<string, \PHP_CodeSniffer\Sniff>
  71.      */
  72.     public $sniffs = array();
  73.  
  74.     /**
  75.      * A mapping of sniff codes to fully qualified class names.
  76.      *
  77.      * The key is the sniff code and the value
  78.      * is the fully qualified name of the sniff class.
  79.      *
  80.      * @var array<string, string>
  81.      */
  82.     public $sniffCodes = array();
  83.  
  84.     /**
  85.      * An array of token types and the sniffs that are listening for them.
  86.      *
  87.      * The key is the token name being listened for and the value
  88.      * is the sniff object.
  89.      *
  90.      * @var array<int, \PHP_CodeSniffer\Sniff>
  91.      */
  92.     public $tokenListeners = array();
  93.  
  94.     /**
  95.      * An array of rules from the ruleset.xml file.
  96.      *
  97.      * It may be empty, indicating that the ruleset does not override
  98.      * any of the default sniff settings.
  99.      *
  100.      * @var array<string, mixed>
  101.      */
  102.     public $ruleset = array();
  103.  
  104.     /**
  105.      * The directories that the processed rulesets are in.
  106.      *
  107.      * @var string[] 
  108.      */
  109.     protected $rulesetDirs = array();
  110.  
  111.     /**
  112.      * The config data for the run.
  113.      *
  114.      * @var \PHP_CodeSniffer\Config 
  115.      */
  116.     private $config = null;
  117.  
  118.  
  119.     /**
  120.      * Initialise the ruleset that the run will use.
  121.      *
  122.      * @param \PHP_CodeSniffer\Config $config The config data for the run.
  123.      *
  124.      * @return void 
  125.      */
  126.     public function __construct(Config $config)
  127.     {
  128.         // Ignore sniff restrictions if caching is on.
  129.         $restrictions = array();
  130.         $exclusions   = array();
  131.         if ($config->cache === false{
  132.             $restrictions $config->sniffs;
  133.             $exclusions   $config->exclude;
  134.         }
  135.  
  136.         $this->config $config;
  137.         $sniffs       = array();
  138.  
  139.         $standardPaths = array();
  140.         foreach ($config->standards as $standard{
  141.             $installed = Util\Standards::getInstalledStandardPath($standard);
  142.             if ($installed === null{
  143.                 $standard = Util\Common::realpath($standard);
  144.                 if (is_dir($standard=== true
  145.                     && is_file(Util\Common::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml')) === true
  146.                 {
  147.                     $standard = Util\Common::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml');
  148.                 }
  149.             else {
  150.                 $standard $installed;
  151.             }
  152.  
  153.             $standardPaths[$standard;
  154.         }
  155.  
  156.         foreach ($standardPaths as $standard{
  157.             $ruleset @simplexml_load_string(file_get_contents($standard));
  158.             if ($ruleset !== false{
  159.                 $standardName = (string) $ruleset['name'];
  160.                 if ($this->name !== ''{
  161.                     $this->name .= ', ';
  162.                 }
  163.  
  164.                 $this->name   .= $standardName;
  165.                 $this->paths[$standard;
  166.  
  167.                 // Allow autoloading of custom files inside this standard.
  168.                 if (isset($ruleset['namespace']=== true{
  169.                     $namespace = (string) $ruleset['namespace'];
  170.                 else {
  171.                     $namespace basename(dirname($standard));
  172.                 }
  173.  
  174.                 Autoload::addSearchPath(dirname($standard)$namespace);
  175.             }
  176.  
  177.             if (defined('PHP_CODESNIFFER_IN_TESTS'=== true && empty($restrictions=== false{
  178.                 // Unit tests use one standard and one sniff at a time.
  179.                 try {
  180.                     $sniffs $this->expandRulesetReference($restrictions[0]dirname($standard));
  181.                 catch (RuntimeException $e{
  182.                     // Sniff reference could not be expanded, which probably means this
  183.                     // is an installed standard. Let the unit test system take care of
  184.                     // setting the correct sniff for testing.
  185.                     return;
  186.                 }
  187.  
  188.                 break;
  189.             }
  190.  
  191.             if (PHP_CODESNIFFER_VERBOSITY === 1{
  192.                 echo "Registering sniffs in the $standardName standard... ";
  193.                 if (count($config->standards> 1 || PHP_CODESNIFFER_VERBOSITY > 2{
  194.                     echo PHP_EOL;
  195.                 }
  196.             }
  197.  
  198.             $sniffs array_merge($sniffs$this->processRuleset($standard));
  199.         }//end foreach
  200.  
  201.         $sniffRestrictions = array();
  202.         foreach ($restrictions as $sniffCode{
  203.             $parts     explode('.'strtolower($sniffCode));
  204.             $sniffName $parts[0].'\sniffs\\'.$parts[1].'\\'.$parts[2].'sniff';
  205.             $sniffRestrictions[$sniffName= true;
  206.         }
  207.  
  208.         $sniffExclusions = array();
  209.         foreach ($exclusions as $sniffCode{
  210.             $parts     explode('.'strtolower($sniffCode));
  211.             $sniffName $parts[0].'\sniffs\\'.$parts[1].'\\'.$parts[2].'sniff';
  212.             $sniffExclusions[$sniffName= true;
  213.         }
  214.  
  215.         $this->registerSniffs($sniffs$sniffRestrictions$sniffExclusions);
  216.         $this->populateTokenListeners();
  217.  
  218.         $numSniffs count($this->sniffs);
  219.         if (PHP_CODESNIFFER_VERBOSITY === 1{
  220.             echo "DONE ($numSniffs sniffs registered)".PHP_EOL;
  221.         }
  222.  
  223.         if ($numSniffs === 0{
  224.             throw new RuntimeException('No sniffs were registered');
  225.         }
  226.  
  227.     }//end __construct()
  228.  
  229.  
  230.     /**
  231.      * Prints a report showing the sniffs contained in a standard.
  232.      *
  233.      * @return void 
  234.      */
  235.     public function explain()
  236.     {
  237.         $sniffs array_keys($this->sniffCodes);
  238.         sort($sniffs);
  239.  
  240.         ob_start();
  241.  
  242.         $lastStandard = null;
  243.         $lastCount    '';
  244.         $sniffCount   count($sniffs);
  245.  
  246.         // Add a dummy entry to the end so we loop
  247.         // one last time and clear the output buffer.
  248.         $sniffs['';
  249.  
  250.         echo PHP_EOL."The $this->name standard contains $sniffCount sniffs".PHP_EOL;
  251.  
  252.         ob_start();
  253.  
  254.         foreach ($sniffs as $i => $sniff{
  255.             if ($i === $sniffCount{
  256.                 $currentStandard = null;
  257.             else {
  258.                 $currentStandard substr($sniff0strpos($sniff'.'));
  259.                 if ($lastStandard === null{
  260.                     $lastStandard $currentStandard;
  261.                 }
  262.             }
  263.  
  264.             if ($currentStandard !== $lastStandard{
  265.                 $sniffList ob_get_contents();
  266.                 ob_end_clean();
  267.  
  268.                 echo PHP_EOL.$lastStandard.' ('.$lastCount.' sniff';
  269.                 if ($lastCount > 1{
  270.                     echo 's';
  271.                 }
  272.  
  273.                 echo ')'.PHP_EOL;
  274.                 echo str_repeat('-'(strlen($lastStandard.$lastCount+ 10));
  275.                 echo PHP_EOL;
  276.                 echo $sniffList;
  277.  
  278.                 $lastStandard $currentStandard;
  279.                 $lastCount    = 0;
  280.  
  281.                 if ($currentStandard === null{
  282.                     break;
  283.                 }
  284.  
  285.                 ob_start();
  286.             }//end if
  287.  
  288.             echo '  '.$sniff.PHP_EOL;
  289.             $lastCount++;
  290.         }//end foreach
  291.  
  292.     }//end explain()
  293.  
  294.  
  295.     /**
  296.      * Processes a single ruleset and returns a list of the sniffs it represents.
  297.      *
  298.      * Rules founds within the ruleset are processed immediately, but sniff classes
  299.      * are not registered by this method.
  300.      *
  301.      * @param string $rulesetPath The path to a ruleset XML file.
  302.      * @param int    $depth       How many nested processing steps we are in. This
  303.      *                             is only used for debug output.
  304.      *
  305.      * @return string[] 
  306.      * @throws RuntimeException If the ruleset path is invalid.
  307.      */
  308.     public function processRuleset($rulesetPath$depth=0)
  309.     {
  310.         $rulesetPath = Util\Common::realpath($rulesetPath);
  311.         if (PHP_CODESNIFFER_VERBOSITY > 1{
  312.             echo str_repeat("\t"$depth);
  313.             echo 'Processing ruleset '.Util\Common::stripBasepath($rulesetPath$this->config->basepath).PHP_EOL;
  314.         }
  315.  
  316.         $ruleset @simplexml_load_string(file_get_contents($rulesetPath));
  317.         if ($ruleset === false{
  318.             throw new RuntimeException("Ruleset $rulesetPath is not valid");
  319.         }
  320.  
  321.         $ownSniffs      = array();
  322.         $includedSniffs = array();
  323.         $excludedSniffs = array();
  324.  
  325.         $rulesetDir          dirname($rulesetPath);
  326.         $this->rulesetDirs[$rulesetDir;
  327.  
  328.         $sniffDir $rulesetDir.DIRECTORY_SEPARATOR.'Sniffs';
  329.         if (is_dir($sniffDir=== true{
  330.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  331.                 echo str_repeat("\t"$depth);
  332.                 echo "\tAdding sniff files from ".Util\Common::stripBasepath($sniffDir$this->config->basepath).' directory'.PHP_EOL;
  333.             }
  334.  
  335.             $ownSniffs $this->expandSniffDirectory($sniffDir$depth);
  336.         }
  337.  
  338.         // Included custom autoloaders.
  339.         foreach ($ruleset->{'autoload'as $autoload{
  340.             if ($this->shouldProcessElement($autoload=== false{
  341.                 continue;
  342.             }
  343.  
  344.             $autoloadPath = (string) $autoload;
  345.             if (is_file($autoloadPath=== false{
  346.                 $autoloadPath = Util\Common::realPath(dirname($rulesetPath).DIRECTORY_SEPARATOR.$autoloadPath);
  347.             }
  348.  
  349.             if ($autoloadPath === false{
  350.                 throw new RuntimeException('The specified autoload file "'.$autoload.'" does not exist');
  351.             }
  352.  
  353.             include_once $autoloadPath;
  354.  
  355.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  356.                 echo str_repeat("\t"$depth);
  357.                 echo "\t=> included autoloader $autoloadPath".PHP_EOL;
  358.             }
  359.         }//end foreach
  360.  
  361.         // Process custom sniff config settings.
  362.         foreach ($ruleset->{'config'as $config{
  363.             if ($this->shouldProcessElement($config=== false{
  364.                 continue;
  365.             }
  366.  
  367.             Config::setConfigData((string) $config['name'](string) $config['value']true);
  368.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  369.                 echo str_repeat("\t"$depth);
  370.                 echo "\t=> set config value ".(string) $config['name'].': '.(string) $config['value'].PHP_EOL;
  371.             }
  372.         }
  373.  
  374.         foreach ($ruleset->rule as $rule{
  375.             if (isset($rule['ref']=== false
  376.                 || $this->shouldProcessElement($rule=== false
  377.             {
  378.                 continue;
  379.             }
  380.  
  381.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  382.                 echo str_repeat("\t"$depth);
  383.                 echo "\tProcessing rule \"".$rule['ref'].'"'.PHP_EOL;
  384.             }
  385.  
  386.             $expandedSniffs $this->expandRulesetReference((string) $rule['ref']$rulesetDir$depth);
  387.             $newSniffs      array_diff($expandedSniffs$includedSniffs);
  388.             $includedSniffs array_merge($includedSniffs$expandedSniffs);
  389.  
  390.             $parts explode('.'$rule['ref']);
  391.             if (count($parts=== 4{
  392.                 $sniffCode $parts[0].'.'.$parts[1].'.'.$parts[2];
  393.                 if (isset($this->ruleset[$sniffCode]['severity']=== true
  394.                     && $this->ruleset[$sniffCode]['severity'=== 0
  395.                 {
  396.                     // This sniff code has already been turned off, but now
  397.                     // it is being explicitly included again, so turn it back on.
  398.                     $this->ruleset[(string) $rule['ref']]['severity'= 5;
  399.                     if (PHP_CODESNIFFER_VERBOSITY > 1{
  400.                         echo str_repeat("\t"$depth);
  401.                         echo "\t\t* disabling sniff exclusion for specific message code *".PHP_EOL;
  402.                         echo str_repeat("\t"$depth);
  403.                         echo "\t\t=> severity set to 5".PHP_EOL;
  404.                     }
  405.                 else if (empty($newSniffs=== false{
  406.                     $newSniff $newSniffs[0];
  407.                     if (in_array($newSniff$ownSniffs=== false{
  408.                         // Including a sniff that hasn't been included higher up, but
  409.                         // only including a single message from it. So turn off all messages in
  410.                         // the sniff, except this one.
  411.                         $this->ruleset[$sniffCode]['severity']            = 0;
  412.                         $this->ruleset[(string) $rule['ref']]['severity'= 5;
  413.                         if (PHP_CODESNIFFER_VERBOSITY > 1{
  414.                             echo str_repeat("\t"$depth);
  415.                             echo "\t\tExcluding sniff \"".$sniffCode.'" except for "'.$parts[3].'"'.PHP_EOL;
  416.                         }
  417.                     }
  418.                 }//end if
  419.             }//end if
  420.  
  421.             if (isset($rule->exclude=== true{
  422.                 foreach ($rule->exclude as $exclude{
  423.                     if (isset($exclude['name']=== false{
  424.                         if (PHP_CODESNIFFER_VERBOSITY > 1{
  425.                             echo str_repeat("\t"$depth);
  426.                             echo "\t\t* ignoring empty exclude rule *".PHP_EOL;
  427.                             echo "\t\t\t=> ".$exclude->asXML().PHP_EOL;
  428.                         }
  429.  
  430.                         continue;
  431.                     }
  432.  
  433.                     if ($this->shouldProcessElement($exclude=== false{
  434.                         continue;
  435.                     }
  436.  
  437.                     if (PHP_CODESNIFFER_VERBOSITY > 1{
  438.                         echo str_repeat("\t"$depth);
  439.                         echo "\t\tExcluding rule \"".$exclude['name'].'"'.PHP_EOL;
  440.                     }
  441.  
  442.                     // Check if a single code is being excluded, which is a shortcut
  443.                     // for setting the severity of the message to 0.
  444.                     $parts explode('.'$exclude['name']);
  445.                     if (count($parts=== 4{
  446.                         $this->ruleset[(string) $exclude['name']]['severity'= 0;
  447.                         if (PHP_CODESNIFFER_VERBOSITY > 1{
  448.                             echo str_repeat("\t"$depth);
  449.                             echo "\t\t=> severity set to 0".PHP_EOL;
  450.                         }
  451.                     else {
  452.                         $excludedSniffs array_merge(
  453.                             $excludedSniffs,
  454.                             $this->expandRulesetReference($exclude['name']$rulesetDir($depth + 1))
  455.                         );
  456.                     }
  457.                 }//end foreach
  458.             }//end if
  459.  
  460.             $this->processRule($rule$newSniffs$depth);
  461.         }//end foreach
  462.  
  463.         // Process custom command line arguments.
  464.         $cliArgs = array();
  465.         foreach ($ruleset->{'arg'as $arg{
  466.             if ($this->shouldProcessElement($arg=== false{
  467.                 continue;
  468.             }
  469.  
  470.             if (isset($arg['name']=== true{
  471.                 $argString '--'.(string) $arg['name'];
  472.                 if (isset($arg['value']=== true{
  473.                     $argString .= '='.(string) $arg['value'];
  474.                 }
  475.             else {
  476.                 $argString '-'.(string) $arg['value'];
  477.             }
  478.  
  479.             $cliArgs[$argString;
  480.  
  481.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  482.                 echo str_repeat("\t"$depth);
  483.                 echo "\t=> set command line value $argString".PHP_EOL;
  484.             }
  485.         }//end foreach
  486.  
  487.         // Set custom php ini values as CLI args.
  488.         foreach ($ruleset->{'ini'as $arg{
  489.             if ($this->shouldProcessElement($arg=== false{
  490.                 continue;
  491.             }
  492.  
  493.             if (isset($arg['name']=== false{
  494.                 continue;
  495.             }
  496.  
  497.             $name      = (string) $arg['name'];
  498.             $argString $name;
  499.             if (isset($arg['value']=== true{
  500.                 $value      = (string) $arg['value'];
  501.                 $argString .= "=$value";
  502.             else {
  503.                 $value 'true';
  504.             }
  505.  
  506.             $cliArgs['-d';
  507.             $cliArgs[$argString;
  508.  
  509.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  510.                 echo str_repeat("\t"$depth);
  511.                 echo "\t=> set PHP ini value $name to $value".PHP_EOL;
  512.             }
  513.         }//end foreach
  514.  
  515.         if (empty($this->config->files=== true{
  516.             // Process hard-coded file paths.
  517.             foreach ($ruleset->{'file'as $file{
  518.                 $file      = (string) $file;
  519.                 $cliArgs[$file;
  520.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  521.                     echo str_repeat("\t"$depth);
  522.                     echo "\t=> added \"$file\" to the file list".PHP_EOL;
  523.                 }
  524.             }
  525.         }
  526.  
  527.         if (empty($cliArgs=== false{
  528.             // Change the directory so all relative paths are worked
  529.             // out based on the location of the ruleset instead of
  530.             // the location of the user.
  531.             $inPhar = Util\Common::isPharFile($rulesetDir);
  532.             if ($inPhar === false{
  533.                 $currentDir getcwd();
  534.                 chdir($rulesetDir);
  535.             }
  536.  
  537.             $this->config->setCommandLineValues($cliArgs);
  538.  
  539.             if ($inPhar === false{
  540.                 chdir($currentDir);
  541.             }
  542.         }
  543.  
  544.         // Process custom ignore pattern rules.
  545.         foreach ($ruleset->{'exclude-pattern'as $pattern{
  546.             if ($this->shouldProcessElement($pattern=== false{
  547.                 continue;
  548.             }
  549.  
  550.             if (isset($pattern['type']=== false{
  551.                 $pattern['type''absolute';
  552.             }
  553.  
  554.             $this->ignorePatterns[(string) $pattern= (string) $pattern['type'];
  555.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  556.                 echo str_repeat("\t"$depth);
  557.                 echo "\t=> added global ".(string) $pattern['type'].' ignore pattern: '.(string) $pattern.PHP_EOL;
  558.             }
  559.         }
  560.  
  561.         $includedSniffs array_unique(array_merge($ownSniffs$includedSniffs));
  562.         $excludedSniffs array_unique($excludedSniffs);
  563.  
  564.         if (PHP_CODESNIFFER_VERBOSITY > 1{
  565.             $included count($includedSniffs);
  566.             $excluded count($excludedSniffs);
  567.             echo str_repeat("\t"$depth);
  568.             echo "=> Ruleset processing complete; included $included sniffs and excluded $excluded".PHP_EOL;
  569.         }
  570.  
  571.         // Merge our own sniff list with our externally included
  572.         // sniff list, but filter out any excluded sniffs.
  573.         $files = array();
  574.         foreach ($includedSniffs as $sniff{
  575.             if (in_array($sniff$excludedSniffs=== true{
  576.                 continue;
  577.             else {
  578.                 $files[= Util\Common::realpath($sniff);
  579.             }
  580.         }
  581.  
  582.         return $files;
  583.  
  584.     }//end processRuleset()
  585.  
  586.  
  587.     /**
  588.      * Expands a directory into a list of sniff files within.
  589.      *
  590.      * @param string $directory The path to a directory.
  591.      * @param int    $depth     How many nested processing steps we are in. This
  592.      *                           is only used for debug output.
  593.      *
  594.      * @return array 
  595.      */
  596.     private function expandSniffDirectory($directory$depth=0)
  597.     {
  598.         $sniffs = array();
  599.  
  600.         $rdi = new \RecursiveDirectoryIterator($directory\RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
  601.         $di  = new \RecursiveIteratorIterator($rdi0\RecursiveIteratorIterator::CATCH_GET_CHILD);
  602.  
  603.         $dirLen strlen($directory);
  604.  
  605.         foreach ($di as $file{
  606.             $filename $file->getFilename();
  607.  
  608.             // Skip hidden files.
  609.             if (substr($filename01=== '.'{
  610.                 continue;
  611.             }
  612.  
  613.             // We are only interested in PHP and sniff files.
  614.             $fileParts explode('.'$filename);
  615.             if (array_pop($fileParts!== 'php'{
  616.                 continue;
  617.             }
  618.  
  619.             $basename basename($filename'.php');
  620.             if (substr($basename-5!== 'Sniff'{
  621.                 continue;
  622.             }
  623.  
  624.             $path $file->getPathname();
  625.  
  626.             // Skip files in hidden directories within the Sniffs directory of this
  627.             // standard. We use the offset with strpos() to allow hidden directories
  628.             // before, valid example:
  629.             // /home/foo/.composer/vendor/squiz/custom_tool/MyStandard/Sniffs/...
  630.             if (strpos($pathDIRECTORY_SEPARATOR.'.'$dirLen!== false{
  631.                 continue;
  632.             }
  633.  
  634.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  635.                 echo str_repeat("\t"$depth);
  636.                 echo "\t\t=> ".Util\Common::stripBasepath($path$this->config->basepath).PHP_EOL;
  637.             }
  638.  
  639.             $sniffs[$path;
  640.         }//end foreach
  641.  
  642.         return $sniffs;
  643.  
  644.     }//end expandSniffDirectory()
  645.  
  646.  
  647.     /**
  648.      * Expands a ruleset reference into a list of sniff files.
  649.      *
  650.      * @param string $ref        The reference from the ruleset XML file.
  651.      * @param string $rulesetDir The directory of the ruleset XML file, used to
  652.      *                            evaluate relative paths.
  653.      * @param int    $depth      How many nested processing steps we are in. This
  654.      *                            is only used for debug output.
  655.      *
  656.      * @return array 
  657.      * @throws RuntimeException If the reference is invalid.
  658.      */
  659.     private function expandRulesetReference($ref$rulesetDir$depth=0)
  660.     {
  661.         // Ignore internal sniffs codes as they are used to only
  662.         // hide and change internal messages.
  663.         if (substr($ref09=== 'Internal.'{
  664.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  665.                 echo str_repeat("\t"$depth);
  666.                 echo "\t\t* ignoring internal sniff code *".PHP_EOL;
  667.             }
  668.  
  669.             return array();
  670.         }
  671.  
  672.         // As sniffs can't begin with a full stop, assume references in
  673.         // this format are relative paths and attempt to convert them
  674.         // to absolute paths. If this fails, let the reference run through
  675.         // the normal checks and have it fail as normal.
  676.         if (substr($ref01=== '.'{
  677.             $realpath = Util\Common::realpath($rulesetDir.'/'.$ref);
  678.             if ($realpath !== false{
  679.                 $ref $realpath;
  680.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  681.                     echo str_repeat("\t"$depth);
  682.                     echo "\t\t=> ".Util\Common::stripBasepath($ref$this->config->basepath).PHP_EOL;
  683.                 }
  684.             }
  685.         }
  686.  
  687.         // As sniffs can't begin with a tilde, assume references in
  688.         // this format are relative to the user's home directory.
  689.         if (substr($ref02=== '~/'{
  690.             $realpath = Util\Common::realpath($ref);
  691.             if ($realpath !== false{
  692.                 $ref $realpath;
  693.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  694.                     echo str_repeat("\t"$depth);
  695.                     echo "\t\t=> ".Util\Common::stripBasepath($ref$this->config->basepath).PHP_EOL;
  696.                 }
  697.             }
  698.         }
  699.  
  700.         if (is_file($ref=== true{
  701.             if (substr($ref-9=== 'Sniff.php'{
  702.                 // A single external sniff.
  703.                 $this->rulesetDirs[dirname(dirname(dirname($ref)));
  704.                 return array($ref);
  705.             }
  706.         else {
  707.             // See if this is a whole standard being referenced.
  708.             $path = Util\Standards::getInstalledStandardPath($ref);
  709.             if (Util\Common::isPharFile($path=== true && strpos($path'ruleset.xml'=== false{
  710.                 // If the ruleset exists inside the phar file, use it.
  711.                 if (file_exists($path.DIRECTORY_SEPARATOR.'ruleset.xml'=== true{
  712.                     $path $path.DIRECTORY_SEPARATOR.'ruleset.xml';
  713.                 else {
  714.                     $path = null;
  715.                 }
  716.             }
  717.  
  718.             if ($path !== null{
  719.                 $ref $path;
  720.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  721.                     echo str_repeat("\t"$depth);
  722.                     echo "\t\t=> ".Util\Common::stripBasepath($ref$this->config->basepath).PHP_EOL;
  723.                 }
  724.             else if (is_dir($ref=== false{
  725.                 // Work out the sniff path.
  726.                 $sepPos strpos($refDIRECTORY_SEPARATOR);
  727.                 if ($sepPos !== false{
  728.                     $stdName substr($ref0$sepPos);
  729.                     $path    substr($ref$sepPos);
  730.                 else {
  731.                     $parts   explode('.'$ref);
  732.                     $stdName $parts[0];
  733.                     if (count($parts=== 1{
  734.                         // A whole standard?
  735.                         $path '';
  736.                     else if (count($parts=== 2{
  737.                         // A directory of sniffs?
  738.                         $path = DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR.$parts[1];
  739.                     else {
  740.                         // A single sniff?
  741.                         $path = DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR.$parts[1].DIRECTORY_SEPARATOR.$parts[2].'Sniff.php';
  742.                     }
  743.                 }
  744.  
  745.                 $newRef  = false;
  746.                 $stdPath = Util\Standards::getInstalledStandardPath($stdName);
  747.                 if ($stdPath !== null && $path !== ''{
  748.                     if (Util\Common::isPharFile($stdPath=== true
  749.                         && strpos($stdPath'ruleset.xml'=== false
  750.                     {
  751.                         // Phar files can only return the directory,
  752.                         // since ruleset can be omitted if building one standard.
  753.                         $newRef = Util\Common::realpath($stdPath.$path);
  754.                     else {
  755.                         $newRef = Util\Common::realpath(dirname($stdPath).$path);
  756.                     }
  757.                 }
  758.  
  759.                 if ($newRef === false{
  760.                     // The sniff is not locally installed, so check if it is being
  761.                     // referenced as a remote sniff outside the install. We do this
  762.                     // by looking through all directories where we have found ruleset
  763.                     // files before, looking for ones for this particular standard,
  764.                     // and seeing if it is in there.
  765.                     foreach ($this->rulesetDirs as $dir{
  766.                         if (strtolower(basename($dir)) !== strtolower($stdName)) {
  767.                             continue;
  768.                         }
  769.  
  770.                         $newRef = Util\Common::realpath($dir.$path);
  771.  
  772.                         if ($newRef !== false{
  773.                             $ref $newRef;
  774.                         }
  775.                     }
  776.                 else {
  777.                     $ref $newRef;
  778.                 }
  779.  
  780.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  781.                     echo str_repeat("\t"$depth);
  782.                     echo "\t\t=> ".Util\Common::stripBasepath($ref$this->config->basepath).PHP_EOL;
  783.                 }
  784.             }//end if
  785.         }//end if
  786.  
  787.         if (is_dir($ref=== true{
  788.             if (is_file($ref.DIRECTORY_SEPARATOR.'ruleset.xml'=== true{
  789.                 // We are referencing an external coding standard.
  790.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  791.                     echo str_repeat("\t"$depth);
  792.                     echo "\t\t* rule is referencing a standard using directory name; processing *".PHP_EOL;
  793.                 }
  794.  
  795.                 return $this->processRuleset($ref.DIRECTORY_SEPARATOR.'ruleset.xml'($depth + 2));
  796.             else {
  797.                 // We are referencing a whole directory of sniffs.
  798.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  799.                     echo str_repeat("\t"$depth);
  800.                     echo "\t\t* rule is referencing a directory of sniffs *".PHP_EOL;
  801.                     echo str_repeat("\t"$depth);
  802.                     echo "\t\tAdding sniff files from directory".PHP_EOL;
  803.                 }
  804.  
  805.                 return $this->expandSniffDirectory($ref($depth + 1));
  806.             }
  807.         else {
  808.             if (is_file($ref=== false{
  809.                 $error = "Referenced sniff \"$ref\" does not exist";
  810.                 throw new RuntimeException($error);
  811.             }
  812.  
  813.             if (substr($ref-9=== 'Sniff.php'{
  814.                 // A single sniff.
  815.                 return array($ref);
  816.             else {
  817.                 // Assume an external ruleset.xml file.
  818.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  819.                     echo str_repeat("\t"$depth);
  820.                     echo "\t\t* rule is referencing a standard using ruleset path; processing *".PHP_EOL;
  821.                 }
  822.  
  823.                 return $this->processRuleset($ref($depth + 2));
  824.             }
  825.         }//end if
  826.  
  827.     }//end expandRulesetReference()
  828.  
  829.  
  830.     /**
  831.      * Processes a rule from a ruleset XML file, overriding built-in defaults.
  832.      *
  833.      * @param SimpleXMLElement $rule      The rule object from a ruleset XML file.
  834.      * @param string[]         $newSniffs An array of sniffs that got included by this rule.
  835.      * @param int              $depth     How many nested processing steps we are in.
  836.      *                                     This is only used for debug output.
  837.      *
  838.      * @return void 
  839.      * @throws RuntimeException If rule settings are invalid.
  840.      */
  841.     private function processRule($rule$newSniffs$depth=0)
  842.     {
  843.         $ref  = (string) $rule['ref'];
  844.         $todo = array($ref);
  845.  
  846.         $parts explode('.'$ref);
  847.         if (count($parts<= 2{
  848.             // We are processing a standard or a category of sniffs.
  849.             foreach ($newSniffs as $sniffFile{
  850.                 $parts         explode(DIRECTORY_SEPARATOR$sniffFile);
  851.                 $sniffName     array_pop($parts);
  852.                 $sniffCategory array_pop($parts);
  853.                 array_pop($parts);
  854.                 $sniffStandard array_pop($parts);
  855.                 $todo[]        $sniffStandard.'.'.$sniffCategory.'.'.substr($sniffName0-9);
  856.             }
  857.         }
  858.  
  859.         foreach ($todo as $code{
  860.             // Custom severity.
  861.             if (isset($rule->severity=== true
  862.                 && $this->shouldProcessElement($rule->severity=== true
  863.             {
  864.                 if (isset($this->ruleset[$code]=== false{
  865.                     $this->ruleset[$code= array();
  866.                 }
  867.  
  868.                 $this->ruleset[$code]['severity'= (int) $rule->severity;
  869.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  870.                     echo str_repeat("\t"$depth);
  871.                     echo "\t\t=> severity set to ".(int) $rule->severity;
  872.                     if ($code !== $ref{
  873.                         echo " for $code";
  874.                     }
  875.  
  876.                     echo PHP_EOL;
  877.                 }
  878.             }
  879.  
  880.             // Custom message type.
  881.             if (isset($rule->type=== true
  882.                 && $this->shouldProcessElement($rule->type=== true
  883.             {
  884.                 if (isset($this->ruleset[$code]=== false{
  885.                     $this->ruleset[$code= array();
  886.                 }
  887.  
  888.                 $type strtolower((string) $rule->type);
  889.                 if ($type !== 'error' && $type !== 'warning'{
  890.                     throw new RuntimeException("Message type \"$type\" is invalid; must be \"error\" or \"warning\"");
  891.                 }
  892.  
  893.                 $this->ruleset[$code]['type'$type;
  894.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  895.                     echo str_repeat("\t"$depth);
  896.                     echo "\t\t=> message type set to ".(string) $rule->type;
  897.                     if ($code !== $ref{
  898.                         echo " for $code";
  899.                     }
  900.  
  901.                     echo PHP_EOL;
  902.                 }
  903.             }//end if
  904.  
  905.             // Custom message.
  906.             if (isset($rule->message=== true
  907.                 && $this->shouldProcessElement($rule->message=== true
  908.             {
  909.                 if (isset($this->ruleset[$code]=== false{
  910.                     $this->ruleset[$code= array();
  911.                 }
  912.  
  913.                 $this->ruleset[$code]['message'= (string) $rule->message;
  914.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  915.                     echo str_repeat("\t"$depth);
  916.                     echo "\t\t=> message set to ".(string) $rule->message;
  917.                     if ($code !== $ref{
  918.                         echo " for $code";
  919.                     }
  920.  
  921.                     echo PHP_EOL;
  922.                 }
  923.             }
  924.  
  925.             // Custom properties.
  926.             if (isset($rule->properties=== true
  927.                 && $this->shouldProcessElement($rule->properties=== true
  928.             {
  929.                 foreach ($rule->properties->property as $prop{
  930.                     if ($this->shouldProcessElement($prop=== false{
  931.                         continue;
  932.                     }
  933.  
  934.                     if (isset($this->ruleset[$code]=== false{
  935.                         $this->ruleset[$code= array(
  936.                                                  'properties' => array(),
  937.                                                 );
  938.                     else if (isset($this->ruleset[$code]['properties']=== false{
  939.                         $this->ruleset[$code]['properties'= array();
  940.                     }
  941.  
  942.                     $name = (string) $prop['name'];
  943.                     if (isset($prop['type']=== true
  944.                         && (string) $prop['type'=== 'array'
  945.                     {
  946.                         $value  = (string) $prop['value'];
  947.                         $values = array();
  948.                         foreach (explode(','$valueas $val{
  949.                             $v '';
  950.  
  951.                             list($k,$vexplode('=>'$val.'=>');
  952.                             if ($v !== ''{
  953.                                 $values[$k$v;
  954.                             else {
  955.                                 $values[$k;
  956.                             }
  957.                         }
  958.  
  959.                         $this->ruleset[$code]['properties'][$name$values;
  960.                         if (PHP_CODESNIFFER_VERBOSITY > 1{
  961.                             echo str_repeat("\t"$depth);
  962.                             echo "\t\t=> array property \"$name\" set to \"$value\"";
  963.                             if ($code !== $ref{
  964.                                 echo " for $code";
  965.                             }
  966.  
  967.                             echo PHP_EOL;
  968.                         }
  969.                     else {
  970.                         $this->ruleset[$code]['properties'][$name= (string) $prop['value'];
  971.                         if (PHP_CODESNIFFER_VERBOSITY > 1{
  972.                             echo str_repeat("\t"$depth);
  973.                             echo "\t\t=> property \"$name\" set to \"".(string) $prop['value'].'"';
  974.                             if ($code !== $ref{
  975.                                 echo " for $code";
  976.                             }
  977.  
  978.                             echo PHP_EOL;
  979.                         }
  980.                     }//end if
  981.                 }//end foreach
  982.             }//end if
  983.  
  984.             // Ignore patterns.
  985.             foreach ($rule->{'exclude-pattern'as $pattern{
  986.                 if ($this->shouldProcessElement($pattern=== false{
  987.                     continue;
  988.                 }
  989.  
  990.                 if (isset($this->ignorePatterns[$code]=== false{
  991.                     $this->ignorePatterns[$code= array();
  992.                 }
  993.  
  994.                 if (isset($pattern['type']=== false{
  995.                     $pattern['type''absolute';
  996.                 }
  997.  
  998.                 $this->ignorePatterns[$code][(string) $pattern= (string) $pattern['type'];
  999.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  1000.                     echo str_repeat("\t"$depth);
  1001.                     echo "\t\t=> added rule-specific ".(string) $pattern['type'].' ignore pattern';
  1002.                     if ($code !== $ref{
  1003.                         echo " for $code";
  1004.                     }
  1005.  
  1006.                     echo ': '.(string) $pattern.PHP_EOL;
  1007.                 }
  1008.             }//end foreach
  1009.  
  1010.             // Include patterns.
  1011.             foreach ($rule->{'include-pattern'as $pattern{
  1012.                 if ($this->shouldProcessElement($pattern=== false{
  1013.                     continue;
  1014.                 }
  1015.  
  1016.                 if (isset($this->includePatterns[$code]=== false{
  1017.                     $this->includePatterns[$code= array();
  1018.                 }
  1019.  
  1020.                 if (isset($pattern['type']=== false{
  1021.                     $pattern['type''absolute';
  1022.                 }
  1023.  
  1024.                 $this->includePatterns[$code][(string) $pattern= (string) $pattern['type'];
  1025.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  1026.                     echo str_repeat("\t"$depth);
  1027.                     echo "\t\t=> added rule-specific ".(string) $pattern['type'].' include pattern';
  1028.                     if ($code !== $ref{
  1029.                         echo " for $code";
  1030.                     }
  1031.  
  1032.                     echo ': '.(string) $pattern.PHP_EOL;
  1033.                 }
  1034.             }//end foreach
  1035.         }//end foreach
  1036.  
  1037.     }//end processRule()
  1038.  
  1039.  
  1040.     /**
  1041.      * Determine if an element should be processed or ignored.
  1042.      *
  1043.      * @param SimpleXMLElement $element An object from a ruleset XML file.
  1044.      *
  1045.      * @return bool 
  1046.      */
  1047.     private function shouldProcessElement($element)
  1048.     {
  1049.         if (isset($element['phpcbf-only']=== false
  1050.             && isset($element['phpcs-only']=== false
  1051.         {
  1052.             // No exceptions are being made.
  1053.             return true;
  1054.         }
  1055.  
  1056.         if (PHP_CODESNIFFER_CBF === true
  1057.             && isset($element['phpcbf-only']=== true
  1058.             && (string) $element['phpcbf-only'=== 'true'
  1059.         {
  1060.             return true;
  1061.         }
  1062.  
  1063.         if (PHP_CODESNIFFER_CBF === false
  1064.             && isset($element['phpcs-only']=== true
  1065.             && (string) $element['phpcs-only'=== 'true'
  1066.         {
  1067.             return true;
  1068.         }
  1069.  
  1070.         return false;
  1071.  
  1072.     }//end shouldProcessElement()
  1073.  
  1074.  
  1075.     /**
  1076.      * Loads and stores sniffs objects used for sniffing files.
  1077.      *
  1078.      * @param array $files        Paths to the sniff files to register.
  1079.      * @param array $restrictions The sniff class names to restrict the allowed
  1080.      *                             listeners to.
  1081.      * @param array $exclusions   The sniff class names to exclude from the
  1082.      *                             listeners list.
  1083.      *
  1084.      * @return void 
  1085.      */
  1086.     public function registerSniffs($files$restrictions$exclusions)
  1087.     {
  1088.         $listeners = array();
  1089.  
  1090.         foreach ($files as $file{
  1091.             // Work out where the position of /StandardName/Sniffs/... is
  1092.             // so we can determine what the class will be called.
  1093.             $sniffPos strrpos($fileDIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR);
  1094.             if ($sniffPos === false{
  1095.                 continue;
  1096.             }
  1097.  
  1098.             $slashPos strrpos(substr($file0$sniffPos)DIRECTORY_SEPARATOR);
  1099.             if ($slashPos === false{
  1100.                 continue;
  1101.             }
  1102.  
  1103.             $className   = Autoload::loadFile($file);
  1104.             $compareName = Util\Common::cleanSniffClass($className);
  1105.  
  1106.             // If they have specified a list of sniffs to restrict to, check
  1107.             // to see if this sniff is allowed.
  1108.             if (empty($restrictions=== false
  1109.                 && isset($restrictions[$compareName]=== false
  1110.             {
  1111.                 continue;
  1112.             }
  1113.  
  1114.             // If they have specified a list of sniffs to exclude, check
  1115.             // to see if this sniff is allowed.
  1116.             if (empty($exclusions=== false
  1117.                 && isset($exclusions[$compareName]=== true
  1118.             {
  1119.                 continue;
  1120.             }
  1121.  
  1122.             // Skip abstract classes.
  1123.             $reflection = new \ReflectionClass($className);
  1124.             if ($reflection->isAbstract(=== true{
  1125.                 continue;
  1126.             }
  1127.  
  1128.             $listeners[$className$className;
  1129.  
  1130.             if (PHP_CODESNIFFER_VERBOSITY > 2{
  1131.                 echo "Registered $className".PHP_EOL;
  1132.             }
  1133.         }//end foreach
  1134.  
  1135.         $this->sniffs = $listeners;
  1136.  
  1137.     }//end registerSniffs()
  1138.  
  1139.  
  1140.     /**
  1141.      * Populates the array of PHP_CodeSniffer_Sniff's for this file.
  1142.      *
  1143.      * @return void 
  1144.      * @throws RuntimeException If sniff registration fails.
  1145.      */
  1146.     public function populateTokenListeners()
  1147.     {
  1148.         // Construct a list of listeners indexed by token being listened for.
  1149.         $this->tokenListeners = array();
  1150.  
  1151.         foreach ($this->sniffs as $sniffClass => $sniffObject{
  1152.             $this->sniffs[$sniffClass= null;
  1153.             $this->sniffs[$sniffClass= new $sniffClass();
  1154.  
  1155.             $sniffCode = Util\Common::getSniffCode($sniffClass);
  1156.             $this->sniffCodes[$sniffCode$sniffClass;
  1157.  
  1158.             // Set custom properties.
  1159.             if (isset($this->ruleset[$sniffCode]['properties']=== true{
  1160.                 foreach ($this->ruleset[$sniffCode]['properties'as $name => $value{
  1161.                     $this->setSniffProperty($sniffClass$name$value);
  1162.                 }
  1163.             }
  1164.  
  1165.             $tokenizers = array();
  1166.             $vars       get_class_vars($sniffClass);
  1167.             if (isset($vars['supportedTokenizers']=== true{
  1168.                 foreach ($vars['supportedTokenizers'as $tokenizer{
  1169.                     $tokenizers[$tokenizer$tokenizer;
  1170.                 }
  1171.             else {
  1172.                 $tokenizers = array('PHP' => 'PHP');
  1173.             }
  1174.  
  1175.             $tokens $this->sniffs[$sniffClass]->register();
  1176.             if (is_array($tokens=== false{
  1177.                 $msg = "Sniff $sniffClass register() method must return an array";
  1178.                 throw new RuntimeException($msg);
  1179.             }
  1180.  
  1181.             $ignorePatterns = array();
  1182.             $patterns       $this->getIgnorePatterns($sniffCode);
  1183.             foreach ($patterns as $pattern => $type{
  1184.                 $replacements = array(
  1185.                                  '\\,' => ',',
  1186.                                  '*'   => '.*',
  1187.                                 );
  1188.  
  1189.                 $ignorePatterns[strtr($pattern$replacements);
  1190.             }
  1191.  
  1192.             $includePatterns = array();
  1193.             $patterns        $this->getIncludePatterns($sniffCode);
  1194.             foreach ($patterns as $pattern => $type{
  1195.                 $replacements = array(
  1196.                                  '\\,' => ',',
  1197.                                  '*'   => '.*',
  1198.                                 );
  1199.  
  1200.                 $includePatterns[strtr($pattern$replacements);
  1201.             }
  1202.  
  1203.             foreach ($tokens as $token{
  1204.                 if (isset($this->tokenListeners[$token]=== false{
  1205.                     $this->tokenListeners[$token= array();
  1206.                 }
  1207.  
  1208.                 if (isset($this->tokenListeners[$token][$sniffClass]=== false{
  1209.                     $this->tokenListeners[$token][$sniffClass= array(
  1210.                                                                   'class'      => $sniffClass,
  1211.                                                                   'source'     => $sniffCode,
  1212.                                                                   'tokenizers' => $tokenizers,
  1213.                                                                   'ignore'     => $ignorePatterns,
  1214.                                                                   'include'    => $includePatterns,
  1215.                                                                  );
  1216.                 }
  1217.             }
  1218.         }//end foreach
  1219.  
  1220.     }//end populateTokenListeners()
  1221.  
  1222.  
  1223.     /**
  1224.      * Set a single property for a sniff.
  1225.      *
  1226.      * @param string $sniffClass The class name of the sniff.
  1227.      * @param string $name       The name of the property to change.
  1228.      * @param string $value      The new value of the property.
  1229.      *
  1230.      * @return void 
  1231.      */
  1232.     public function setSniffProperty($sniffClass$name$value)
  1233.     {
  1234.         // Setting a property for a sniff we are not using.
  1235.         if (isset($this->sniffs[$sniffClass]=== false{
  1236.             return;
  1237.         }
  1238.  
  1239.         $name trim($name);
  1240.         if (is_string($value=== true{
  1241.             $value trim($value);
  1242.         }
  1243.  
  1244.         // Special case for booleans.
  1245.         if ($value === 'true'{
  1246.             $value = true;
  1247.         else if ($value === 'false'{
  1248.             $value = false;
  1249.         }
  1250.  
  1251.         $this->sniffs[$sniffClass]->$name $value;
  1252.  
  1253.     }//end setSniffProperty()
  1254.  
  1255.  
  1256.     /**
  1257.      * Gets the array of ignore patterns.
  1258.      *
  1259.      * Optionally takes a listener to get ignore patterns specified
  1260.      * for that sniff only.
  1261.      *
  1262.      * @param string $listener The listener to get patterns for. If NULL, all
  1263.      *                          patterns are returned.
  1264.      *
  1265.      * @return array 
  1266.      */
  1267.     public function getIgnorePatterns($listener=null)
  1268.     {
  1269.         if ($listener === null{
  1270.             return $this->ignorePatterns;
  1271.         }
  1272.  
  1273.         if (isset($this->ignorePatterns[$listener]=== true{
  1274.             return $this->ignorePatterns[$listener];
  1275.         }
  1276.  
  1277.         return array();
  1278.  
  1279.     }//end getIgnorePatterns()
  1280.  
  1281.  
  1282.     /**
  1283.      * Gets the array of include patterns.
  1284.      *
  1285.      * Optionally takes a listener to get include patterns specified
  1286.      * for that sniff only.
  1287.      *
  1288.      * @param string $listener The listener to get patterns for. If NULL, all
  1289.      *                          patterns are returned.
  1290.      *
  1291.      * @return array 
  1292.      */
  1293.     public function getIncludePatterns($listener=null)
  1294.     {
  1295.         if ($listener === null{
  1296.             return $this->includePatterns;
  1297.         }
  1298.  
  1299.         if (isset($this->includePatterns[$listener]=== true{
  1300.             return $this->includePatterns[$listener];
  1301.         }
  1302.  
  1303.         return array();
  1304.  
  1305.     }//end getIncludePatterns()
  1306.  
  1307.  
  1308. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:43 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.