Current File : //var/www/prestashop/modules/ps_metrics/vendor/squizlabs/php_codesniffer/src/Ruleset.php
<?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/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 */
namespace ps_metrics_module_v4_0_6\PHP_CodeSniffer;

use ps_metrics_module_v4_0_6\PHP_CodeSniffer\Exceptions\RuntimeException;
use ps_metrics_module_v4_0_6\PHP_CodeSniffer\Sniffs\DeprecatedSniff;
use ps_metrics_module_v4_0_6\PHP_CodeSniffer\Util\Common;
use ps_metrics_module_v4_0_6\PHP_CodeSniffer\Util\Standards;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ReflectionClass;
use stdClass;
class Ruleset
{
    /**
     * 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.
     *
     * @var string
     */
    public $name = '';
    /**
     * A list of file paths for the ruleset files being used.
     *
     * @var string[]
     */
    public $paths = [];
    /**
     * 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, array>
     */
    public $ignorePatterns = [];
    /**
     * 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 = [];
    /**
     * 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\Sniffs\Sniff>
     */
    public $sniffs = [];
    /**
     * 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 = [];
    /**
     * 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
     * is the sniff object.
     *
     * @var array<int, array<string, array<string, mixed>>>
     */
    public $tokenListeners = [];
    /**
     * 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 = [];
    /**
     * The directories that the processed rulesets are in.
     *
     * @var string[]
     */
    protected $rulesetDirs = [];
    /**
     * The config data for the run.
     *
     * @var \PHP_CodeSniffer\Config
     */
    private $config = null;
    /**
     * An array of the names of sniffs which have been marked as deprecated.
     *
     * The key is the sniff code and the value
     * is the fully qualified name of the sniff class.
     *
     * @var array<string, string>
     */
    private $deprecatedSniffs = [];
    /**
     * Initialise the ruleset that the run will use.
     *
     * @param \PHP_CodeSniffer\Config $config The config data for the run.
     *
     * @return void
     * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If no sniffs were registered.
     */
    public function __construct(Config $config)
    {
        $this->config = $config;
        $restrictions = $config->sniffs;
        $exclusions = $config->exclude;
        $sniffs = [];
        $standardPaths = [];
        foreach ($config->standards as $standard) {
            $installed = Standards::getInstalledStandardPath($standard);
            if ($installed === null) {
                $standard = Common::realpath($standard);
                if (\is_dir($standard) === \true && \is_file(Common::realpath($standard . \DIRECTORY_SEPARATOR . 'ruleset.xml')) === \true) {
                    $standard = Common::realpath($standard . \DIRECTORY_SEPARATOR . 'ruleset.xml');
                }
            } else {
                $standard = $installed;
            }
            $standardPaths[] = $standard;
        }
        foreach ($standardPaths as $standard) {
            $ruleset = @\simplexml_load_string(\file_get_contents($standard));
            if ($ruleset !== \false) {
                $standardName = (string) $ruleset['name'];
                if ($this->name !== '') {
                    $this->name .= ', ';
                }
                $this->name .= $standardName;
                // Allow autoloading of custom files inside this standard.
                if (isset($ruleset['namespace']) === \true) {
                    $namespace = (string) $ruleset['namespace'];
                } else {
                    $namespace = \basename(\dirname($standard));
                }
                Autoload::addSearchPath(\dirname($standard), $namespace);
            }
            if (\defined('PHP_CODESNIFFER_IN_TESTS') === \true && empty($restrictions) === \false) {
                // In unit tests, only register the sniffs that the test wants and not the entire standard.
                try {
                    foreach ($restrictions as $restriction) {
                        $sniffs = \array_merge($sniffs, $this->expandRulesetReference($restriction, \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.
                    return;
                }
                break;
            }
            if (PHP_CODESNIFFER_VERBOSITY === 1) {
                echo "Registering sniffs in the {$standardName} standard... ";
                if (\count($config->standards) > 1 || PHP_CODESNIFFER_VERBOSITY > 2) {
                    echo \PHP_EOL;
                }
            }
            $sniffs = \array_merge($sniffs, $this->processRuleset($standard));
        }
        //end foreach
        // Ignore sniff restrictions if caching is on.
        if ($config->cache === \true) {
            $restrictions = [];
            $exclusions = [];
        }
        $sniffRestrictions = [];
        foreach ($restrictions as $sniffCode) {
            $parts = \explode('.', \strtolower($sniffCode));
            $sniffName = $parts[0] . '\\sniffs\\' . $parts[1] . '\\' . $parts[2] . 'sniff';
            $sniffRestrictions[$sniffName] = \true;
        }
        $sniffExclusions = [];
        foreach ($exclusions as $sniffCode) {
            $parts = \explode('.', \strtolower($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;
        }
        if ($numSniffs === 0) {
            throw new RuntimeException('No sniffs were registered');
        }
    }
    //end __construct()
    /**
     * Prints a report showing the sniffs contained in a standard.
     *
     * @return void
     */
    public function explain()
    {
        $sniffs = \array_keys($this->sniffCodes);
        \sort($sniffs, \SORT_NATURAL | \SORT_FLAG_CASE);
        $sniffCount = \count($sniffs);
        // Add a dummy entry to the end so we loop one last time
        // and echo out the collected info about the last standard.
        $sniffs[] = '';
        $summaryLine = \PHP_EOL . "The {$this->name} standard contains 1 sniff" . \PHP_EOL;
        if ($sniffCount !== 1) {
            $summaryLine = \str_replace('1 sniff', "{$sniffCount} sniffs", $summaryLine);
        }
        echo $summaryLine;
        $lastStandard = null;
        $lastCount = 0;
        $sniffsInStandard = [];
        foreach ($sniffs as $i => $sniff) {
            if ($i === $sniffCount) {
                $currentStandard = null;
            } else {
                $currentStandard = \substr($sniff, 0, \strpos($sniff, '.'));
                if ($lastStandard === null) {
                    $lastStandard = $currentStandard;
                }
            }
            // Reached the first item in the next standard.
            // Echo out the info collected from the previous standard.
            if ($currentStandard !== $lastStandard) {
                $subTitle = $lastStandard . ' (' . $lastCount . ' sniff';
                if ($lastCount > 1) {
                    $subTitle .= 's';
                }
                $subTitle .= ')';
                echo \PHP_EOL . $subTitle . \PHP_EOL;
                echo \str_repeat('-', \strlen($subTitle)) . \PHP_EOL;
                echo '  ' . \implode(\PHP_EOL . '  ', $sniffsInStandard) . \PHP_EOL;
                $lastStandard = $currentStandard;
                $lastCount = 0;
                $sniffsInStandard = [];
                if ($currentStandard === null) {
                    break;
                }
            }
            //end if
            if (isset($this->deprecatedSniffs[$sniff]) === \true) {
                $sniff .= ' *';
            }
            $sniffsInStandard[] = $sniff;
            ++$lastCount;
        }
        //end foreach
        if (\count($this->deprecatedSniffs) > 0) {
            echo \PHP_EOL . '* Sniffs marked with an asterix are deprecated.' . \PHP_EOL;
        }
    }
    //end explain()
    /**
     * Checks whether any deprecated sniffs were registered via the ruleset.
     *
     * @return bool
     */
    public function hasSniffDeprecations()
    {
        return \count($this->deprecatedSniffs) > 0;
    }
    //end hasSniffDeprecations()
    /**
     * Prints an information block about deprecated sniffs being used.
     *
     * @return void
     *
     * @throws \PHP_CodeSniffer\Exceptions\RuntimeException When the interface implementation is faulty.
     */
    public function showSniffDeprecations()
    {
        if ($this->hasSniffDeprecations() === \false) {
            return;
        }
        // Don't show deprecation notices in quiet mode, in explain mode
        // or when the documentation is being shown.
        // Documentation and explain will mark a sniff as deprecated natively
        // and also call the Ruleset multiple times which would lead to duplicate
        // display of the deprecation messages.
        if ($this->config->quiet === \true || $this->config->explain === \true || $this->config->generator !== null) {
            return;
        }
        $reportWidth = $this->config->reportWidth;
        // Message takes report width minus the leading dash + two spaces, minus a one space gutter at the end.
        $maxMessageWidth = $reportWidth - 4;
        $maxActualWidth = 0;
        \ksort($this->deprecatedSniffs, \SORT_NATURAL | \SORT_FLAG_CASE);
        $messages = [];
        $messageTemplate = 'This sniff has been deprecated since %s and will be removed in %s. %s';
        $errorTemplate = 'The %s::%s() method must return a %sstring, received %s';
        foreach ($this->deprecatedSniffs as $sniffCode => $className) {
            if (isset($this->sniffs[$className]) === \false) {
                // Should only be possible in test situations, but some extra defensive coding is never a bad thing.
                continue;
            }
            // Verify the interface was implemented correctly.
            // Unfortunately can't be safeguarded via type declarations yet.
            $deprecatedSince = $this->sniffs[$className]->getDeprecationVersion();
            if (\is_string($deprecatedSince) === \false) {
                throw new RuntimeException(\sprintf($errorTemplate, $className, 'getDeprecationVersion', 'non-empty ', \gettype($deprecatedSince)));
            }
            if ($deprecatedSince === '') {
                throw new RuntimeException(\sprintf($errorTemplate, $className, 'getDeprecationVersion', 'non-empty ', '""'));
            }
            $removedIn = $this->sniffs[$className]->getRemovalVersion();
            if (\is_string($removedIn) === \false) {
                throw new RuntimeException(\sprintf($errorTemplate, $className, 'getRemovalVersion', 'non-empty ', \gettype($removedIn)));
            }
            if ($removedIn === '') {
                throw new RuntimeException(\sprintf($errorTemplate, $className, 'getRemovalVersion', 'non-empty ', '""'));
            }
            $customMessage = $this->sniffs[$className]->getDeprecationMessage();
            if (\is_string($customMessage) === \false) {
                throw new RuntimeException(\sprintf($errorTemplate, $className, 'getDeprecationMessage', '', \gettype($customMessage)));
            }
            // Truncate the error code if there is not enough report width.
            if (\strlen($sniffCode) > $maxMessageWidth) {
                $sniffCode = \substr($sniffCode, 0, $maxMessageWidth - 3) . '...';
            }
            $message = '-  ' . $sniffCode . \PHP_EOL;
            if ($this->config->colors === \true) {
                $message = '-  ' . "\x1b[36m" . $sniffCode . "\x1b[0m" . \PHP_EOL;
            }
            $maxActualWidth = \max($maxActualWidth, \strlen($sniffCode));
            // Normalize new line characters in custom message.
            $customMessage = \preg_replace('`\\R`', \PHP_EOL, $customMessage);
            $notice = \trim(\sprintf($messageTemplate, $deprecatedSince, $removedIn, $customMessage));
            $maxActualWidth = \max($maxActualWidth, \min(\strlen($notice), $maxMessageWidth));
            $wrapped = \wordwrap($notice, $maxMessageWidth, \PHP_EOL);
            $message .= '   ' . \implode(\PHP_EOL . '   ', \explode(\PHP_EOL, $wrapped));
            $messages[] = $message;
        }
        //end foreach
        if (\count($messages) === 0) {
            return;
        }
        $summaryLine = "WARNING: The {$this->name} standard uses 1 deprecated sniff";
        $sniffCount = \count($messages);
        if ($sniffCount !== 1) {
            $summaryLine = \str_replace('1 deprecated sniff', "{$sniffCount} deprecated sniffs", $summaryLine);
        }
        $maxActualWidth = \max($maxActualWidth, \min(\strlen($summaryLine), $maxMessageWidth));
        $summaryLine = \wordwrap($summaryLine, $reportWidth, \PHP_EOL);
        if ($this->config->colors === \true) {
            echo "\x1b[33m" . $summaryLine . "\x1b[0m" . \PHP_EOL;
        } else {
            echo $summaryLine . \PHP_EOL;
        }
        echo \str_repeat('-', \min($maxActualWidth + 4, $reportWidth)) . \PHP_EOL;
        echo \implode(\PHP_EOL, $messages);
        $closer = \wordwrap('Deprecated sniffs are still run, but will stop working at some point in the future.', $reportWidth, \PHP_EOL);
        echo \PHP_EOL . \PHP_EOL . $closer . \PHP_EOL . \PHP_EOL;
    }
    //end showSniffDeprecations()
    /**
     * 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.
     *
     * @return string[]
     * @throws \PHP_CodeSniffer\Exceptions\RuntimeException - If the ruleset path is invalid.
     *                                                      - If a specified autoload file could not be found.
     */
    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;
    }
    //end processRuleset()
    /**
     * 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.
     *
     * @return array
     */
    private function expandSniffDirectory($directory, $depth = 0)
    {
        $sniffs = [];
        $rdi = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
        $di = new RecursiveIteratorIterator($rdi, 0, RecursiveIteratorIterator::CATCH_GET_CHILD);
        $dirLen = \strlen($directory);
        foreach ($di as $file) {
            $filename = $file->getFilename();
            // Skip hidden files.
            if (\substr($filename, 0, 1) === '.') {
                continue;
            }
            // We are only interested in PHP and sniff files.
            $fileParts = \explode('.', $filename);
            if (\array_pop($fileParts) !== 'php') {
                continue;
            }
            $basename = \basename($filename, '.php');
            if (\substr($basename, -5) !== 'Sniff') {
                continue;
            }
            $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) {
                continue;
            }
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
                echo \str_repeat("\t", $depth);
                echo "\t\t=> " . Common::stripBasepath($path, $this->config->basepath) . \PHP_EOL;
            }
            $sniffs[] = $path;
        }
        //end foreach
        return $sniffs;
    }
    //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.
     *
     * @return array
     * @throws \PHP_CodeSniffer\Exceptions\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 \str_repeat("\t", $depth);
                echo "\t\t* ignoring internal sniff code *" . \PHP_EOL;
            }
            return [];
        }
        // 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 = Common::realpath($rulesetDir . '/' . $ref);
            if ($realpath !== \false) {
                $ref = $realpath;
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> " . 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 = Common::realpath($ref);
            if ($realpath !== \false) {
                $ref = $realpath;
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> " . Common::stripBasepath($ref, $this->config->basepath) . \PHP_EOL;
                }
            }
        }
        if (\is_file($ref) === \true) {
            if (\substr($ref, -9) === 'Sniff.php') {
                // A single external sniff.
                $this->rulesetDirs[] = \dirname(\dirname(\dirname($ref)));
                return [$ref];
            }
        } else {
            // See if this is a whole standard being referenced.
            $path = Standards::getInstalledStandardPath($ref);
            if ($path !== null && 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 .= \DIRECTORY_SEPARATOR . 'ruleset.xml';
                } else {
                    $path = null;
                }
            }
            if ($path !== null) {
                $ref = $path;
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> " . Common::stripBasepath($ref, $this->config->basepath) . \PHP_EOL;
                }
            } else {
                if (\is_dir($ref) === \false) {
                    // Work out the sniff path.
                    $sepPos = \strpos($ref, \DIRECTORY_SEPARATOR);
                    if ($sepPos !== \false) {
                        $stdName = \substr($ref, 0, $sepPos);
                        $path = \substr($ref, $sepPos);
                    } else {
                        $parts = \explode('.', $ref);
                        $stdName = $parts[0];
                        if (\count($parts) === 1) {
                            // A whole standard?
                            $path = '';
                        } else {
                            if (\count($parts) === 2) {
                                // A directory of sniffs?
                                $path = \DIRECTORY_SEPARATOR . 'Sniffs' . \DIRECTORY_SEPARATOR . $parts[1];
                            } else {
                                // A single sniff?
                                $path = \DIRECTORY_SEPARATOR . 'Sniffs' . \DIRECTORY_SEPARATOR . $parts[1] . \DIRECTORY_SEPARATOR . $parts[2] . 'Sniff.php';
                            }
                        }
                    }
                    $newRef = \false;
                    $stdPath = Standards::getInstalledStandardPath($stdName);
                    if ($stdPath !== null && $path !== '') {
                        if (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 = Common::realpath($stdPath . $path);
                        } else {
                            $newRef = Common::realpath(\dirname($stdPath) . $path);
                        }
                    }
                    if ($newRef === \false) {
                        // 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) {
                            if (\strtolower(\basename($dir)) !== \strtolower($stdName)) {
                                continue;
                            }
                            $newRef = Common::realpath($dir . $path);
                            if ($newRef !== \false) {
                                $ref = $newRef;
                            }
                        }
                    } else {
                        $ref = $newRef;
                    }
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
                        echo \str_repeat("\t", $depth);
                        echo "\t\t=> " . Common::stripBasepath($ref, $this->config->basepath) . \PHP_EOL;
                    }
                }
            }
            //end if
        }
        //end if
        if (\is_dir($ref) === \true) {
            if (\is_file($ref . \DIRECTORY_SEPARATOR . 'ruleset.xml') === \true) {
                // We are referencing an external coding standard.
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t* rule is referencing a standard using directory name; processing *" . \PHP_EOL;
                }
                return $this->processRuleset($ref . \DIRECTORY_SEPARATOR . 'ruleset.xml', $depth + 2);
            } else {
                // We are referencing a whole directory of sniffs.
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t* rule is referencing a directory of sniffs *" . \PHP_EOL;
                    echo \str_repeat("\t", $depth);
                    echo "\t\tAdding sniff files from directory" . \PHP_EOL;
                }
                return $this->expandSniffDirectory($ref, $depth + 1);
            }
        } else {
            if (\is_file($ref) === \false) {
                $error = "Referenced sniff \"{$ref}\" does not exist";
                throw new RuntimeException($error);
            }
            if (\substr($ref, -9) === 'Sniff.php') {
                // A single sniff.
                return [$ref];
            } else {
                // Assume an external ruleset.xml file.
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t* rule is referencing a standard using ruleset path; processing *" . \PHP_EOL;
                }
                return $this->processRuleset($ref, $depth + 2);
            }
        }
        //end if
    }
    //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.
     *
     * @return void
     * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If rule settings are invalid.
     */
    private function processRule($rule, $newSniffs, $depth = 0)
    {
        $ref = (string) $rule['ref'];
        $todo = [$ref];
        $parts = \explode('.', $ref);
        $partsCount = \count($parts);
        if ($partsCount <= 2 || $partsCount > \count(\array_filter($parts)) || \in_array($ref, $newSniffs) === \true) {
            // We are processing a standard, a category of sniffs or a relative path inclusion.
            foreach ($newSniffs as $sniffFile) {
                $parts = \explode(\DIRECTORY_SEPARATOR, $sniffFile);
                if (\count($parts) === 1 && \DIRECTORY_SEPARATOR === '\\') {
                    // Path using forward slashes while running on Windows.
                    $parts = \explode('/', $sniffFile);
                }
                $sniffName = \array_pop($parts);
                $sniffCategory = \array_pop($parts);
                \array_pop($parts);
                $sniffStandard = \array_pop($parts);
                $todo[] = $sniffStandard . '.' . $sniffCategory . '.' . \substr($sniffName, 0, -9);
            }
        }
        foreach ($todo as $code) {
            // Custom severity.
            if (isset($rule->severity) === \true && $this->shouldProcessElement($rule->severity) === \true) {
                if (isset($this->ruleset[$code]) === \false) {
                    $this->ruleset[$code] = [];
                }
                $this->ruleset[$code]['severity'] = (int) $rule->severity;
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> severity set to " . (int) $rule->severity;
                    if ($code !== $ref) {
                        echo " for {$code}";
                    }
                    echo \PHP_EOL;
                }
            }
            // Custom message type.
            if (isset($rule->type) === \true && $this->shouldProcessElement($rule->type) === \true) {
                if (isset($this->ruleset[$code]) === \false) {
                    $this->ruleset[$code] = [];
                }
                $type = \strtolower((string) $rule->type);
                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 \str_repeat("\t", $depth);
                    echo "\t\t=> message type set to " . (string) $rule->type;
                    if ($code !== $ref) {
                        echo " for {$code}";
                    }
                    echo \PHP_EOL;
                }
            }
            //end if
            // Custom message.
            if (isset($rule->message) === \true && $this->shouldProcessElement($rule->message) === \true) {
                if (isset($this->ruleset[$code]) === \false) {
                    $this->ruleset[$code] = [];
                }
                $this->ruleset[$code]['message'] = (string) $rule->message;
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> message set to " . (string) $rule->message;
                    if ($code !== $ref) {
                        echo " for {$code}";
                    }
                    echo \PHP_EOL;
                }
            }
            // Custom properties.
            if (isset($rule->properties) === \true && $this->shouldProcessElement($rule->properties) === \true) {
                $propertyScope = 'standard';
                if ($code === $ref || \substr($ref, -9) === 'Sniff.php') {
                    $propertyScope = 'sniff';
                }
                foreach ($rule->properties->property as $prop) {
                    if ($this->shouldProcessElement($prop) === \false) {
                        continue;
                    }
                    if (isset($this->ruleset[$code]) === \false) {
                        $this->ruleset[$code] = ['properties' => []];
                    } else {
                        if (isset($this->ruleset[$code]['properties']) === \false) {
                            $this->ruleset[$code]['properties'] = [];
                        }
                    }
                    $name = (string) $prop['name'];
                    if (isset($prop['type']) === \true && (string) $prop['type'] === 'array') {
                        $values = [];
                        if (isset($prop['extend']) === \true && (string) $prop['extend'] === 'true' && isset($this->ruleset[$code]['properties'][$name]['value']) === \true) {
                            $values = $this->ruleset[$code]['properties'][$name]['value'];
                        }
                        if (isset($prop->element) === \true) {
                            $printValue = '';
                            foreach ($prop->element as $element) {
                                if ($this->shouldProcessElement($element) === \false) {
                                    continue;
                                }
                                $value = (string) $element['value'];
                                if (isset($element['key']) === \true) {
                                    $key = (string) $element['key'];
                                    $values[$key] = $value;
                                    $printValue .= $key . '=>' . $value . ',';
                                } else {
                                    $values[] = $value;
                                    $printValue .= $value . ',';
                                }
                            }
                            $printValue = \rtrim($printValue, ',');
                        } else {
                            $value = (string) $prop['value'];
                            $printValue = $value;
                            foreach (\explode(',', $value) as $val) {
                                list($k, $v) = \explode('=>', $val . '=>');
                                if ($v !== '') {
                                    $values[\trim($k)] = \trim($v);
                                } else {
                                    $values[] = \trim($k);
                                }
                            }
                        }
                        //end if
                        $this->ruleset[$code]['properties'][$name] = ['value' => $values, 'scope' => $propertyScope];
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
                            echo \str_repeat("\t", $depth);
                            echo "\t\t=> array property \"{$name}\" set to \"{$printValue}\"";
                            if ($code !== $ref) {
                                echo " for {$code}";
                            }
                            echo \PHP_EOL;
                        }
                    } else {
                        $this->ruleset[$code]['properties'][$name] = ['value' => (string) $prop['value'], 'scope' => $propertyScope];
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
                            echo \str_repeat("\t", $depth);
                            echo "\t\t=> property \"{$name}\" set to \"" . (string) $prop['value'] . '"';
                            if ($code !== $ref) {
                                echo " for {$code}";
                            }
                            echo \PHP_EOL;
                        }
                    }
                    //end if
                }
                //end foreach
            }
            //end if
            // Ignore patterns.
            foreach ($rule->{'exclude-pattern'} as $pattern) {
                if ($this->shouldProcessElement($pattern) === \false) {
                    continue;
                }
                if (isset($this->ignorePatterns[$code]) === \false) {
                    $this->ignorePatterns[$code] = [];
                }
                if (isset($pattern['type']) === \false) {
                    $pattern['type'] = 'absolute';
                }
                $this->ignorePatterns[$code][(string) $pattern] = (string) $pattern['type'];
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> added rule-specific " . (string) $pattern['type'] . ' ignore pattern';
                    if ($code !== $ref) {
                        echo " for {$code}";
                    }
                    echo ': ' . (string) $pattern . \PHP_EOL;
                }
            }
            //end foreach
            // Include patterns.
            foreach ($rule->{'include-pattern'} as $pattern) {
                if ($this->shouldProcessElement($pattern) === \false) {
                    continue;
                }
                if (isset($this->includePatterns[$code]) === \false) {
                    $this->includePatterns[$code] = [];
                }
                if (isset($pattern['type']) === \false) {
                    $pattern['type'] = 'absolute';
                }
                $this->includePatterns[$code][(string) $pattern] = (string) $pattern['type'];
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
                    echo \str_repeat("\t", $depth);
                    echo "\t\t=> added rule-specific " . (string) $pattern['type'] . ' include pattern';
                    if ($code !== $ref) {
                        echo " for {$code}";
                    }
                    echo ': ' . (string) $pattern . \PHP_EOL;
                }
            }
            //end foreach
        }
        //end foreach
    }
    //end processRule()
    /**
     * Determine if an element should be processed or ignored.
     *
     * @param \SimpleXMLElement $element An object from a ruleset XML file.
     *
     * @return bool
     */
    private function shouldProcessElement($element)
    {
        if (isset($element['phpcbf-only']) === \false && isset($element['phpcs-only']) === \false) {
            // No exceptions are being made.
            return \true;
        }
        if (PHP_CODESNIFFER_CBF === \true && isset($element['phpcbf-only']) === \true && (string) $element['phpcbf-only'] === 'true') {
            return \true;
        }
        if (PHP_CODESNIFFER_CBF === \false && isset($element['phpcs-only']) === \true && (string) $element['phpcs-only'] === 'true') {
            return \true;
        }
        return \false;
    }
    //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
     *                            listeners to.
     * @param array $exclusions   The sniff class names to exclude from the
     *                            listeners list.
     *
     * @return void
     */
    public function registerSniffs($files, $restrictions, $exclusions)
    {
        $listeners = [];
        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) {
                continue;
            }
            $slashPos = \strrpos(\substr($file, 0, $sniffPos), \DIRECTORY_SEPARATOR);
            if ($slashPos === \false) {
                continue;
            }
            $className = Autoload::loadFile($file);
            $compareName = 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) {
                continue;
            }
            // 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) {
                continue;
            }
            // Skip abstract classes.
            $reflection = new ReflectionClass($className);
            if ($reflection->isAbstract() === \true) {
                continue;
            }
            $listeners[$className] = $className;
            if (PHP_CODESNIFFER_VERBOSITY > 2) {
                echo "Registered {$className}" . \PHP_EOL;
            }
        }
        //end foreach
        $this->sniffs = $listeners;
    }
    //end registerSniffs()
    /**
     * Populates the array of PHP_CodeSniffer_Sniff objects for this file.
     *
     * @return void
     * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If sniff registration fails.
     */
    public function populateTokenListeners()
    {
        // Construct a list of listeners indexed by token being listened for.
        $this->tokenListeners = [];
        foreach ($this->sniffs as $sniffClass => $sniffObject) {
            $this->sniffs[$sniffClass] = null;
            $this->sniffs[$sniffClass] = new $sniffClass();
            $sniffCode = Common::getSniffCode($sniffClass);
            $this->sniffCodes[$sniffCode] = $sniffClass;
            if ($this->sniffs[$sniffClass] instanceof DeprecatedSniff) {
                $this->deprecatedSniffs[$sniffCode] = $sniffClass;
            }
            // Set custom properties.
            if (isset($this->ruleset[$sniffCode]['properties']) === \true) {
                foreach ($this->ruleset[$sniffCode]['properties'] as $name => $settings) {
                    $this->setSniffProperty($sniffClass, $name, $settings);
                }
            }
            $tokenizers = [];
            $vars = \get_class_vars($sniffClass);
            if (isset($vars['supportedTokenizers']) === \true) {
                foreach ($vars['supportedTokenizers'] as $tokenizer) {
                    $tokenizers[$tokenizer] = $tokenizer;
                }
            } else {
                $tokenizers = ['PHP' => 'PHP'];
            }
            $tokens = $this->sniffs[$sniffClass]->register();
            if (\is_array($tokens) === \false) {
                $msg = "Sniff {$sniffClass} register() method must return an array";
                throw new RuntimeException($msg);
            }
            $ignorePatterns = [];
            $patterns = $this->getIgnorePatterns($sniffCode);
            foreach ($patterns as $pattern => $type) {
                $replacements = ['\\,' => ',', '*' => '.*'];
                $ignorePatterns[] = \strtr($pattern, $replacements);
            }
            $includePatterns = [];
            $patterns = $this->getIncludePatterns($sniffCode);
            foreach ($patterns as $pattern => $type) {
                $replacements = ['\\,' => ',', '*' => '.*'];
                $includePatterns[] = \strtr($pattern, $replacements);
            }
            foreach ($tokens as $token) {
                if (isset($this->tokenListeners[$token]) === \false) {
                    $this->tokenListeners[$token] = [];
                }
                if (isset($this->tokenListeners[$token][$sniffClass]) === \false) {
                    $this->tokenListeners[$token][$sniffClass] = ['class' => $sniffClass, 'source' => $sniffCode, 'tokenizers' => $tokenizers, 'ignore' => $ignorePatterns, 'include' => $includePatterns];
                }
            }
        }
        //end foreach
    }
    //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 array  $settings   Array with the new value of the property and the scope of the property being set.
     *
     * @return void
     *
     * @throws \PHP_CodeSniffer\Exceptions\RuntimeException When attempting to set a non-existent property on a sniff
     *                                                      which doesn't declare the property or explicitly supports
     *                                                      dynamic properties.
     */
    public function setSniffProperty($sniffClass, $name, $settings)
    {
        // Setting a property for a sniff we are not using.
        if (isset($this->sniffs[$sniffClass]) === \false) {
            return;
        }
        $name = \trim($name);
        $propertyName = $name;
        if (\substr($propertyName, -2) === '[]') {
            $propertyName = \substr($propertyName, 0, -2);
        }
        /*
         * BC-compatibility layer for $settings using the pre-PHPCS 3.8.0 format.
         *
         * Prior to PHPCS 3.8.0, `$settings` was expected to only contain the new _value_
         * for the property (which could be an array).
         * Since PHPCS 3.8.0, `$settings` is expected to be an array with two keys: 'scope'
         * and 'value', where 'scope' indicates whether the property should be set to the given 'value'
         * for one individual sniff or for all sniffs in a standard.
         *
         * This BC-layer is only for integrations with PHPCS which may call this method directly
         * and will be removed in PHPCS 4.0.0.
         */
        if (\is_array($settings) === \false || isset($settings['scope'], $settings['value']) === \false) {
            // This will be an "old" format value.
            $settings = ['value' => $settings, 'scope' => 'standard'];
            \trigger_error(__FUNCTION__ . ': the format of the $settings parameter has changed from (mixed) $value to array(\'scope\' => \'sniff|standard\', \'value\' => $value). Please update your integration code. See PR #3629 for more information.', \E_USER_DEPRECATED);
        }
        $isSettable = \false;
        $sniffObject = $this->sniffs[$sniffClass];
        if (\property_exists($sniffObject, $propertyName) === \true || $sniffObject instanceof stdClass === \true || \method_exists($sniffObject, '__set') === \true) {
            $isSettable = \true;
        }
        if ($isSettable === \false) {
            if ($settings['scope'] === 'sniff') {
                $notice = "Ruleset invalid. Property \"{$propertyName}\" does not exist on sniff ";
                $notice .= \array_search($sniffClass, $this->sniffCodes, \true);
                throw new RuntimeException($notice);
            }
            return;
        }
        $value = $settings['value'];
        if (\is_string($value) === \true) {
            $value = \trim($value);
        }
        if ($value === '') {
            $value = null;
        }
        // Special case for booleans.
        if ($value === 'true') {
            $value = \true;
        } else {
            if ($value === 'false') {
                $value = \false;
            } else {
                if (\substr($name, -2) === '[]') {
                    $name = $propertyName;
                    $values = [];
                    if ($value !== null) {
                        foreach (\explode(',', $value) as $val) {
                            list($k, $v) = \explode('=>', $val . '=>');
                            if ($v !== '') {
                                $values[\trim($k)] = \trim($v);
                            } else {
                                $values[] = \trim($k);
                            }
                        }
                    }
                    $value = $values;
                }
            }
        }
        $sniffObject->{$name} = $value;
    }
    //end setSniffProperty()
    /**
     * Gets the array of ignore patterns.
     *
     * Optionally takes a listener to get ignore patterns specified
     * for that sniff only.
     *
     * @param string $listener The listener to get patterns for. If NULL, all
     *                         patterns are returned.
     *
     * @return array
     */
    public function getIgnorePatterns($listener = null)
    {
        if ($listener === null) {
            return $this->ignorePatterns;
        }
        if (isset($this->ignorePatterns[$listener]) === \true) {
            return $this->ignorePatterns[$listener];
        }
        return [];
    }
    //end getIgnorePatterns()
    /**
     * Gets the array of include patterns.
     *
     * Optionally takes a listener to get include patterns specified
     * for that sniff only.
     *
     * @param string $listener The listener to get patterns for. If NULL, all
     *                         patterns are returned.
     *
     * @return array
     */
    public function getIncludePatterns($listener = null)
    {
        if ($listener === null) {
            return $this->includePatterns;
        }
        if (isset($this->includePatterns[$listener]) === \true) {
            return $this->includePatterns[$listener];
        }
        return [];
    }
    //end getIncludePatterns()
}
//end class
¿Qué es la limpieza dental de perros? - Clínica veterinaria


