Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. Ruleset.php

function Ruleset::processRuleset

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.

Parameters

string $rulesetPath The path to a ruleset XML file.:

int $depth How many nested processing steps we are in. This: is only used for debug output.

Return value

string[]

Throws

\PHP_CodeSniffer\Exceptions\RuntimeException - If the ruleset path is invalid.

  • If a specified autoload file could not be found.
2 calls to Ruleset::processRuleset()
Ruleset::expandRulesetReference in vendor/squizlabs/php_codesniffer/src/Ruleset.php
Expands a ruleset reference into a list of sniff files.
Ruleset::__construct in vendor/squizlabs/php_codesniffer/src/Ruleset.php
Initialise the ruleset that the run will use.

File

vendor/squizlabs/php_codesniffer/src/Ruleset.php, line 478

Class

Ruleset

Namespace

PHP_CodeSniffer

Code

public function processRuleset($rulesetPath, $depth = 0) {
    $rulesetPath = Common::realpath($rulesetPath);
    if (PHP_CODESNIFFER_VERBOSITY > 1) {
        echo str_repeat("\t", $depth);
        echo 'Processing ruleset ' . Common::stripBasepath($rulesetPath, $this->config->basepath) . PHP_EOL;
    }
    libxml_use_internal_errors(true);
    $ruleset = simplexml_load_string(file_get_contents($rulesetPath));
    if ($ruleset === false) {
        $errorMsg = "Ruleset {$rulesetPath} is not valid" . PHP_EOL;
        $errors = libxml_get_errors();
        foreach ($errors as $error) {
            $errorMsg .= '- On line ' . $error->line . ', column ' . $error->column . ': ' . $error->message;
        }
        libxml_clear_errors();
        throw new RuntimeException($errorMsg);
    }
    libxml_use_internal_errors(false);
    $ownSniffs = [];
    $includedSniffs = [];
    $excludedSniffs = [];
    $this->paths[] = $rulesetPath;
    $rulesetDir = dirname($rulesetPath);
    $this->rulesetDirs[] = $rulesetDir;
    $sniffDir = $rulesetDir . DIRECTORY_SEPARATOR . 'Sniffs';
    if (is_dir($sniffDir) === true) {
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            echo "\tAdding sniff files from " . Common::stripBasepath($sniffDir, $this->config->basepath) . ' directory' . PHP_EOL;
        }
        $ownSniffs = $this->expandSniffDirectory($sniffDir, $depth);
    }
    // Include custom autoloaders.
    foreach ($ruleset->{'autoload'} as $autoload) {
        if ($this->shouldProcessElement($autoload) === false) {
            continue;
        }
        $autoloadPath = (string) $autoload;
        // Try relative autoload paths first.
        $relativePath = Common::realPath(dirname($rulesetPath) . DIRECTORY_SEPARATOR . $autoloadPath);
        if ($relativePath !== false && is_file($relativePath) === true) {
            $autoloadPath = $relativePath;
        }
        else {
            if (is_file($autoloadPath) === false) {
                throw new RuntimeException('The specified autoload file "' . $autoload . '" does not exist');
            }
        }
        include_once $autoloadPath;
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            echo "\t=> included autoloader {$autoloadPath}" . PHP_EOL;
        }
    }
    
    //end foreach
    // Process custom sniff config settings.
    foreach ($ruleset->{'config'} as $config) {
        if ($this->shouldProcessElement($config) === false) {
            continue;
        }
        Config::setConfigData((string) $config['name'], (string) $config['value'], true);
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            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) {
            continue;
        }
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            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 && $parts[0] !== '' && $parts[1] !== '' && $parts[2] !== '') {
            $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 str_repeat("\t", $depth);
                    echo "\t\t* disabling sniff exclusion for specific message code *" . PHP_EOL;
                    echo str_repeat("\t", $depth);
                    echo "\t\t=> severity set to 5" . PHP_EOL;
                }
            }
            else {
                if (empty($newSniffs) === false) {
                    $newSniff = $newSniffs[0];
                    if (in_array($newSniff, $ownSniffs, true) === 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 str_repeat("\t", $depth);
                            echo "\t\tExcluding sniff \"" . $sniffCode . '" except for "' . $parts[3] . '"' . PHP_EOL;
                        }
                    }
                }
            }
            
            //end if
        }
        
        //end if
        if (isset($rule->exclude) === true) {
            foreach ($rule->exclude as $exclude) {
                if (isset($exclude['name']) === false) {
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
                        echo str_repeat("\t", $depth);
                        echo "\t\t* ignoring empty exclude rule *" . PHP_EOL;
                        echo "\t\t\t=> " . $exclude->asXML() . PHP_EOL;
                    }
                    continue;
                }
                if ($this->shouldProcessElement($exclude) === false) {
                    continue;
                }
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo str_repeat("\t", $depth);
                    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 str_repeat("\t", $depth);
                        echo "\t\t=> severity set to 0" . PHP_EOL;
                    }
                }
                else {
                    $excludedSniffs = array_merge($excludedSniffs, $this->expandRulesetReference((string) $exclude['name'], $rulesetDir, $depth + 1));
                }
            }
            
            //end foreach
        }
        
        //end if
        $this->processRule($rule, $newSniffs, $depth);
    }
    
    //end foreach
    // Process custom command line arguments.
    $cliArgs = [];
    foreach ($ruleset->{'arg'} as $arg) {
        if ($this->shouldProcessElement($arg) === false) {
            continue;
        }
        if (isset($arg['name']) === true) {
            $argString = '--' . (string) $arg['name'];
            if (isset($arg['value']) === true) {
                $argString .= '=' . (string) $arg['value'];
            }
        }
        else {
            $argString = '-' . (string) $arg['value'];
        }
        $cliArgs[] = $argString;
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            echo "\t=> set command line value {$argString}" . PHP_EOL;
        }
    }
    
    //end foreach
    // Set custom php ini values as CLI args.
    foreach ($ruleset->{'ini'} as $arg) {
        if ($this->shouldProcessElement($arg) === false) {
            continue;
        }
        if (isset($arg['name']) === false) {
            continue;
        }
        $name = (string) $arg['name'];
        $argString = $name;
        if (isset($arg['value']) === true) {
            $value = (string) $arg['value'];
            $argString .= "={$value}";
        }
        else {
            $value = 'true';
        }
        $cliArgs[] = '-d';
        $cliArgs[] = $argString;
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            echo "\t=> set PHP ini value {$name} to {$value}" . PHP_EOL;
        }
    }
    
    //end foreach
    if (empty($this->config->files) === true) {
        // Process hard-coded file paths.
        foreach ($ruleset->{'file'} as $file) {
            $file = (string) $file;
            $cliArgs[] = $file;
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
                echo str_repeat("\t", $depth);
                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 = Common::isPharFile($rulesetDir);
        if ($inPhar === false) {
            $currentDir = getcwd();
            chdir($rulesetDir);
        }
        $this->config
            ->setCommandLineValues($cliArgs);
        if ($inPhar === false) {
            chdir($currentDir);
        }
    }
    // Process custom ignore pattern rules.
    foreach ($ruleset->{'exclude-pattern'} as $pattern) {
        if ($this->shouldProcessElement($pattern) === false) {
            continue;
        }
        if (isset($pattern['type']) === false) {
            $pattern['type'] = 'absolute';
        }
        $this->ignorePatterns[(string) $pattern] = (string) $pattern['type'];
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
            echo str_repeat("\t", $depth);
            echo "\t=> added global " . (string) $pattern['type'] . ' ignore pattern: ' . (string) $pattern . PHP_EOL;
        }
    }
    $includedSniffs = array_unique(array_merge($ownSniffs, $includedSniffs));
    $excludedSniffs = array_unique($excludedSniffs);
    if (PHP_CODESNIFFER_VERBOSITY > 1) {
        $included = count($includedSniffs);
        $excluded = count($excludedSniffs);
        echo str_repeat("\t", $depth);
        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.
    $files = [];
    foreach ($includedSniffs as $sniff) {
        if (in_array($sniff, $excludedSniffs, true) === true) {
            continue;
        }
        else {
            $files[] = Common::realpath($sniff);
        }
    }
    return $files;
}
RSS feed
Powered by Drupal