implement JS password scoring, td_stock approve logicc

This commit is contained in:
Thanakorn S
2026-04-30 15:14:42 +07:00
parent db5c47b6ca
commit ac4fd9a5ad
3147 changed files with 1298 additions and 343 deletions
@@ -0,0 +1,351 @@
<?php
/**
* Function for caching between runs.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Util;
use PHP_CodeSniffer\Autoload;
use PHP_CodeSniffer\Config;
use PHP_CodeSniffer\Ruleset;
class Cache
{
/**
* The filesystem location of the cache file.
*
* @var void
*/
private static $path = '';
/**
* The cached data.
*
* @var array<string, mixed>
*/
private static $cache = [];
/**
* Loads existing cache data for the run, if any.
*
* @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
* @param \PHP_CodeSniffer\Config $config The config data for the run.
*
* @return void
*/
public static function load(Ruleset $ruleset, Config $config)
{
// Look at every loaded sniff class so far and use their file contents
// to generate a hash for the code used during the run.
// At this point, the loaded class list contains the core PHPCS code
// and all sniffs that have been loaded as part of the run.
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo PHP_EOL."\tGenerating loaded file list for code hash".PHP_EOL;
}
$codeHashFiles = [];
$classes = array_keys(Autoload::getLoadedClasses());
sort($classes);
$installDir = dirname(__DIR__);
$installDirLen = strlen($installDir);
$standardDir = $installDir.DIRECTORY_SEPARATOR.'Standards';
$standardDirLen = strlen($standardDir);
foreach ($classes as $file) {
if (substr($file, 0, $standardDirLen) !== $standardDir) {
if (substr($file, 0, $installDirLen) === $installDir) {
// We are only interested in sniffs here.
continue;
}
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t\t=> external file: $file".PHP_EOL;
}
} else if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t\t=> internal sniff: $file".PHP_EOL;
}
$codeHashFiles[] = $file;
}
// Add the content of the used rulesets to the hash so that sniff setting
// changes in the ruleset invalidate the cache.
$rulesets = $ruleset->paths;
sort($rulesets);
foreach ($rulesets as $file) {
if (substr($file, 0, $standardDirLen) !== $standardDir) {
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t\t=> external ruleset: $file".PHP_EOL;
}
} else if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t\t=> internal ruleset: $file".PHP_EOL;
}
$codeHashFiles[] = $file;
}
// Go through the core PHPCS code and add those files to the file
// hash. This ensures that core PHPCS changes will also invalidate the cache.
// Note that we ignore sniffs here, and any files that don't affect
// the outcome of the run.
$di = new \RecursiveDirectoryIterator(
$installDir,
(\FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS)
);
$filter = new \RecursiveCallbackFilterIterator(
$di,
function ($file, $key, $iterator) {
// Skip non-php files.
$filename = $file->getFilename();
if ($file->isFile() === true && substr($filename, -4) !== '.php') {
return false;
}
$filePath = Common::realpath($key);
if ($filePath === false) {
return false;
}
if ($iterator->hasChildren() === true
&& ($filename === 'Standards'
|| $filename === 'Exceptions'
|| $filename === 'Reports'
|| $filename === 'Generators')
) {
return false;
}
return true;
}
);
$iterator = new \RecursiveIteratorIterator($filter);
foreach ($iterator as $file) {
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t\t=> core file: $file".PHP_EOL;
}
$codeHashFiles[] = $file->getPathname();
}
$codeHash = '';
sort($codeHashFiles);
foreach ($codeHashFiles as $file) {
$codeHash .= md5_file($file);
}
$codeHash = md5($codeHash);
// Along with the code hash, use various settings that can affect
// the results of a run to create a new hash. This hash will be used
// in the cache file name.
$rulesetHash = md5(var_export($ruleset->ignorePatterns, true).var_export($ruleset->includePatterns, true));
$phpExtensionsHash = md5(var_export(get_loaded_extensions(), true));
$configData = [
'phpVersion' => PHP_VERSION_ID,
'phpExtensions' => $phpExtensionsHash,
'tabWidth' => $config->tabWidth,
'encoding' => $config->encoding,
'recordErrors' => $config->recordErrors,
'annotations' => $config->annotations,
'configData' => Config::getAllConfigData(),
'codeHash' => $codeHash,
'rulesetHash' => $rulesetHash,
];
$configString = var_export($configData, true);
$cacheHash = substr(sha1($configString), 0, 12);
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\tGenerating cache key data".PHP_EOL;
foreach ($configData as $key => $value) {
if (is_array($value) === true) {
echo "\t\t=> $key:".PHP_EOL;
foreach ($value as $subKey => $subValue) {
echo "\t\t\t=> $subKey: $subValue".PHP_EOL;
}
continue;
}
if ($value === true || $value === false) {
$value = (int) $value;
}
echo "\t\t=> $key: $value".PHP_EOL;
}
echo "\t\t=> cacheHash: $cacheHash".PHP_EOL;
}//end if
if ($config->cacheFile !== null) {
$cacheFile = $config->cacheFile;
} else {
// Determine the common paths for all files being checked.
// We can use this to locate an existing cache file, or to
// determine where to create a new one.
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\tChecking possible cache file paths".PHP_EOL;
}
$paths = [];
foreach ($config->files as $file) {
$file = Common::realpath($file);
while ($file !== DIRECTORY_SEPARATOR) {
if (isset($paths[$file]) === false) {
$paths[$file] = 1;
} else {
$paths[$file]++;
}
$lastFile = $file;
$file = dirname($file);
if ($file === $lastFile) {
// Just in case something went wrong,
// we don't want to end up in an infinite loop.
break;
}
}
}
ksort($paths);
$paths = array_reverse($paths);
$numFiles = count($config->files);
$cacheFile = null;
$cacheDir = getenv('XDG_CACHE_HOME');
if ($cacheDir === false || is_dir($cacheDir) === false) {
$cacheDir = sys_get_temp_dir();
}
foreach ($paths as $file => $count) {
if ($count !== $numFiles) {
unset($paths[$file]);
continue;
}
$fileHash = substr(sha1($file), 0, 12);
$testFile = $cacheDir.DIRECTORY_SEPARATOR."phpcs.$fileHash.$cacheHash.cache";
if ($cacheFile === null) {
// This will be our default location if we can't find
// an existing file.
$cacheFile = $testFile;
}
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t\t=> $testFile".PHP_EOL;
echo "\t\t\t * based on shared location: $file *".PHP_EOL;
}
if (file_exists($testFile) === true) {
$cacheFile = $testFile;
break;
}
}//end foreach
if ($cacheFile === null) {
// Unlikely, but just in case $paths is empty for some reason.
$cacheFile = $cacheDir.DIRECTORY_SEPARATOR."phpcs.$cacheHash.cache";
}
}//end if
self::$path = $cacheFile;
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t=> Using cache file: ".self::$path.PHP_EOL;
}
if (file_exists(self::$path) === true) {
self::$cache = json_decode(file_get_contents(self::$path), true);
// Verify the contents of the cache file.
if (self::$cache['config'] !== $configData) {
self::$cache = [];
if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t* cache was invalid and has been cleared *".PHP_EOL;
}
}
} else if (PHP_CODESNIFFER_VERBOSITY > 1) {
echo "\t* cache file does not exist *".PHP_EOL;
}
self::$cache['config'] = $configData;
}//end load()
/**
* Saves the current cache to the filesystem.
*
* @return void
*/
public static function save()
{
file_put_contents(self::$path, json_encode(self::$cache));
}//end save()
/**
* Retrieves a single entry from the cache.
*
* @param string $key The key of the data to get. If NULL,
* everything in the cache is returned.
*
* @return mixed
*/
public static function get($key=null)
{
if ($key === null) {
return self::$cache;
}
if (isset(self::$cache[$key]) === true) {
return self::$cache[$key];
}
return false;
}//end get()
/**
* Retrieves a single entry from the cache.
*
* @param string $key The key of the data to set. If NULL,
* sets the entire cache.
* @param mixed $value The value to set.
*
* @return void
*/
public static function set($key, $value)
{
if ($key === null) {
self::$cache = $value;
} else {
self::$cache[$key] = $value;
}
}//end set()
/**
* Retrieves the number of cache entries.
*
* @return int
*/
public static function getSize()
{
return (count(self::$cache) - 1);
}//end getSize()
}//end class
@@ -0,0 +1,570 @@
<?php
/**
* Basic util functions.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Util;
class Common
{
/**
* An array of variable types for param/var we will check.
*
* @var string[]
*/
public static $allowedTypes = [
'array',
'boolean',
'float',
'integer',
'mixed',
'object',
'string',
'resource',
'callable',
];
/**
* Return TRUE if the path is a PHAR file.
*
* @param string $path The path to use.
*
* @return mixed
*/
public static function isPharFile($path)
{
if (strpos($path, 'phar://') === 0) {
return true;
}
return false;
}//end isPharFile()
/**
* Checks if a file is readable.
*
* Addresses PHP bug related to reading files from network drives on Windows.
* e.g. when using WSL2.
*
* @param string $path The path to the file.
*
* @return boolean
*/
public static function isReadable($path)
{
if (@is_readable($path) === true) {
return true;
}
if (@file_exists($path) === true && @is_file($path) === true) {
$f = @fopen($path, 'rb');
if (fclose($f) === true) {
return true;
}
}
return false;
}//end isReadable()
/**
* CodeSniffer alternative for realpath.
*
* Allows for PHAR support.
*
* @param string $path The path to use.
*
* @return mixed
*/
public static function realpath($path)
{
// Support the path replacement of ~ with the user's home directory.
if (substr($path, 0, 2) === '~/') {
$homeDir = getenv('HOME');
if ($homeDir !== false) {
$path = $homeDir.substr($path, 1);
}
}
// Check for process substitution.
if (strpos($path, '/dev/fd') === 0) {
return str_replace('/dev/fd', 'php://fd', $path);
}
// No extra work needed if this is not a phar file.
if (self::isPharFile($path) === false) {
return realpath($path);
}
// Before trying to break down the file path,
// check if it exists first because it will mostly not
// change after running the below code.
if (file_exists($path) === true) {
return $path;
}
$phar = \Phar::running(false);
$extra = str_replace('phar://'.$phar, '', $path);
$path = realpath($phar);
if ($path === false) {
return false;
}
$path = 'phar://'.$path.$extra;
if (file_exists($path) === true) {
return $path;
}
return false;
}//end realpath()
/**
* Removes a base path from the front of a file path.
*
* @param string $path The path of the file.
* @param string $basepath The base path to remove. This should not end
* with a directory separator.
*
* @return string
*/
public static function stripBasepath($path, $basepath)
{
if (empty($basepath) === true) {
return $path;
}
$basepathLen = strlen($basepath);
if (substr($path, 0, $basepathLen) === $basepath) {
$path = substr($path, $basepathLen);
}
$path = ltrim($path, DIRECTORY_SEPARATOR);
if ($path === '') {
$path = '.';
}
return $path;
}//end stripBasepath()
/**
* Detects the EOL character being used in a string.
*
* @param string $contents The contents to check.
*
* @return string
*/
public static function detectLineEndings($contents)
{
if (preg_match("/\r\n?|\n/", $contents, $matches) !== 1) {
// Assume there are no newlines.
$eolChar = "\n";
} else {
$eolChar = $matches[0];
}
return $eolChar;
}//end detectLineEndings()
/**
* Check if STDIN is a TTY.
*
* @return boolean
*/
public static function isStdinATTY()
{
// The check is slow (especially calling `tty`) so we static
// cache the result.
static $isTTY = null;
if ($isTTY !== null) {
return $isTTY;
}
if (defined('STDIN') === false) {
return false;
}
// If PHP has the POSIX extensions we will use them.
if (function_exists('posix_isatty') === true) {
$isTTY = (posix_isatty(STDIN) === true);
return $isTTY;
}
// Next try is detecting whether we have `tty` installed and use that.
if (defined('PHP_WINDOWS_VERSION_PLATFORM') === true) {
$devnull = 'NUL';
$which = 'where';
} else {
$devnull = '/dev/null';
$which = 'which';
}
$tty = trim(shell_exec("$which tty 2> $devnull"));
if (empty($tty) === false) {
exec("tty -s 2> $devnull", $output, $returnValue);
$isTTY = ($returnValue === 0);
return $isTTY;
}
// Finally we will use fstat. The solution borrowed from
// https://stackoverflow.com/questions/11327367/detect-if-a-php-script-is-being-run-interactively-or-not
// This doesn't work on Mingw/Cygwin/... using Mintty but they
// have `tty` installed.
$type = [
'S_IFMT' => 0170000,
'S_IFIFO' => 0010000,
];
$stat = fstat(STDIN);
$mode = ($stat['mode'] & $type['S_IFMT']);
$isTTY = ($mode !== $type['S_IFIFO']);
return $isTTY;
}//end isStdinATTY()
/**
* Escape a path to a system command.
*
* @param string $cmd The path to the system command.
*
* @return string
*/
public static function escapeshellcmd($cmd)
{
$cmd = escapeshellcmd($cmd);
if (stripos(PHP_OS, 'WIN') === 0) {
// Spaces are not escaped by escapeshellcmd on Windows, but need to be
// for the command to be able to execute.
$cmd = preg_replace('`(?<!^) `', '^ ', $cmd);
}
return $cmd;
}//end escapeshellcmd()
/**
* Prepares token content for output to screen.
*
* Replaces invisible characters so they are visible. On non-Windows
* operating systems it will also colour the invisible characters.
*
* @param string $content The content to prepare.
* @param string[] $exclude A list of characters to leave invisible.
* Can contain \r, \n, \t and a space.
*
* @return string
*/
public static function prepareForOutput($content, $exclude=[])
{
if (stripos(PHP_OS, 'WIN') === 0) {
if (in_array("\r", $exclude, true) === false) {
$content = str_replace("\r", '\r', $content);
}
if (in_array("\n", $exclude, true) === false) {
$content = str_replace("\n", '\n', $content);
}
if (in_array("\t", $exclude, true) === false) {
$content = str_replace("\t", '\t', $content);
}
} else {
if (in_array("\r", $exclude, true) === false) {
$content = str_replace("\r", "\033[30;1m\\r\033[0m", $content);
}
if (in_array("\n", $exclude, true) === false) {
$content = str_replace("\n", "\033[30;1m\\n\033[0m", $content);
}
if (in_array("\t", $exclude, true) === false) {
$content = str_replace("\t", "\033[30;1m\\t\033[0m", $content);
}
if (in_array(' ', $exclude, true) === false) {
$content = str_replace(' ', "\033[30;1m·\033[0m", $content);
}
}//end if
return $content;
}//end prepareForOutput()
/**
* Returns true if the specified string is in the camel caps format.
*
* @param string $string The string the verify.
* @param boolean $classFormat If true, check to see if the string is in the
* class format. Class format strings must start
* with a capital letter and contain no
* underscores.
* @param boolean $public If true, the first character in the string
* must be an a-z character. If false, the
* character must be an underscore. This
* argument is only applicable if $classFormat
* is false.
* @param boolean $strict If true, the string must not have two capital
* letters next to each other. If false, a
* relaxed camel caps policy is used to allow
* for acronyms.
*
* @return boolean
*/
public static function isCamelCaps(
$string,
$classFormat=false,
$public=true,
$strict=true
) {
// Check the first character first.
if ($classFormat === false) {
$legalFirstChar = '';
if ($public === false) {
$legalFirstChar = '[_]';
}
if ($strict === false) {
// Can either start with a lowercase letter, or multiple uppercase
// in a row, representing an acronym.
$legalFirstChar .= '([A-Z]{2,}|[a-z])';
} else {
$legalFirstChar .= '[a-z]';
}
} else {
$legalFirstChar = '[A-Z]';
}
if (preg_match("/^$legalFirstChar/", $string) === 0) {
return false;
}
// Check that the name only contains legal characters.
$legalChars = 'a-zA-Z0-9';
if (preg_match("|[^$legalChars]|", substr($string, 1)) > 0) {
return false;
}
if ($strict === true) {
// Check that there are not two capital letters next to each other.
$length = strlen($string);
$lastCharWasCaps = $classFormat;
for ($i = 1; $i < $length; $i++) {
$ascii = ord($string[$i]);
if ($ascii >= 48 && $ascii <= 57) {
// The character is a number, so it can't be a capital.
$isCaps = false;
} else {
if (strtoupper($string[$i]) === $string[$i]) {
$isCaps = true;
} else {
$isCaps = false;
}
}
if ($isCaps === true && $lastCharWasCaps === true) {
return false;
}
$lastCharWasCaps = $isCaps;
}
}//end if
return true;
}//end isCamelCaps()
/**
* Returns true if the specified string is in the underscore caps format.
*
* @param string $string The string to verify.
*
* @return boolean
*/
public static function isUnderscoreName($string)
{
// If there are space in the name, it can't be valid.
if (strpos($string, ' ') !== false) {
return false;
}
$validName = true;
$nameBits = explode('_', $string);
if (preg_match('|^[A-Z]|', $string) === 0) {
// Name does not begin with a capital letter.
$validName = false;
} else {
foreach ($nameBits as $bit) {
if ($bit === '') {
continue;
}
if ($bit[0] !== strtoupper($bit[0])) {
$validName = false;
break;
}
}
}
return $validName;
}//end isUnderscoreName()
/**
* Returns a valid variable type for param/var tags.
*
* If type is not one of the standard types, it must be a custom type.
* Returns the correct type name suggestion if type name is invalid.
*
* @param string $varType The variable type to process.
*
* @return string
*/
public static function suggestType($varType)
{
if ($varType === '') {
return '';
}
if (in_array($varType, self::$allowedTypes, true) === true) {
return $varType;
} else {
$lowerVarType = strtolower($varType);
switch ($lowerVarType) {
case 'bool':
case 'boolean':
return 'boolean';
case 'double':
case 'real':
case 'float':
return 'float';
case 'int':
case 'integer':
return 'integer';
case 'array()':
case 'array':
return 'array';
}//end switch
if (strpos($lowerVarType, 'array(') !== false) {
// Valid array declaration:
// array, array(type), array(type1 => type2).
$matches = [];
$pattern = '/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i';
if (preg_match($pattern, $varType, $matches) !== 0) {
$type1 = '';
if (isset($matches[1]) === true) {
$type1 = $matches[1];
}
$type2 = '';
if (isset($matches[3]) === true) {
$type2 = $matches[3];
}
$type1 = self::suggestType($type1);
$type2 = self::suggestType($type2);
if ($type2 !== '') {
$type2 = ' => '.$type2;
}
return "array($type1$type2)";
} else {
return 'array';
}//end if
} else if (in_array($lowerVarType, self::$allowedTypes, true) === true) {
// A valid type, but not lower cased.
return $lowerVarType;
} else {
// Must be a custom type name.
return $varType;
}//end if
}//end if
}//end suggestType()
/**
* Given a sniff class name, returns the code for the sniff.
*
* @param string $sniffClass The fully qualified sniff class name.
*
* @return string
*/
public static function getSniffCode($sniffClass)
{
$parts = explode('\\', $sniffClass);
$sniff = array_pop($parts);
if (substr($sniff, -5) === 'Sniff') {
// Sniff class name.
$sniff = substr($sniff, 0, -5);
} else {
// Unit test class name.
$sniff = substr($sniff, 0, -8);
}
$category = array_pop($parts);
$sniffDir = array_pop($parts);
$standard = array_pop($parts);
$code = $standard.'.'.$category.'.'.$sniff;
return $code;
}//end getSniffCode()
/**
* Removes project-specific information from a sniff class name.
*
* @param string $sniffClass The fully qualified sniff class name.
*
* @return string
*/
public static function cleanSniffClass($sniffClass)
{
$newName = strtolower($sniffClass);
$sniffPos = strrpos($newName, '\sniffs\\');
if ($sniffPos === false) {
// Nothing we can do as it isn't in a known format.
return $newName;
}
$end = (strlen($newName) - $sniffPos + 1);
$start = strrpos($newName, '\\', ($end * -1));
if ($start === false) {
// Nothing needs to be cleaned.
return $newName;
}
$newName = substr($newName, ($start + 1));
return $newName;
}//end cleanSniffClass()
}//end class
@@ -0,0 +1,339 @@
<?php
/**
* Functions for helping process standards.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Util;
use PHP_CodeSniffer\Config;
class Standards
{
/**
* Get a list of paths where standards are installed.
*
* Unresolvable relative paths will be excluded from the results.
*
* @return array
*/
public static function getInstalledStandardPaths()
{
$ds = DIRECTORY_SEPARATOR;
$installedPaths = [dirname(dirname(__DIR__)).$ds.'src'.$ds.'Standards'];
$configPaths = Config::getConfigData('installed_paths');
if ($configPaths !== null) {
$installedPaths = array_merge($installedPaths, explode(',', $configPaths));
}
$resolvedInstalledPaths = [];
foreach ($installedPaths as $installedPath) {
if (substr($installedPath, 0, 1) === '.') {
$installedPath = Common::realPath(__DIR__.$ds.'..'.$ds.'..'.$ds.$installedPath);
if ($installedPath === false) {
continue;
}
}
$resolvedInstalledPaths[] = $installedPath;
}
return $resolvedInstalledPaths;
}//end getInstalledStandardPaths()
/**
* Get the details of all coding standards installed.
*
* Coding standards are directories located in the
* CodeSniffer/Standards directory. Valid coding standards
* include a Sniffs subdirectory.
*
* The details returned for each standard are:
* - path: the path to the coding standard's main directory
* - name: the name of the coding standard, as sourced from the ruleset.xml file
* - namespace: the namespace used by the coding standard, as sourced from the ruleset.xml file
*
* If you only need the paths to the installed standards,
* use getInstalledStandardPaths() instead as it performs less work to
* retrieve coding standard names.
*
* @param boolean $includeGeneric If true, the special "Generic"
* coding standard will be included
* if installed.
* @param string $standardsDir A specific directory to look for standards
* in. If not specified, PHP_CodeSniffer will
* look in its default locations.
*
* @return array
* @see getInstalledStandardPaths()
*/
public static function getInstalledStandardDetails(
$includeGeneric=false,
$standardsDir=''
) {
$rulesets = [];
if ($standardsDir === '') {
$installedPaths = self::getInstalledStandardPaths();
} else {
$installedPaths = [$standardsDir];
}
foreach ($installedPaths as $standardsDir) {
// Check if the installed dir is actually a standard itself.
$csFile = $standardsDir.'/ruleset.xml';
if (is_file($csFile) === true) {
$rulesets[] = $csFile;
continue;
}
if (is_dir($standardsDir) === false) {
continue;
}
$di = new \DirectoryIterator($standardsDir);
foreach ($di as $file) {
if ($file->isDir() === true && $file->isDot() === false) {
$filename = $file->getFilename();
// Ignore the special "Generic" standard.
if ($includeGeneric === false && $filename === 'Generic') {
continue;
}
// Valid coding standard dirs include a ruleset.
$csFile = $file->getPathname().'/ruleset.xml';
if (is_file($csFile) === true) {
$rulesets[] = $csFile;
}
}
}
}//end foreach
$installedStandards = [];
foreach ($rulesets as $rulesetPath) {
$ruleset = @simplexml_load_string(file_get_contents($rulesetPath));
if ($ruleset === false) {
continue;
}
$standardName = (string) $ruleset['name'];
$dirname = basename(dirname($rulesetPath));
if (isset($ruleset['namespace']) === true) {
$namespace = (string) $ruleset['namespace'];
} else {
$namespace = $dirname;
}
$installedStandards[$dirname] = [
'path' => dirname($rulesetPath),
'name' => $standardName,
'namespace' => $namespace,
];
}//end foreach
return $installedStandards;
}//end getInstalledStandardDetails()
/**
* Get a list of all coding standards installed.
*
* Coding standards are directories located in the
* CodeSniffer/Standards directory. Valid coding standards
* include a Sniffs subdirectory.
*
* @param boolean $includeGeneric If true, the special "Generic"
* coding standard will be included
* if installed.
* @param string $standardsDir A specific directory to look for standards
* in. If not specified, PHP_CodeSniffer will
* look in its default locations.
*
* @return array
* @see isInstalledStandard()
*/
public static function getInstalledStandards(
$includeGeneric=false,
$standardsDir=''
) {
$installedStandards = [];
if ($standardsDir === '') {
$installedPaths = self::getInstalledStandardPaths();
} else {
$installedPaths = [$standardsDir];
}
foreach ($installedPaths as $standardsDir) {
// Check if the installed dir is actually a standard itself.
$csFile = $standardsDir.'/ruleset.xml';
if (is_file($csFile) === true) {
$basename = basename($standardsDir);
$installedStandards[$basename] = $basename;
continue;
}
if (is_dir($standardsDir) === false) {
// Doesn't exist.
continue;
}
$di = new \DirectoryIterator($standardsDir);
$standardsInDir = [];
foreach ($di as $file) {
if ($file->isDir() === true && $file->isDot() === false) {
$filename = $file->getFilename();
// Ignore the special "Generic" standard.
if ($includeGeneric === false && $filename === 'Generic') {
continue;
}
// Valid coding standard dirs include a ruleset.
$csFile = $file->getPathname().'/ruleset.xml';
if (is_file($csFile) === true) {
$standardsInDir[$filename] = $filename;
}
}
}
natsort($standardsInDir);
$installedStandards += $standardsInDir;
}//end foreach
return $installedStandards;
}//end getInstalledStandards()
/**
* Determine if a standard is installed.
*
* Coding standards are directories located in the
* CodeSniffer/Standards directory. Valid coding standards
* include a ruleset.xml file.
*
* @param string $standard The name of the coding standard.
*
* @return boolean
* @see getInstalledStandards()
*/
public static function isInstalledStandard($standard)
{
$path = self::getInstalledStandardPath($standard);
if ($path !== null && strpos($path, 'ruleset.xml') !== false) {
return true;
} else {
// This could be a custom standard, installed outside our
// standards directory.
$standard = Common::realPath($standard);
if ($standard === false) {
return false;
}
// Might be an actual ruleset file itUtil.
// If it has an XML extension, let's at least try it.
if (is_file($standard) === true
&& (substr(strtolower($standard), -4) === '.xml'
|| substr(strtolower($standard), -9) === '.xml.dist')
) {
return true;
}
// If it is a directory with a ruleset.xml file in it,
// it is a standard.
$ruleset = rtrim($standard, ' /\\').DIRECTORY_SEPARATOR.'ruleset.xml';
if (is_file($ruleset) === true) {
return true;
}
}//end if
return false;
}//end isInstalledStandard()
/**
* Return the path of an installed coding standard.
*
* Coding standards are directories located in the
* CodeSniffer/Standards directory. Valid coding standards
* include a ruleset.xml file.
*
* @param string $standard The name of the coding standard.
*
* @return string|null
*/
public static function getInstalledStandardPath($standard)
{
if (strpos($standard, '.') !== false) {
return null;
}
$installedPaths = self::getInstalledStandardPaths();
foreach ($installedPaths as $installedPath) {
$standardPath = $installedPath.DIRECTORY_SEPARATOR.$standard;
if (file_exists($standardPath) === false) {
if (basename($installedPath) !== $standard) {
continue;
}
$standardPath = $installedPath;
}
$path = Common::realpath($standardPath.DIRECTORY_SEPARATOR.'ruleset.xml');
if ($path !== false && is_file($path) === true) {
return $path;
} else if (Common::isPharFile($standardPath) === true) {
$path = Common::realpath($standardPath);
if ($path !== false) {
return $path;
}
}
}//end foreach
return null;
}//end getInstalledStandardPath()
/**
* Prints out a list of installed coding standards.
*
* @return void
*/
public static function printInstalledStandards()
{
$installedStandards = self::getInstalledStandards();
$numStandards = count($installedStandards);
if ($numStandards === 0) {
echo 'No coding standards are installed.'.PHP_EOL;
} else {
$lastStandard = array_pop($installedStandards);
if ($numStandards === 1) {
echo "The only coding standard installed is $lastStandard".PHP_EOL;
} else {
$standardList = implode(', ', $installedStandards);
$standardList .= ' and '.$lastStandard;
echo 'The installed coding standards are '.$standardList.PHP_EOL;
}
}
}//end printInstalledStandards()
}//end class
@@ -0,0 +1,86 @@
<?php
/**
* Timing functions for the run.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Util;
class Timing
{
/**
* The start time of the run.
*
* @var float
*/
private static $startTime;
/**
* Used to make sure we only print the run time once per run.
*
* @var boolean
*/
private static $printed = false;
/**
* Start recording time for the run.
*
* @return void
*/
public static function startTiming()
{
self::$startTime = microtime(true);
}//end startTiming()
/**
* Print information about the run.
*
* @param boolean $force If TRUE, prints the output even if it has
* already been printed during the run.
*
* @return void
*/
public static function printRunTime($force=false)
{
if ($force === false && self::$printed === true) {
// A double call.
return;
}
if (self::$startTime === null) {
// Timing was never started.
return;
}
$time = ((microtime(true) - self::$startTime) * 1000);
if ($time > 60000) {
$mins = floor($time / 60000);
$secs = round((fmod($time, 60000) / 1000), 2);
$time = $mins.' mins';
if ($secs !== 0) {
$time .= ", $secs secs";
}
} else if ($time > 1000) {
$time = round(($time / 1000), 2).' secs';
} else {
$time = round($time).'ms';
}
$mem = round((memory_get_peak_usage(true) / (1024 * 1024)), 2).'MB';
echo "Time: $time; Memory: $mem".PHP_EOL.PHP_EOL;
self::$printed = true;
}//end printRunTime()
}//end class
@@ -0,0 +1,810 @@
<?php
/**
* Stores weightings and groupings of tokens.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Util;
define('T_NONE', 'PHPCS_T_NONE');
define('T_OPEN_CURLY_BRACKET', 'PHPCS_T_OPEN_CURLY_BRACKET');
define('T_CLOSE_CURLY_BRACKET', 'PHPCS_T_CLOSE_CURLY_BRACKET');
define('T_OPEN_SQUARE_BRACKET', 'PHPCS_T_OPEN_SQUARE_BRACKET');
define('T_CLOSE_SQUARE_BRACKET', 'PHPCS_T_CLOSE_SQUARE_BRACKET');
define('T_OPEN_PARENTHESIS', 'PHPCS_T_OPEN_PARENTHESIS');
define('T_CLOSE_PARENTHESIS', 'PHPCS_T_CLOSE_PARENTHESIS');
define('T_COLON', 'PHPCS_T_COLON');
define('T_NULLABLE', 'PHPCS_T_NULLABLE');
define('T_STRING_CONCAT', 'PHPCS_T_STRING_CONCAT');
define('T_INLINE_THEN', 'PHPCS_T_INLINE_THEN');
define('T_INLINE_ELSE', 'PHPCS_T_INLINE_ELSE');
define('T_NULL', 'PHPCS_T_NULL');
define('T_FALSE', 'PHPCS_T_FALSE');
define('T_TRUE', 'PHPCS_T_TRUE');
define('T_SEMICOLON', 'PHPCS_T_SEMICOLON');
define('T_EQUAL', 'PHPCS_T_EQUAL');
define('T_MULTIPLY', 'PHPCS_T_MULTIPLY');
define('T_DIVIDE', 'PHPCS_T_DIVIDE');
define('T_PLUS', 'PHPCS_T_PLUS');
define('T_MINUS', 'PHPCS_T_MINUS');
define('T_MODULUS', 'PHPCS_T_MODULUS');
define('T_BITWISE_AND', 'PHPCS_T_BITWISE_AND');
define('T_BITWISE_OR', 'PHPCS_T_BITWISE_OR');
define('T_BITWISE_XOR', 'PHPCS_T_BITWISE_XOR');
define('T_BITWISE_NOT', 'PHPCS_T_BITWISE_NOT');
define('T_ARRAY_HINT', 'PHPCS_T_ARRAY_HINT');
define('T_GREATER_THAN', 'PHPCS_T_GREATER_THAN');
define('T_LESS_THAN', 'PHPCS_T_LESS_THAN');
define('T_BOOLEAN_NOT', 'PHPCS_T_BOOLEAN_NOT');
define('T_SELF', 'PHPCS_T_SELF');
define('T_PARENT', 'PHPCS_T_PARENT');
define('T_DOUBLE_QUOTED_STRING', 'PHPCS_T_DOUBLE_QUOTED_STRING');
define('T_COMMA', 'PHPCS_T_COMMA');
define('T_HEREDOC', 'PHPCS_T_HEREDOC');
define('T_PROTOTYPE', 'PHPCS_T_PROTOTYPE');
define('T_THIS', 'PHPCS_T_THIS');
define('T_REGULAR_EXPRESSION', 'PHPCS_T_REGULAR_EXPRESSION');
define('T_PROPERTY', 'PHPCS_T_PROPERTY');
define('T_LABEL', 'PHPCS_T_LABEL');
define('T_OBJECT', 'PHPCS_T_OBJECT');
define('T_CLOSE_OBJECT', 'PHPCS_T_CLOSE_OBJECT');
define('T_COLOUR', 'PHPCS_T_COLOUR');
define('T_HASH', 'PHPCS_T_HASH');
define('T_URL', 'PHPCS_T_URL');
define('T_STYLE', 'PHPCS_T_STYLE');
define('T_ASPERAND', 'PHPCS_T_ASPERAND');
define('T_DOLLAR', 'PHPCS_T_DOLLAR');
define('T_TYPEOF', 'PHPCS_T_TYPEOF');
define('T_CLOSURE', 'PHPCS_T_CLOSURE');
define('T_ANON_CLASS', 'PHPCS_T_ANON_CLASS');
define('T_BACKTICK', 'PHPCS_T_BACKTICK');
define('T_START_NOWDOC', 'PHPCS_T_START_NOWDOC');
define('T_NOWDOC', 'PHPCS_T_NOWDOC');
define('T_END_NOWDOC', 'PHPCS_T_END_NOWDOC');
define('T_OPEN_SHORT_ARRAY', 'PHPCS_T_OPEN_SHORT_ARRAY');
define('T_CLOSE_SHORT_ARRAY', 'PHPCS_T_CLOSE_SHORT_ARRAY');
define('T_GOTO_LABEL', 'PHPCS_T_GOTO_LABEL');
define('T_BINARY_CAST', 'PHPCS_T_BINARY_CAST');
define('T_EMBEDDED_PHP', 'PHPCS_T_EMBEDDED_PHP');
define('T_RETURN_TYPE', 'PHPCS_T_RETURN_TYPE');
define('T_OPEN_USE_GROUP', 'PHPCS_T_OPEN_USE_GROUP');
define('T_CLOSE_USE_GROUP', 'PHPCS_T_CLOSE_USE_GROUP');
define('T_ZSR', 'PHPCS_T_ZSR');
define('T_ZSR_EQUAL', 'PHPCS_T_ZSR_EQUAL');
define('T_FN_ARROW', 'PHPCS_T_FN_ARROW');
define('T_TYPE_UNION', 'PHPCS_T_TYPE_UNION');
define('T_PARAM_NAME', 'PHPCS_T_PARAM_NAME');
define('T_MATCH_ARROW', 'PHPCS_T_MATCH_ARROW');
define('T_MATCH_DEFAULT', 'PHPCS_T_MATCH_DEFAULT');
define('T_ATTRIBUTE_END', 'PHPCS_T_ATTRIBUTE_END');
define('T_ENUM_CASE', 'PHPCS_T_ENUM_CASE');
define('T_TYPE_INTERSECTION', 'PHPCS_T_TYPE_INTERSECTION');
// Some PHP 5.5 tokens, replicated for lower versions.
if (defined('T_FINALLY') === false) {
define('T_FINALLY', 'PHPCS_T_FINALLY');
}
if (defined('T_YIELD') === false) {
define('T_YIELD', 'PHPCS_T_YIELD');
}
// Some PHP 5.6 tokens, replicated for lower versions.
if (defined('T_ELLIPSIS') === false) {
define('T_ELLIPSIS', 'PHPCS_T_ELLIPSIS');
}
if (defined('T_POW') === false) {
define('T_POW', 'PHPCS_T_POW');
}
if (defined('T_POW_EQUAL') === false) {
define('T_POW_EQUAL', 'PHPCS_T_POW_EQUAL');
}
// Some PHP 7 tokens, replicated for lower versions.
if (defined('T_SPACESHIP') === false) {
define('T_SPACESHIP', 'PHPCS_T_SPACESHIP');
}
if (defined('T_COALESCE') === false) {
define('T_COALESCE', 'PHPCS_T_COALESCE');
}
if (defined('T_COALESCE_EQUAL') === false) {
define('T_COALESCE_EQUAL', 'PHPCS_T_COALESCE_EQUAL');
}
if (defined('T_YIELD_FROM') === false) {
define('T_YIELD_FROM', 'PHPCS_T_YIELD_FROM');
}
// Some PHP 7.4 tokens, replicated for lower versions.
if (defined('T_BAD_CHARACTER') === false) {
define('T_BAD_CHARACTER', 'PHPCS_T_BAD_CHARACTER');
}
if (defined('T_FN') === false) {
define('T_FN', 'PHPCS_T_FN');
}
// Some PHP 8.0 tokens, replicated for lower versions.
if (defined('T_NULLSAFE_OBJECT_OPERATOR') === false) {
define('T_NULLSAFE_OBJECT_OPERATOR', 'PHPCS_T_NULLSAFE_OBJECT_OPERATOR');
}
if (defined('T_NAME_QUALIFIED') === false) {
define('T_NAME_QUALIFIED', 'PHPCS_T_NAME_QUALIFIED');
}
if (defined('T_NAME_FULLY_QUALIFIED') === false) {
define('T_NAME_FULLY_QUALIFIED', 'PHPCS_T_NAME_FULLY_QUALIFIED');
}
if (defined('T_NAME_RELATIVE') === false) {
define('T_NAME_RELATIVE', 'PHPCS_T_NAME_RELATIVE');
}
if (defined('T_MATCH') === false) {
define('T_MATCH', 'PHPCS_T_MATCH');
}
if (defined('T_ATTRIBUTE') === false) {
define('T_ATTRIBUTE', 'PHPCS_T_ATTRIBUTE');
}
// Some PHP 8.1 tokens, replicated for lower versions.
if (defined('T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG') === false) {
define('T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG', 'PHPCS_T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG');
}
if (defined('T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG') === false) {
define('T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG', 'PHPCS_T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG');
}
if (defined('T_READONLY') === false) {
define('T_READONLY', 'PHPCS_T_READONLY');
}
if (defined('T_ENUM') === false) {
define('T_ENUM', 'PHPCS_T_ENUM');
}
// Tokens used for parsing doc blocks.
define('T_DOC_COMMENT_STAR', 'PHPCS_T_DOC_COMMENT_STAR');
define('T_DOC_COMMENT_WHITESPACE', 'PHPCS_T_DOC_COMMENT_WHITESPACE');
define('T_DOC_COMMENT_TAG', 'PHPCS_T_DOC_COMMENT_TAG');
define('T_DOC_COMMENT_OPEN_TAG', 'PHPCS_T_DOC_COMMENT_OPEN_TAG');
define('T_DOC_COMMENT_CLOSE_TAG', 'PHPCS_T_DOC_COMMENT_CLOSE_TAG');
define('T_DOC_COMMENT_STRING', 'PHPCS_T_DOC_COMMENT_STRING');
// Tokens used for PHPCS instruction comments.
define('T_PHPCS_ENABLE', 'PHPCS_T_PHPCS_ENABLE');
define('T_PHPCS_DISABLE', 'PHPCS_T_PHPCS_DISABLE');
define('T_PHPCS_SET', 'PHPCS_T_PHPCS_SET');
define('T_PHPCS_IGNORE', 'PHPCS_T_PHPCS_IGNORE');
define('T_PHPCS_IGNORE_FILE', 'PHPCS_T_PHPCS_IGNORE_FILE');
final class Tokens
{
/**
* The token weightings.
*
* @var array<int|string, int>
*/
public static $weightings = [
T_CLASS => 1000,
T_INTERFACE => 1000,
T_TRAIT => 1000,
T_ENUM => 1000,
T_NAMESPACE => 1000,
T_FUNCTION => 100,
T_CLOSURE => 100,
/*
* Conditions.
*/
T_WHILE => 50,
T_FOR => 50,
T_FOREACH => 50,
T_IF => 50,
T_ELSE => 50,
T_ELSEIF => 50,
T_DO => 50,
T_TRY => 50,
T_CATCH => 50,
T_FINALLY => 50,
T_SWITCH => 50,
T_MATCH => 50,
T_SELF => 25,
T_PARENT => 25,
/*
* Operators and arithmetic.
*/
T_BITWISE_AND => 8,
T_BITWISE_OR => 8,
T_BITWISE_XOR => 8,
T_MULTIPLY => 5,
T_DIVIDE => 5,
T_PLUS => 5,
T_MINUS => 5,
T_MODULUS => 5,
T_POW => 5,
T_SPACESHIP => 5,
T_COALESCE => 5,
T_COALESCE_EQUAL => 5,
T_SL => 5,
T_SR => 5,
T_SL_EQUAL => 5,
T_SR_EQUAL => 5,
T_EQUAL => 5,
T_AND_EQUAL => 5,
T_CONCAT_EQUAL => 5,
T_DIV_EQUAL => 5,
T_MINUS_EQUAL => 5,
T_MOD_EQUAL => 5,
T_MUL_EQUAL => 5,
T_OR_EQUAL => 5,
T_PLUS_EQUAL => 5,
T_XOR_EQUAL => 5,
T_BOOLEAN_AND => 5,
T_BOOLEAN_OR => 5,
/*
* Equality.
*/
T_IS_EQUAL => 5,
T_IS_NOT_EQUAL => 5,
T_IS_IDENTICAL => 5,
T_IS_NOT_IDENTICAL => 5,
T_IS_SMALLER_OR_EQUAL => 5,
T_IS_GREATER_OR_EQUAL => 5,
];
/**
* Tokens that represent assignments.
*
* @var array<int|string, int|string>
*/
public static $assignmentTokens = [
T_EQUAL => T_EQUAL,
T_AND_EQUAL => T_AND_EQUAL,
T_OR_EQUAL => T_OR_EQUAL,
T_CONCAT_EQUAL => T_CONCAT_EQUAL,
T_DIV_EQUAL => T_DIV_EQUAL,
T_MINUS_EQUAL => T_MINUS_EQUAL,
T_POW_EQUAL => T_POW_EQUAL,
T_MOD_EQUAL => T_MOD_EQUAL,
T_MUL_EQUAL => T_MUL_EQUAL,
T_PLUS_EQUAL => T_PLUS_EQUAL,
T_XOR_EQUAL => T_XOR_EQUAL,
T_DOUBLE_ARROW => T_DOUBLE_ARROW,
T_SL_EQUAL => T_SL_EQUAL,
T_SR_EQUAL => T_SR_EQUAL,
T_COALESCE_EQUAL => T_COALESCE_EQUAL,
T_ZSR_EQUAL => T_ZSR_EQUAL,
];
/**
* Tokens that represent equality comparisons.
*
* @var array<int|string, int|string>
*/
public static $equalityTokens = [
T_IS_EQUAL => T_IS_EQUAL,
T_IS_NOT_EQUAL => T_IS_NOT_EQUAL,
T_IS_IDENTICAL => T_IS_IDENTICAL,
T_IS_NOT_IDENTICAL => T_IS_NOT_IDENTICAL,
T_IS_SMALLER_OR_EQUAL => T_IS_SMALLER_OR_EQUAL,
T_IS_GREATER_OR_EQUAL => T_IS_GREATER_OR_EQUAL,
];
/**
* Tokens that represent comparison operator.
*
* @var array<int|string, int|string>
*/
public static $comparisonTokens = [
T_IS_EQUAL => T_IS_EQUAL,
T_IS_IDENTICAL => T_IS_IDENTICAL,
T_IS_NOT_EQUAL => T_IS_NOT_EQUAL,
T_IS_NOT_IDENTICAL => T_IS_NOT_IDENTICAL,
T_LESS_THAN => T_LESS_THAN,
T_GREATER_THAN => T_GREATER_THAN,
T_IS_SMALLER_OR_EQUAL => T_IS_SMALLER_OR_EQUAL,
T_IS_GREATER_OR_EQUAL => T_IS_GREATER_OR_EQUAL,
T_SPACESHIP => T_SPACESHIP,
T_COALESCE => T_COALESCE,
];
/**
* Tokens that represent arithmetic operators.
*
* @var array<int|string, int|string>
*/
public static $arithmeticTokens = [
T_PLUS => T_PLUS,
T_MINUS => T_MINUS,
T_MULTIPLY => T_MULTIPLY,
T_DIVIDE => T_DIVIDE,
T_MODULUS => T_MODULUS,
T_POW => T_POW,
];
/**
* Tokens that perform operations.
*
* @var array<int|string, int|string>
*/
public static $operators = [
T_MINUS => T_MINUS,
T_PLUS => T_PLUS,
T_MULTIPLY => T_MULTIPLY,
T_DIVIDE => T_DIVIDE,
T_MODULUS => T_MODULUS,
T_POW => T_POW,
T_SPACESHIP => T_SPACESHIP,
T_COALESCE => T_COALESCE,
T_BITWISE_AND => T_BITWISE_AND,
T_BITWISE_OR => T_BITWISE_OR,
T_BITWISE_XOR => T_BITWISE_XOR,
T_SL => T_SL,
T_SR => T_SR,
];
/**
* Tokens that perform boolean operations.
*
* @var array<int|string, int|string>
*/
public static $booleanOperators = [
T_BOOLEAN_AND => T_BOOLEAN_AND,
T_BOOLEAN_OR => T_BOOLEAN_OR,
T_LOGICAL_AND => T_LOGICAL_AND,
T_LOGICAL_OR => T_LOGICAL_OR,
T_LOGICAL_XOR => T_LOGICAL_XOR,
];
/**
* Tokens that represent casting.
*
* @var array<int|string, int|string>
*/
public static $castTokens = [
T_INT_CAST => T_INT_CAST,
T_STRING_CAST => T_STRING_CAST,
T_DOUBLE_CAST => T_DOUBLE_CAST,
T_ARRAY_CAST => T_ARRAY_CAST,
T_BOOL_CAST => T_BOOL_CAST,
T_OBJECT_CAST => T_OBJECT_CAST,
T_UNSET_CAST => T_UNSET_CAST,
T_BINARY_CAST => T_BINARY_CAST,
];
/**
* Token types that open parenthesis.
*
* @var array<int|string, int|string>
*/
public static $parenthesisOpeners = [
T_ARRAY => T_ARRAY,
T_LIST => T_LIST,
T_FUNCTION => T_FUNCTION,
T_CLOSURE => T_CLOSURE,
T_ANON_CLASS => T_ANON_CLASS,
T_WHILE => T_WHILE,
T_FOR => T_FOR,
T_FOREACH => T_FOREACH,
T_SWITCH => T_SWITCH,
T_IF => T_IF,
T_ELSEIF => T_ELSEIF,
T_CATCH => T_CATCH,
T_DECLARE => T_DECLARE,
T_MATCH => T_MATCH,
];
/**
* Tokens that are allowed to open scopes.
*
* @var array<int|string, int|string>
*/
public static $scopeOpeners = [
T_CLASS => T_CLASS,
T_ANON_CLASS => T_ANON_CLASS,
T_INTERFACE => T_INTERFACE,
T_TRAIT => T_TRAIT,
T_ENUM => T_ENUM,
T_NAMESPACE => T_NAMESPACE,
T_FUNCTION => T_FUNCTION,
T_CLOSURE => T_CLOSURE,
T_IF => T_IF,
T_SWITCH => T_SWITCH,
T_CASE => T_CASE,
T_DECLARE => T_DECLARE,
T_DEFAULT => T_DEFAULT,
T_WHILE => T_WHILE,
T_ELSE => T_ELSE,
T_ELSEIF => T_ELSEIF,
T_FOR => T_FOR,
T_FOREACH => T_FOREACH,
T_DO => T_DO,
T_TRY => T_TRY,
T_CATCH => T_CATCH,
T_FINALLY => T_FINALLY,
T_PROPERTY => T_PROPERTY,
T_OBJECT => T_OBJECT,
T_USE => T_USE,
T_MATCH => T_MATCH,
];
/**
* Tokens that represent scope modifiers.
*
* @var array<int|string, int|string>
*/
public static $scopeModifiers = [
T_PRIVATE => T_PRIVATE,
T_PUBLIC => T_PUBLIC,
T_PROTECTED => T_PROTECTED,
];
/**
* Tokens that can prefix a method name
*
* @var array<int|string, int|string>
*/
public static $methodPrefixes = [
T_PRIVATE => T_PRIVATE,
T_PUBLIC => T_PUBLIC,
T_PROTECTED => T_PROTECTED,
T_ABSTRACT => T_ABSTRACT,
T_STATIC => T_STATIC,
T_FINAL => T_FINAL,
];
/**
* Tokens that open code blocks.
*
* @var array<int|string, int|string>
*/
public static $blockOpeners = [
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
T_OPEN_SQUARE_BRACKET => T_OPEN_SQUARE_BRACKET,
T_OPEN_PARENTHESIS => T_OPEN_PARENTHESIS,
T_OBJECT => T_OBJECT,
];
/**
* Tokens that don't represent code.
*
* @var array<int|string, int|string>
*/
public static $emptyTokens = [
T_WHITESPACE => T_WHITESPACE,
T_COMMENT => T_COMMENT,
T_DOC_COMMENT => T_DOC_COMMENT,
T_DOC_COMMENT_STAR => T_DOC_COMMENT_STAR,
T_DOC_COMMENT_WHITESPACE => T_DOC_COMMENT_WHITESPACE,
T_DOC_COMMENT_TAG => T_DOC_COMMENT_TAG,
T_DOC_COMMENT_OPEN_TAG => T_DOC_COMMENT_OPEN_TAG,
T_DOC_COMMENT_CLOSE_TAG => T_DOC_COMMENT_CLOSE_TAG,
T_DOC_COMMENT_STRING => T_DOC_COMMENT_STRING,
T_PHPCS_ENABLE => T_PHPCS_ENABLE,
T_PHPCS_DISABLE => T_PHPCS_DISABLE,
T_PHPCS_SET => T_PHPCS_SET,
T_PHPCS_IGNORE => T_PHPCS_IGNORE,
T_PHPCS_IGNORE_FILE => T_PHPCS_IGNORE_FILE,
];
/**
* Tokens that are comments.
*
* @var array<int|string, int|string>
*/
public static $commentTokens = [
T_COMMENT => T_COMMENT,
T_DOC_COMMENT => T_DOC_COMMENT,
T_DOC_COMMENT_STAR => T_DOC_COMMENT_STAR,
T_DOC_COMMENT_WHITESPACE => T_DOC_COMMENT_WHITESPACE,
T_DOC_COMMENT_TAG => T_DOC_COMMENT_TAG,
T_DOC_COMMENT_OPEN_TAG => T_DOC_COMMENT_OPEN_TAG,
T_DOC_COMMENT_CLOSE_TAG => T_DOC_COMMENT_CLOSE_TAG,
T_DOC_COMMENT_STRING => T_DOC_COMMENT_STRING,
T_PHPCS_ENABLE => T_PHPCS_ENABLE,
T_PHPCS_DISABLE => T_PHPCS_DISABLE,
T_PHPCS_SET => T_PHPCS_SET,
T_PHPCS_IGNORE => T_PHPCS_IGNORE,
T_PHPCS_IGNORE_FILE => T_PHPCS_IGNORE_FILE,
];
/**
* Tokens that are comments containing PHPCS instructions.
*
* @var array<int|string, int|string>
*/
public static $phpcsCommentTokens = [
T_PHPCS_ENABLE => T_PHPCS_ENABLE,
T_PHPCS_DISABLE => T_PHPCS_DISABLE,
T_PHPCS_SET => T_PHPCS_SET,
T_PHPCS_IGNORE => T_PHPCS_IGNORE,
T_PHPCS_IGNORE_FILE => T_PHPCS_IGNORE_FILE,
];
/**
* Tokens that represent strings.
*
* Note that T_STRINGS are NOT represented in this list.
*
* @var array<int|string, int|string>
*/
public static $stringTokens = [
T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING,
];
/**
* Tokens that represent text strings.
*
* @var array<int|string, int|string>
*/
public static $textStringTokens = [
T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING,
T_INLINE_HTML => T_INLINE_HTML,
T_HEREDOC => T_HEREDOC,
T_NOWDOC => T_NOWDOC,
];
/**
* Tokens that represent brackets and parenthesis.
*
* @var array<int|string, int|string>
*/
public static $bracketTokens = [
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
T_OPEN_SQUARE_BRACKET => T_OPEN_SQUARE_BRACKET,
T_CLOSE_SQUARE_BRACKET => T_CLOSE_SQUARE_BRACKET,
T_OPEN_PARENTHESIS => T_OPEN_PARENTHESIS,
T_CLOSE_PARENTHESIS => T_CLOSE_PARENTHESIS,
];
/**
* Tokens that include files.
*
* @var array<int|string, int|string>
*/
public static $includeTokens = [
T_REQUIRE_ONCE => T_REQUIRE_ONCE,
T_REQUIRE => T_REQUIRE,
T_INCLUDE_ONCE => T_INCLUDE_ONCE,
T_INCLUDE => T_INCLUDE,
];
/**
* Tokens that make up a heredoc string.
*
* @var array<int|string, int|string>
*/
public static $heredocTokens = [
T_START_HEREDOC => T_START_HEREDOC,
T_END_HEREDOC => T_END_HEREDOC,
T_HEREDOC => T_HEREDOC,
T_START_NOWDOC => T_START_NOWDOC,
T_END_NOWDOC => T_END_NOWDOC,
T_NOWDOC => T_NOWDOC,
];
/**
* Tokens that represent the names of called functions.
*
* Mostly, these are just strings. But PHP tokenizes some language
* constructs and functions using their own tokens.
*
* @var array<int|string, int|string>
*/
public static $functionNameTokens = [
T_STRING => T_STRING,
T_EVAL => T_EVAL,
T_EXIT => T_EXIT,
T_INCLUDE => T_INCLUDE,
T_INCLUDE_ONCE => T_INCLUDE_ONCE,
T_REQUIRE => T_REQUIRE,
T_REQUIRE_ONCE => T_REQUIRE_ONCE,
T_ISSET => T_ISSET,
T_UNSET => T_UNSET,
T_EMPTY => T_EMPTY,
T_SELF => T_SELF,
T_PARENT => T_PARENT,
T_STATIC => T_STATIC,
];
/**
* Tokens that open class and object scopes.
*
* @var array<int|string, int|string>
*/
public static $ooScopeTokens = [
T_CLASS => T_CLASS,
T_ANON_CLASS => T_ANON_CLASS,
T_INTERFACE => T_INTERFACE,
T_TRAIT => T_TRAIT,
T_ENUM => T_ENUM,
];
/**
* Tokens representing PHP magic constants.
*
* @var array <int|string> => <int|string>
*
* @link https://www.php.net/language.constants.predefined PHP Manual on magic constants
*/
public static $magicConstants = [
T_CLASS_C => T_CLASS_C,
T_DIR => T_DIR,
T_FILE => T_FILE,
T_FUNC_C => T_FUNC_C,
T_LINE => T_LINE,
T_METHOD_C => T_METHOD_C,
T_NS_C => T_NS_C,
T_TRAIT_C => T_TRAIT_C,
];
/**
* Tokens representing context sensitive keywords in PHP.
*
* @var array<int|string, int|string>
*
* https://wiki.php.net/rfc/context_sensitive_lexer
*/
public static $contextSensitiveKeywords = [
T_ABSTRACT => T_ABSTRACT,
T_ARRAY => T_ARRAY,
T_AS => T_AS,
T_BREAK => T_BREAK,
T_CALLABLE => T_CALLABLE,
T_CASE => T_CASE,
T_CATCH => T_CATCH,
T_CLASS => T_CLASS,
T_CLONE => T_CLONE,
T_CONST => T_CONST,
T_CONTINUE => T_CONTINUE,
T_DECLARE => T_DECLARE,
T_DEFAULT => T_DEFAULT,
T_DO => T_DO,
T_ECHO => T_ECHO,
T_ELSE => T_ELSE,
T_ELSEIF => T_ELSEIF,
T_EMPTY => T_EMPTY,
T_ENDDECLARE => T_ENDDECLARE,
T_ENDFOR => T_ENDFOR,
T_ENDFOREACH => T_ENDFOREACH,
T_ENDIF => T_ENDIF,
T_ENDSWITCH => T_ENDSWITCH,
T_ENDWHILE => T_ENDWHILE,
T_ENUM => T_ENUM,
T_EVAL => T_EVAL,
T_EXIT => T_EXIT,
T_EXTENDS => T_EXTENDS,
T_FINAL => T_FINAL,
T_FINALLY => T_FINALLY,
T_FN => T_FN,
T_FOR => T_FOR,
T_FOREACH => T_FOREACH,
T_FUNCTION => T_FUNCTION,
T_GLOBAL => T_GLOBAL,
T_GOTO => T_GOTO,
T_IF => T_IF,
T_IMPLEMENTS => T_IMPLEMENTS,
T_INCLUDE => T_INCLUDE,
T_INCLUDE_ONCE => T_INCLUDE_ONCE,
T_INSTANCEOF => T_INSTANCEOF,
T_INSTEADOF => T_INSTEADOF,
T_INTERFACE => T_INTERFACE,
T_ISSET => T_ISSET,
T_LIST => T_LIST,
T_LOGICAL_AND => T_LOGICAL_AND,
T_LOGICAL_OR => T_LOGICAL_OR,
T_LOGICAL_XOR => T_LOGICAL_XOR,
T_MATCH => T_MATCH,
T_NAMESPACE => T_NAMESPACE,
T_NEW => T_NEW,
T_PRINT => T_PRINT,
T_PRIVATE => T_PRIVATE,
T_PROTECTED => T_PROTECTED,
T_PUBLIC => T_PUBLIC,
T_READONLY => T_READONLY,
T_REQUIRE => T_REQUIRE,
T_REQUIRE_ONCE => T_REQUIRE_ONCE,
T_RETURN => T_RETURN,
T_STATIC => T_STATIC,
T_SWITCH => T_SWITCH,
T_THROW => T_THROW,
T_TRAIT => T_TRAIT,
T_TRY => T_TRY,
T_UNSET => T_UNSET,
T_USE => T_USE,
T_VAR => T_VAR,
T_WHILE => T_WHILE,
T_YIELD => T_YIELD,
T_YIELD_FROM => T_YIELD_FROM,
];
/**
* Given a token, returns the name of the token.
*
* If passed an integer, the token name is sourced from PHP's token_name()
* function. If passed a string, it is assumed to be a PHPCS-supplied token
* that begins with PHPCS_T_, so the name is sourced from the token value itself.
*
* @param int|string $token The token to get the name for.
*
* @return string
*/
public static function tokenName($token)
{
if (is_string($token) === false) {
// PHP-supplied token name.
return token_name($token);
}
return substr($token, 6);
}//end tokenName()
/**
* Returns the highest weighted token type.
*
* Tokens are weighted by their approximate frequency of appearance in code
* - the less frequently they appear in the code, the higher the weighting.
* For example T_CLASS tokens appear very infrequently in a file, and
* therefore have a high weighting.
*
* Returns false if there are no weightings for any of the specified tokens.
*
* @param array<int|string> $tokens The token types to get the highest weighted
* type for.
*
* @return int|false The highest weighted token.
*/
public static function getHighestWeightedToken(array $tokens)
{
$highest = -1;
$highestType = false;
$weights = self::$weightings;
foreach ($tokens as $token) {
if (isset($weights[$token]) === true) {
$weight = $weights[$token];
} else {
$weight = 0;
}
if ($weight > $highest) {
$highest = $weight;
$highestType = $token;
}
}
return $highestType;
}//end getHighestWeightedToken()
}//end class