Es la eliminación del sarro y la placa adherida a la superficie de los dientes mediante un equipo de ultrasonidos que garantiza la integridad de las piezas dentales a la vez que elimina en profundidad cualquier resto de suciedad.

A continuación se procede al pulido de los dientes mediante una fresa especial que elimina la placa bacteriana y devuelve a los dientes el aspecto sano que deben tener.

Una vez terminado todo el proceso, se mantiene al perro en observación hasta que se despierta de la anestesia, bajo la atenta supervisión de un veterinario.

¿Cada cuánto tiempo tengo que hacerle una limpieza dental a mi perro?

A partir de cierta edad, los perros pueden necesitar una limpieza dental anual o bianual. Depende de cada caso. En líneas generales, puede decirse que los perros de razas pequeñas suelen acumular más sarro y suelen necesitar una atención mayor en cuanto a higiene dental.


Riesgos de una mala higiene


Los riesgos más evidentes de una mala higiene dental en los perros son los siguientes:

  • Cuando la acumulación de sarro no se trata, se puede producir una inflamación y retracción de las encías que puede descalzar el diente y provocar caídas.
  • Mal aliento (halitosis).
  • Sarro perros
  • Puede ir a más
  • Las bacterias de la placa pueden trasladarse a través del torrente circulatorio a órganos vitales como el corazón ocasionando problemas de endocarditis en las válvulas. Las bacterias pueden incluso acantonarse en huesos (La osteomielitis es la infección ósea, tanto cortical como medular) provocando mucho dolor y una artritis séptica).

