芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/xmintal-back/vendor/phpunit/phpunit/src/Util/Configuration.php
* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Util; use const DIRECTORY_SEPARATOR; use const PATH_SEPARATOR; use const PHP_VERSION; use function assert; use function constant; use function count; use function define; use function defined; use function dirname; use function explode; use function file_exists; use function file_get_contents; use function getenv; use function implode; use function in_array; use function ini_get; use function ini_set; use function is_numeric; use function libxml_clear_errors; use function libxml_get_errors; use function libxml_use_internal_errors; use function preg_match; use function putenv; use function realpath; use function sprintf; use function stream_resolve_include_path; use function strlen; use function strpos; use function strtolower; use function strtoupper; use function substr; use function trim; use function version_compare; use DOMDocument; use DOMElement; use DOMNode; use DOMNodeList; use DOMXPath; use LibXMLError; use PHPUnit\Framework\Exception; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\TextUI\ResultPrinter; use PHPUnit\Util\TestDox\CliTestDoxPrinter; use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Configuration { /** * @var self[] */ private static $instances = []; /** * @var DOMDocument */ private $document; /** * @var DOMXPath */ private $xpath; /** * @var string */ private $filename; /** * @var LibXMLError[] */ private $errors = []; /** * Returns a PHPUnit configuration object. * * @throws Exception */ public static function getInstance(string $filename): self { $realPath = realpath($filename); if ($realPath === false) { throw new Exception( sprintf( 'Could not read "%s".', $filename ) ); } if (!isset(self::$instances[$realPath])) { self::$instances[$realPath] = new self($realPath); } return self::$instances[$realPath]; } /** * Loads a PHPUnit configuration file. * * @throws Exception */ private function __construct(string $filename) { $this->filename = $filename; $this->document = Xml::loadFile($filename, false, true, true); $this->xpath = new DOMXPath($this->document); $this->validateConfigurationAgainstSchema(); } /** * @codeCoverageIgnore */ private function __clone() { } public function hasValidationErrors(): bool { return count($this->errors) > 0; } public function getValidationErrors(): array { $result = []; foreach ($this->errors as $error) { if (!isset($result[$error->line])) { $result[$error->line] = []; } $result[$error->line][] = trim($error->message); } return $result; } /** * Returns the real path to the configuration file. */ public function getFilename(): string { return $this->filename; } public function getExtensionConfiguration(): array { $result = []; foreach ($this->xpath->query('extensions/extension') as $extension) { $result[] = $this->getElementConfigurationParameters($extension); } return $result; } /** * Returns the configuration for SUT filtering. */ public function getFilterConfiguration(): array { $addUncoveredFilesFromWhitelist = true; $processUncoveredFilesFromWhitelist = false; $includeDirectory = []; $includeFile = []; $excludeDirectory = []; $excludeFile = []; $tmp = $this->xpath->query('filter/whitelist'); if ($tmp->length === 1) { if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) { $addUncoveredFilesFromWhitelist = $this->getBoolean( (string) $tmp->item(0)->getAttribute( 'addUncoveredFilesFromWhitelist' ), true ); } if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) { $processUncoveredFilesFromWhitelist = $this->getBoolean( (string) $tmp->item(0)->getAttribute( 'processUncoveredFilesFromWhitelist' ), false ); } $includeDirectory = $this->readFilterDirectories( 'filter/whitelist/directory' ); $includeFile = $this->readFilterFiles( 'filter/whitelist/file' ); $excludeDirectory = $this->readFilterDirectories( 'filter/whitelist/exclude/directory' ); $excludeFile = $this->readFilterFiles( 'filter/whitelist/exclude/file' ); } return [ 'whitelist' => [ 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist, 'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist, 'include' => [ 'directory' => $includeDirectory, 'file' => $includeFile, ], 'exclude' => [ 'directory' => $excludeDirectory, 'file' => $excludeFile, ], ], ]; } /** * Returns the configuration for groups. */ public function getGroupConfiguration(): array { return $this->parseGroupConfiguration('groups'); } /** * Returns the configuration for testdox groups. */ public function getTestdoxGroupConfiguration(): array { return $this->parseGroupConfiguration('testdoxGroups'); } /** * Returns the configuration for listeners. */ public function getListenerConfiguration(): array { $result = []; foreach ($this->xpath->query('listeners/listener') as $listener) { $result[] = $this->getElementConfigurationParameters($listener); } return $result; } /** * Returns the logging configuration. */ public function getLoggingConfiguration(): array { $result = []; foreach ($this->xpath->query('logging/log') as $log) { assert($log instanceof DOMElement); $type = (string) $log->getAttribute('type'); $target = (string) $log->getAttribute('target'); if (!$target) { continue; } $target = $this->toAbsolutePath($target); if ($type === 'coverage-html') { if ($log->hasAttribute('lowUpperBound')) { $result['lowUpperBound'] = $this->getInteger( (string) $log->getAttribute('lowUpperBound'), 50 ); } if ($log->hasAttribute('highLowerBound')) { $result['highLowerBound'] = $this->getInteger( (string) $log->getAttribute('highLowerBound'), 90 ); } } elseif ($type === 'coverage-crap4j') { if ($log->hasAttribute('threshold')) { $result['crap4jThreshold'] = $this->getInteger( (string) $log->getAttribute('threshold'), 30 ); } } elseif ($type === 'coverage-text') { if ($log->hasAttribute('showUncoveredFiles')) { $result['coverageTextShowUncoveredFiles'] = $this->getBoolean( (string) $log->getAttribute('showUncoveredFiles'), false ); } if ($log->hasAttribute('showOnlySummary')) { $result['coverageTextShowOnlySummary'] = $this->getBoolean( (string) $log->getAttribute('showOnlySummary'), false ); } } $result[$type] = $target; } return $result; } /** * Returns the PHP configuration. */ public function getPHPConfiguration(): array { $result = [ 'include_path' => [], 'ini' => [], 'const' => [], 'var' => [], 'env' => [], 'post' => [], 'get' => [], 'cookie' => [], 'server' => [], 'files' => [], 'request' => [], ]; foreach ($this->xpath->query('php/includePath') as $includePath) { assert($includePath instanceof DOMNode); $path = (string) $includePath->textContent; if ($path) { $result['include_path'][] = $this->toAbsolutePath($path); } } foreach ($this->xpath->query('php/ini') as $ini) { assert($ini instanceof DOMElement); $name = (string) $ini->getAttribute('name'); $value = (string) $ini->getAttribute('value'); $result['ini'][$name]['value'] = $value; } foreach ($this->xpath->query('php/const') as $const) { assert($const instanceof DOMElement); $name = (string) $const->getAttribute('name'); $value = (string) $const->getAttribute('value'); $result['const'][$name]['value'] = $this->getBoolean($value, $value); } foreach (['var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) { foreach ($this->xpath->query('php/' . $array) as $var) { assert($var instanceof DOMElement); $name = (string) $var->getAttribute('name'); $value = (string) $var->getAttribute('value'); $verbatim = false; if ($var->hasAttribute('verbatim')) { $verbatim = $this->getBoolean($var->getAttribute('verbatim'), false); $result[$array][$name]['verbatim'] = $verbatim; } if ($var->hasAttribute('force')) { $force = $this->getBoolean($var->getAttribute('force'), false); $result[$array][$name]['force'] = $force; } if (!$verbatim) { $value = $this->getBoolean($value, $value); } $result[$array][$name]['value'] = $value; } } return $result; } /** * Handles the PHP configuration. */ public function handlePHPConfiguration(): void { $configuration = $this->getPHPConfiguration(); if (!empty($configuration['include_path'])) { ini_set( 'include_path', implode(PATH_SEPARATOR, $configuration['include_path']) . PATH_SEPARATOR . ini_get('include_path') ); } foreach ($configuration['ini'] as $name => $data) { $value = $data['value']; if (defined($value)) { $value = (string) constant($value); } ini_set($name, $value); } foreach ($configuration['const'] as $name => $data) { $value = $data['value']; if (!defined($name)) { define($name, $value); } } foreach ($configuration['var'] as $name => $data) { $GLOBALS[$name] = $data['value']; } foreach ($configuration['server'] as $name => $data) { $_SERVER[$name] = $data['value']; } foreach (['post', 'get', 'cookie', 'files', 'request'] as $array) { $target = &$GLOBALS['_' . strtoupper($array)]; foreach ($configuration[$array] as $name => $data) { $target[$name] = $data['value']; } } foreach ($configuration['env'] as $name => $data) { $value = $data['value']; $force = $data['force'] ?? false; if ($force || getenv($name) === false) { putenv("{$name}={$value}"); } $value = getenv($name); if (!isset($_ENV[$name])) { $_ENV[$name] = $value; } if ($force) { $_ENV[$name] = $value; } } } /** * Returns the PHPUnit configuration. */ public function getPHPUnitConfiguration(): array { $result = []; $root = $this->document->documentElement; if ($root->hasAttribute('cacheTokens')) { $result['cacheTokens'] = $this->getBoolean( (string) $root->getAttribute('cacheTokens'), false ); } if ($root->hasAttribute('columns')) { $columns = (string) $root->getAttribute('columns'); if ($columns === 'max') { $result['columns'] = 'max'; } else { $result['columns'] = $this->getInteger($columns, 80); } } if ($root->hasAttribute('colors')) { /* only allow boolean for compatibility with previous versions 'always' only allowed from command line */ if ($this->getBoolean($root->getAttribute('colors'), false)) { $result['colors'] = ResultPrinter::COLOR_AUTO; } else { $result['colors'] = ResultPrinter::COLOR_NEVER; } } /* * @see https://github.com/sebastianbergmann/phpunit/issues/657 */ if ($root->hasAttribute('stderr')) { $result['stderr'] = $this->getBoolean( (string) $root->getAttribute('stderr'), false ); } if ($root->hasAttribute('backupGlobals')) { $result['backupGlobals'] = $this->getBoolean( (string) $root->getAttribute('backupGlobals'), false ); } if ($root->hasAttribute('backupStaticAttributes')) { $result['backupStaticAttributes'] = $this->getBoolean( (string) $root->getAttribute('backupStaticAttributes'), false ); } if ($root->getAttribute('bootstrap')) { $result['bootstrap'] = $this->toAbsolutePath( (string) $root->getAttribute('bootstrap') ); } if ($root->hasAttribute('convertDeprecationsToExceptions')) { $result['convertDeprecationsToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertDeprecationsToExceptions'), false ); } if ($root->hasAttribute('convertErrorsToExceptions')) { $result['convertErrorsToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertErrorsToExceptions'), true ); } if ($root->hasAttribute('convertNoticesToExceptions')) { $result['convertNoticesToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertNoticesToExceptions'), true ); } if ($root->hasAttribute('convertWarningsToExceptions')) { $result['convertWarningsToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertWarningsToExceptions'), true ); } if ($root->hasAttribute('forceCoversAnnotation')) { $result['forceCoversAnnotation'] = $this->getBoolean( (string) $root->getAttribute('forceCoversAnnotation'), false ); } if ($root->hasAttribute('disableCodeCoverageIgnore')) { $result['disableCodeCoverageIgnore'] = $this->getBoolean( (string) $root->getAttribute('disableCodeCoverageIgnore'), false ); } if ($root->hasAttribute('processIsolation')) { $result['processIsolation'] = $this->getBoolean( (string) $root->getAttribute('processIsolation'), false ); } if ($root->hasAttribute('stopOnDefect')) { $result['stopOnDefect'] = $this->getBoolean( (string) $root->getAttribute('stopOnDefect'), false ); } if ($root->hasAttribute('stopOnError')) { $result['stopOnError'] = $this->getBoolean( (string) $root->getAttribute('stopOnError'), false ); } if ($root->hasAttribute('stopOnFailure')) { $result['stopOnFailure'] = $this->getBoolean( (string) $root->getAttribute('stopOnFailure'), false ); } if ($root->hasAttribute('stopOnWarning')) { $result['stopOnWarning'] = $this->getBoolean( (string) $root->getAttribute('stopOnWarning'), false ); } if ($root->hasAttribute('stopOnIncomplete')) { $result['stopOnIncomplete'] = $this->getBoolean( (string) $root->getAttribute('stopOnIncomplete'), false ); } if ($root->hasAttribute('stopOnRisky')) { $result['stopOnRisky'] = $this->getBoolean( (string) $root->getAttribute('stopOnRisky'), false ); } if ($root->hasAttribute('stopOnSkipped')) { $result['stopOnSkipped'] = $this->getBoolean( (string) $root->getAttribute('stopOnSkipped'), false ); } if ($root->hasAttribute('failOnWarning')) { $result['failOnWarning'] = $this->getBoolean( (string) $root->getAttribute('failOnWarning'), false ); } if ($root->hasAttribute('failOnRisky')) { $result['failOnRisky'] = $this->getBoolean( (string) $root->getAttribute('failOnRisky'), false ); } if ($root->hasAttribute('testSuiteLoaderClass')) { $result['testSuiteLoaderClass'] = (string) $root->getAttribute( 'testSuiteLoaderClass' ); } if ($root->hasAttribute('defaultTestSuite')) { $result['defaultTestSuite'] = (string) $root->getAttribute( 'defaultTestSuite' ); } if ($root->getAttribute('testSuiteLoaderFile')) { $result['testSuiteLoaderFile'] = $this->toAbsolutePath( (string) $root->getAttribute('testSuiteLoaderFile') ); } if ($root->hasAttribute('printerClass')) { $result['printerClass'] = (string) $root->getAttribute( 'printerClass' ); } if ($root->getAttribute('printerFile')) { $result['printerFile'] = $this->toAbsolutePath( (string) $root->getAttribute('printerFile') ); } if ($root->hasAttribute('beStrictAboutChangesToGlobalState')) { $result['beStrictAboutChangesToGlobalState'] = $this->getBoolean( (string) $root->getAttribute('beStrictAboutChangesToGlobalState'), false ); } if ($root->hasAttribute('beStrictAboutOutputDuringTests')) { $result['disallowTestOutput'] = $this->getBoolean( (string) $root->getAttribute('beStrictAboutOutputDuringTests'), false ); } if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) { $result['beStrictAboutResourceUsageDuringSmallTests'] = $this->getBoolean( (string) $root->getAttribute('beStrictAboutResourceUsageDuringSmallTests'), false ); } if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) { $result['reportUselessTests'] = $this->getBoolean( (string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'), true ); } if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) { $result['disallowTodoAnnotatedTests'] = $this->getBoolean( (string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'), false ); } if ($root->hasAttribute('beStrictAboutCoversAnnotation')) { $result['strictCoverage'] = $this->getBoolean( (string) $root->getAttribute('beStrictAboutCoversAnnotation'), false ); } if ($root->hasAttribute('defaultTimeLimit')) { $result['defaultTimeLimit'] = $this->getInteger( (string) $root->getAttribute('defaultTimeLimit'), 1 ); } if ($root->hasAttribute('enforceTimeLimit')) { $result['enforceTimeLimit'] = $this->getBoolean( (string) $root->getAttribute('enforceTimeLimit'), false ); } if ($root->hasAttribute('ignoreDeprecatedCodeUnitsFromCodeCoverage')) { $result['ignoreDeprecatedCodeUnitsFromCodeCoverage'] = $this->getBoolean( (string) $root->getAttribute('ignoreDeprecatedCodeUnitsFromCodeCoverage'), false ); } if ($root->hasAttribute('timeoutForSmallTests')) { $result['timeoutForSmallTests'] = $this->getInteger( (string) $root->getAttribute('timeoutForSmallTests'), 1 ); } if ($root->hasAttribute('timeoutForMediumTests')) { $result['timeoutForMediumTests'] = $this->getInteger( (string) $root->getAttribute('timeoutForMediumTests'), 10 ); } if ($root->hasAttribute('timeoutForLargeTests')) { $result['timeoutForLargeTests'] = $this->getInteger( (string) $root->getAttribute('timeoutForLargeTests'), 60 ); } if ($root->hasAttribute('reverseDefectList')) { $result['reverseDefectList'] = $this->getBoolean( (string) $root->getAttribute('reverseDefectList'), false ); } if ($root->hasAttribute('verbose')) { $result['verbose'] = $this->getBoolean( (string) $root->getAttribute('verbose'), false ); } if ($root->hasAttribute('testdox')) { $testdox = $this->getBoolean( (string) $root->getAttribute('testdox'), false ); if ($testdox) { if (isset($result['printerClass'])) { $result['conflictBetweenPrinterClassAndTestdox'] = true; } else { $result['printerClass'] = CliTestDoxPrinter::class; } } } if ($root->hasAttribute('registerMockObjectsFromTestArgumentsRecursively')) { $result['registerMockObjectsFromTestArgumentsRecursively'] = $this->getBoolean( (string) $root->getAttribute('registerMockObjectsFromTestArgumentsRecursively'), false ); } if ($root->hasAttribute('extensionsDirectory')) { $result['extensionsDirectory'] = $this->toAbsolutePath( (string) $root->getAttribute( 'extensionsDirectory' ) ); } if ($root->hasAttribute('cacheResult')) { $result['cacheResult'] = $this->getBoolean( (string) $root->getAttribute('cacheResult'), true ); } if ($root->hasAttribute('cacheResultFile')) { $result['cacheResultFile'] = $this->toAbsolutePath( (string) $root->getAttribute('cacheResultFile') ); } if ($root->hasAttribute('executionOrder')) { foreach (explode(',', $root->getAttribute('executionOrder')) as $order) { switch ($order) { case 'default': $result['executionOrder'] = TestSuiteSorter::ORDER_DEFAULT; $result['executionOrderDefects'] = TestSuiteSorter::ORDER_DEFAULT; $result['resolveDependencies'] = false; break; case 'defects': $result['executionOrderDefects'] = TestSuiteSorter::ORDER_DEFECTS_FIRST; break; case 'depends': $result['resolveDependencies'] = true; break; case 'duration': $result['executionOrder'] = TestSuiteSorter::ORDER_DURATION; break; case 'no-depends': $result['resolveDependencies'] = false; break; case 'random': $result['executionOrder'] = TestSuiteSorter::ORDER_RANDOMIZED; break; case 'reverse': $result['executionOrder'] = TestSuiteSorter::ORDER_REVERSED; break; case 'size': $result['executionOrder'] = TestSuiteSorter::ORDER_SIZE; break; } } } if ($root->hasAttribute('resolveDependencies')) { $result['resolveDependencies'] = $this->getBoolean( (string) $root->getAttribute('resolveDependencies'), false ); } if ($root->hasAttribute('noInteraction')) { $result['noInteraction'] = $this->getBoolean( (string) $root->getAttribute('noInteraction'), false ); } return $result; } /** * Returns the test suite configuration. * * @throws Exception */ public function getTestSuiteConfiguration(string $testSuiteFilter = ''): TestSuite { $testSuiteNodes = $this->xpath->query('testsuites/testsuite'); if ($testSuiteNodes->length === 0) { $testSuiteNodes = $this->xpath->query('testsuite'); } if ($testSuiteNodes->length === 1) { return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter); } $suite = new TestSuite; foreach ($testSuiteNodes as $testSuiteNode) { $suite->addTestSuite( $this->getTestSuite($testSuiteNode, $testSuiteFilter) ); } return $suite; } /** * Returns the test suite names from the configuration. */ public function getTestSuiteNames(): array { $names = []; foreach ($this->xpath->query('*/testsuite') as $node) { /* @var DOMElement $node */ $names[] = $node->getAttribute('name'); } return $names; } private function validateConfigurationAgainstSchema(): void { $original = libxml_use_internal_errors(true); $xsdFilename = __DIR__ . '/../../phpunit.xsd'; if (defined('__PHPUNIT_PHAR_ROOT__')) { $xsdFilename = __PHPUNIT_PHAR_ROOT__ . '/phpunit.xsd'; } $this->document->schemaValidateSource(file_get_contents($xsdFilename)); $this->errors = libxml_get_errors(); libxml_clear_errors(); libxml_use_internal_errors($original); } /** * Collects and returns the configuration arguments from the PHPUnit * XML configuration. */ private function getConfigurationArguments(DOMNodeList $nodes): array { $arguments = []; if ($nodes->length === 0) { return $arguments; } foreach ($nodes as $node) { if (!$node instanceof DOMElement) { continue; } if ($node->tagName !== 'arguments') { continue; } foreach ($node->childNodes as $argument) { if (!$argument instanceof DOMElement) { continue; } if ($argument->tagName === 'file' || $argument->tagName === 'directory') { $arguments[] = $this->toAbsolutePath((string) $argument->textContent); } else { $arguments[] = Xml::xmlToVariable($argument); } } } return $arguments; } /** * @throws Exception */ private function getTestSuite(DOMElement $testSuiteNode, string $testSuiteFilter = ''): TestSuite { if ($testSuiteNode->hasAttribute('name')) { $suite = new TestSuite( (string) $testSuiteNode->getAttribute('name') ); } else { $suite = new TestSuite; } $exclude = []; foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) { $excludeFile = (string) $excludeNode->textContent; if ($excludeFile) { $exclude[] = $this->toAbsolutePath($excludeFile); } } $fileIteratorFacade = new FileIteratorFacade; $testSuiteFilter = $testSuiteFilter ? explode(',', $testSuiteFilter) : []; foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) { assert($directoryNode instanceof DOMElement); if (!empty($testSuiteFilter) && !in_array($directoryNode->parentNode->getAttribute('name'), $testSuiteFilter, true)) { continue; } $directory = (string) $directoryNode->textContent; if (empty($directory)) { continue; } if (!$this->satisfiesPhpVersion($directoryNode)) { continue; } $files = $fileIteratorFacade->getFilesAsArray( $this->toAbsolutePath($directory), $directoryNode->hasAttribute('suffix') ? (string) $directoryNode->getAttribute('suffix') : 'Test.php', $directoryNode->hasAttribute('prefix') ? (string) $directoryNode->getAttribute('prefix') : '', $exclude ); $suite->addTestFiles($files); } foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) { assert($fileNode instanceof DOMElement); if (!empty($testSuiteFilter) && !in_array($fileNode->parentNode->getAttribute('name'), $testSuiteFilter, true)) { continue; } $file = (string) $fileNode->textContent; if (empty($file)) { continue; } $file = $fileIteratorFacade->getFilesAsArray( $this->toAbsolutePath($file) ); if (!isset($file[0])) { continue; } $file = $file[0]; if (!$this->satisfiesPhpVersion($fileNode)) { continue; } $suite->addTestFile($file); } return $suite; } private function satisfiesPhpVersion(DOMElement $node): bool { $phpVersion = PHP_VERSION; $phpVersionOperator = '>='; if ($node->hasAttribute('phpVersion')) { $phpVersion = (string) $node->getAttribute('phpVersion'); } if ($node->hasAttribute('phpVersionOperator')) { $phpVersionOperator = (string) $node->getAttribute('phpVersionOperator'); } return version_compare(PHP_VERSION, $phpVersion, (new VersionComparisonOperator($phpVersionOperator))->asString()); } /** * if $value is 'false' or 'true', this returns the value that $value represents. * Otherwise, returns $default, which may be a string in rare cases. * See PHPUnit\Util\ConfigurationTest::testPHPConfigurationIsReadCorrectly. * * @param bool|string $default * * @return bool|string */ private function getBoolean(string $value, $default) { if (strtolower($value) === 'false') { return false; } if (strtolower($value) === 'true') { return true; } return $default; } private function getInteger(string $value, int $default): int { if (is_numeric($value)) { return (int) $value; } return $default; } private function readFilterDirectories(string $query): array { $directories = []; foreach ($this->xpath->query($query) as $directoryNode) { assert($directoryNode instanceof DOMElement); $directoryPath = (string) $directoryNode->textContent; if (!$directoryPath) { continue; } $directories[] = [ 'path' => $this->toAbsolutePath($directoryPath), 'prefix' => $directoryNode->hasAttribute('prefix') ? (string) $directoryNode->getAttribute('prefix') : '', 'suffix' => $directoryNode->hasAttribute('suffix') ? (string) $directoryNode->getAttribute('suffix') : '.php', 'group' => $directoryNode->hasAttribute('group') ? (string) $directoryNode->getAttribute('group') : 'DEFAULT', ]; } return $directories; } /** * @return string[] */ private function readFilterFiles(string $query): array { $files = []; foreach ($this->xpath->query($query) as $file) { assert($file instanceof DOMNode); $filePath = (string) $file->textContent; if ($filePath) { $files[] = $this->toAbsolutePath($filePath); } } return $files; } private function toAbsolutePath(string $path, bool $useIncludePath = false): string { $path = trim($path); if (strpos($path, '/') === 0) { return $path; } // Matches the following on Windows: // - \\NetworkComputer\Path // - \\.\D: // - \\.\c: // - C:\Windows // - C:\windows // - C:/windows // - c:/windows if (defined('PHP_WINDOWS_VERSION_BUILD') && ($path[0] === '\\' || (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) { return $path; } if (strpos($path, '://') !== false) { return $path; } $file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path; if ($useIncludePath && !file_exists($file)) { $includePathFile = stream_resolve_include_path($path); if ($includePathFile) { $file = $includePathFile; } } return $file; } private function parseGroupConfiguration(string $root): array { $groups = [ 'include' => [], 'exclude' => [], ]; foreach ($this->xpath->query($root . '/include/group') as $group) { assert($group instanceof DOMNode); $groups['include'][] = (string) $group->textContent; } foreach ($this->xpath->query($root . '/exclude/group') as $group) { assert($group instanceof DOMNode); $groups['exclude'][] = (string) $group->textContent; } return $groups; } private function getElementConfigurationParameters(DOMElement $element): array { $class = (string) $element->getAttribute('class'); $file = ''; $arguments = $this->getConfigurationArguments($element->childNodes); if ($element->getAttribute('file')) { $file = $this->toAbsolutePath( (string) $element->getAttribute('file'), true ); } return [ 'class' => $class, 'file' => $file, 'arguments' => $arguments, ]; } }