¿Cómo se forma el sarro?

El sarro es la calcificación de la placa dental. Los restos de alimentos, junto con las bacterias presentes en la boca, van a formar la placa bacteriana o placa dental. Si la placa no se retira, al mezclarse con la saliva y los minerales presentes en ella, reaccionará formando una costra. La placa se calcifica y se forma el sarro.

El sarro, cuando se forma, es de color blanquecino pero a medida que pasa el tiempo se va poniendo amarillo y luego marrón.

Síntomas de una pobre higiene dental
La señal más obvia de una mala salud dental canina es el mal aliento.

Sin embargo, a veces no es tan fácil de detectar
Y hay perros que no se dejan abrir la boca por su dueño. Por ejemplo…

Recientemente nos trajeron a la clínica a un perro que parpadeaba de un ojo y decía su dueño que le picaba un lado de la cara. Tenía molestias y dificultad para comer, lo que había llevado a sus dueños a comprarle comida blanda (que suele ser un poco más cara y llevar más contenido en grasa) durante medio año. Después de una exploración oftalmológica, nos dimos cuenta de que el ojo tenía una úlcera en la córnea probablemente de rascarse . Además, el canto lateral del ojo estaba inflamado. Tenía lo que en humanos llamamos flemón pero como era un perro de pelo largo, no se le notaba a simple vista. Al abrirle la boca nos llamó la atención el ver una muela llena de sarro. Le realizamos una radiografía y encontramos una fístula que llegaba hasta la parte inferior del ojo.

Le tuvimos que extraer la muela. Tras esto, el ojo se curó completamente con unos colirios y una lentilla protectora de úlcera. Afortunadamente, la úlcera no profundizó y no perforó el ojo. Ahora el perro come perfectamente a pesar de haber perdido una muela.

¿Cómo mantener la higiene dental de tu perro?
Hay varias maneras de prevenir problemas derivados de la salud dental de tu perro.

Limpiezas de dientes en casa
Es recomendable limpiar los dientes de tu perro semanal o diariamente si se puede. Existe una gran variedad de productos que se pueden utilizar:

Pastas de dientes.
Cepillos de dientes o dedales para el dedo índice, que hacen más fácil la limpieza.
Colutorios para echar en agua de bebida o directamente sobre el diente en líquido o en spray.

En la Clínica Tus Veterinarios enseñamos a nuestros clientes a tomar el hábito de limpiar los dientes de sus perros desde que son cachorros. Esto responde a nuestro compromiso con la prevención de enfermedades caninas.

Hoy en día tenemos muchos clientes que limpian los dientes todos los días a su mascota, y como resultado, se ahorran el dinero de hacer limpiezas dentales profesionales y consiguen una mejor salud de su perro.


Limpiezas dentales profesionales de perros y gatos

Recomendamos hacer una limpieza dental especializada anualmente. La realizamos con un aparato de ultrasonidos que utiliza agua para quitar el sarro. Después, procedemos a pulir los dientes con un cepillo de alta velocidad y una pasta especial. Hacemos esto para proteger el esmalte.

La frecuencia de limpiezas dentales necesaria varía mucho entre razas. En general, las razas grandes tienen buena calidad de esmalte, por lo que no necesitan hacerlo tan a menudo e incluso pueden pasarse la vida sin requerir una limpieza. Sin embargo, razas pequeñas como el Yorkshire o el Maltés, deben hacérselas todos los años desde cachorros si se quiere conservar sus piezas dentales.

Otro factor fundamental es la calidad del pienso. Algunas marcas han diseñado croquetas que limpian la superficie del diente y de la muela al masticarse.

Ultrasonido para perros

¿Se necesita anestesia para las limpiezas dentales de perros y gatos?

La limpieza dental en perros no es una técnica que pueda practicarse sin anestesia general , aunque hay veces que los propietarios no quieren anestesiar y si tiene poco sarro y el perro es muy bueno se puede intentar…… , pero no se va a poder pulir ni acceder a todas la zona de la boca …. Además los limpiadores dentales van a irrigar agua y hay riesgo de aspiración a vías respiratorias si no se realiza una anestesia correcta con intubación traqueal . En resumen , sin anestesia no se va hacer una correcta limpieza dental.

Tampoco sirve la sedación ya que necesitamos que el animal esté totalmente quieto, y el veterinario tenga un acceso completo a todas sus piezas dentales y encías.

Alimentos para la limpieza dental

Hay que tener cierto cuidado a la hora de comprar determinados alimentos porque no todos son saludables. Algunos tienen demasiado contenido graso, que en exceso puede causar problemas cardiovasculares y obesidad.

Los mejores alimentos para los dientes son aquellos que están elaborados por empresas farmacéuticas y llevan componentes químicos con tratamientos específicos para el diente del perro. Esto implica no solo limpieza a través de la acción mecánica de morder sino también un tratamiento antibacteriano para prevenir el sarro.

Conclusión

Si eres como la mayoría de dueños, por falta de tiempo , es probable que no estés prestando la suficiente atención a la limpieza dental de tu perro. Por eso te animamos a que comiences a limpiar los dientes de tu perro y consideres atender a su higiene bucal con frecuencia.

Estas simples medidas pueden conllevar a que tu perro tenga una vida más larga y mucho más saludable.

Si te resulta imposible introducir un cepillo de dientes a tu perro en la boca, pásate con él por clínica Tus Veterinarios y te explicamos cómo hacerlo.

Necesitas hacer una limpieza dental profesional a tu mascota?
Llámanos al 622575274 o contacta con nosotros

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¡Hola!