first commit
This commit is contained in:
171
plugins/simplesaml/lib/vendor/symfony/config/Builder/ClassBuilder.php
vendored
Normal file
171
plugins/simplesaml/lib/vendor/symfony/config/Builder/ClassBuilder.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Builder;
|
||||
|
||||
/**
|
||||
* Build PHP classes to generate config.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ClassBuilder
|
||||
{
|
||||
private string $namespace;
|
||||
private string $name;
|
||||
|
||||
/** @var Property[] */
|
||||
private array $properties = [];
|
||||
|
||||
/** @var Method[] */
|
||||
private array $methods = [];
|
||||
private array $require = [];
|
||||
private array $use = [];
|
||||
private array $implements = [];
|
||||
private bool $allowExtraKeys = false;
|
||||
|
||||
public function __construct(string $namespace, string $name)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->name = ucfirst($this->camelCase($name)).'Config';
|
||||
}
|
||||
|
||||
public function getDirectory(): string
|
||||
{
|
||||
return str_replace('\\', \DIRECTORY_SEPARATOR, $this->namespace);
|
||||
}
|
||||
|
||||
public function getFilename(): string
|
||||
{
|
||||
return $this->name.'.php';
|
||||
}
|
||||
|
||||
public function build(): string
|
||||
{
|
||||
$rootPath = explode(\DIRECTORY_SEPARATOR, $this->getDirectory());
|
||||
$require = '';
|
||||
foreach ($this->require as $class) {
|
||||
// figure out relative path.
|
||||
$path = explode(\DIRECTORY_SEPARATOR, $class->getDirectory());
|
||||
$path[] = $class->getFilename();
|
||||
foreach ($rootPath as $key => $value) {
|
||||
if ($path[$key] !== $value) {
|
||||
break;
|
||||
}
|
||||
unset($path[$key]);
|
||||
}
|
||||
$require .= sprintf('require_once __DIR__.\DIRECTORY_SEPARATOR.\'%s\';', implode('\'.\DIRECTORY_SEPARATOR.\'', $path))."\n";
|
||||
}
|
||||
$use = $require ? "\n" : '';
|
||||
foreach (array_keys($this->use) as $statement) {
|
||||
$use .= sprintf('use %s;', $statement)."\n";
|
||||
}
|
||||
|
||||
$implements = [] === $this->implements ? '' : 'implements '.implode(', ', $this->implements);
|
||||
$body = '';
|
||||
foreach ($this->properties as $property) {
|
||||
$body .= ' '.$property->getContent()."\n";
|
||||
}
|
||||
foreach ($this->methods as $method) {
|
||||
$lines = explode("\n", $method->getContent());
|
||||
foreach ($lines as $line) {
|
||||
$body .= ($line ? ' '.$line : '')."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$content = strtr('<?php
|
||||
|
||||
namespace NAMESPACE;
|
||||
|
||||
REQUIREUSE
|
||||
/**
|
||||
* This class is automatically generated to help in creating a config.
|
||||
*/
|
||||
class CLASS IMPLEMENTS
|
||||
{
|
||||
BODY
|
||||
}
|
||||
', ['NAMESPACE' => $this->namespace, 'REQUIRE' => $require, 'USE' => $use, 'CLASS' => $this->getName(), 'IMPLEMENTS' => $implements, 'BODY' => $body]);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function addRequire(self $class): void
|
||||
{
|
||||
$this->require[] = $class;
|
||||
}
|
||||
|
||||
public function addUse(string $class): void
|
||||
{
|
||||
$this->use[$class] = true;
|
||||
}
|
||||
|
||||
public function addImplements(string $interface): void
|
||||
{
|
||||
$this->implements[] = '\\'.ltrim($interface, '\\');
|
||||
}
|
||||
|
||||
public function addMethod(string $name, string $body, array $params = []): void
|
||||
{
|
||||
$this->methods[] = new Method(strtr($body, ['NAME' => $this->camelCase($name)] + $params));
|
||||
}
|
||||
|
||||
public function addProperty(string $name, ?string $classType = null, ?string $defaultValue = null): Property
|
||||
{
|
||||
$property = new Property($name, '_' !== $name[0] ? $this->camelCase($name) : $name);
|
||||
if (null !== $classType) {
|
||||
$property->setType($classType);
|
||||
}
|
||||
$this->properties[] = $property;
|
||||
$defaultValue = null !== $defaultValue ? sprintf(' = %s', $defaultValue) : '';
|
||||
$property->setContent(sprintf('private $%s%s;', $property->getName(), $defaultValue));
|
||||
|
||||
return $property;
|
||||
}
|
||||
|
||||
public function getProperties(): array
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
private function camelCase(string $input): string
|
||||
{
|
||||
$output = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $input))));
|
||||
|
||||
return preg_replace('#\W#', '', $output);
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getNamespace(): string
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
public function getFqcn(): string
|
||||
{
|
||||
return '\\'.$this->namespace.'\\'.$this->name;
|
||||
}
|
||||
|
||||
public function setAllowExtraKeys(bool $allowExtraKeys): void
|
||||
{
|
||||
$this->allowExtraKeys = $allowExtraKeys;
|
||||
}
|
||||
|
||||
public function shouldAllowExtraKeys(): bool
|
||||
{
|
||||
return $this->allowExtraKeys;
|
||||
}
|
||||
}
|
600
plugins/simplesaml/lib/vendor/symfony/config/Builder/ConfigBuilderGenerator.php
vendored
Normal file
600
plugins/simplesaml/lib/vendor/symfony/config/Builder/ConfigBuilderGenerator.php
vendored
Normal file
@@ -0,0 +1,600 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\ArrayNode;
|
||||
use Symfony\Component\Config\Definition\BaseNode;
|
||||
use Symfony\Component\Config\Definition\BooleanNode;
|
||||
use Symfony\Component\Config\Definition\Builder\ExprBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\EnumNode;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Config\Definition\FloatNode;
|
||||
use Symfony\Component\Config\Definition\IntegerNode;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
use Symfony\Component\Config\Definition\PrototypedArrayNode;
|
||||
use Symfony\Component\Config\Definition\ScalarNode;
|
||||
use Symfony\Component\Config\Definition\VariableNode;
|
||||
use Symfony\Component\Config\Loader\ParamConfigurator;
|
||||
|
||||
/**
|
||||
* Generate ConfigBuilders to help create valid config.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ConfigBuilderGenerator implements ConfigBuilderGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @var ClassBuilder[]
|
||||
*/
|
||||
private array $classes = [];
|
||||
private string $outputDir;
|
||||
|
||||
public function __construct(string $outputDir)
|
||||
{
|
||||
$this->outputDir = $outputDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Closure that will return the root config class
|
||||
*/
|
||||
public function build(ConfigurationInterface $configuration): \Closure
|
||||
{
|
||||
$this->classes = [];
|
||||
|
||||
$rootNode = $configuration->getConfigTreeBuilder()->buildTree();
|
||||
$rootClass = new ClassBuilder('Symfony\\Config', $rootNode->getName());
|
||||
|
||||
$path = $this->getFullPath($rootClass);
|
||||
if (!is_file($path)) {
|
||||
// Generate the class if the file not exists
|
||||
$this->classes[] = $rootClass;
|
||||
$this->buildNode($rootNode, $rootClass, $this->getSubNamespace($rootClass));
|
||||
$rootClass->addImplements(ConfigBuilderInterface::class);
|
||||
$rootClass->addMethod('getExtensionAlias', '
|
||||
public function NAME(): string
|
||||
{
|
||||
return \'ALIAS\';
|
||||
}', ['ALIAS' => $rootNode->getPath()]);
|
||||
|
||||
$this->writeClasses();
|
||||
}
|
||||
|
||||
return function () use ($path, $rootClass) {
|
||||
require_once $path;
|
||||
$className = $rootClass->getFqcn();
|
||||
|
||||
return new $className();
|
||||
};
|
||||
}
|
||||
|
||||
private function getFullPath(ClassBuilder $class): string
|
||||
{
|
||||
$directory = $this->outputDir.\DIRECTORY_SEPARATOR.$class->getDirectory();
|
||||
if (!is_dir($directory)) {
|
||||
@mkdir($directory, 0777, true);
|
||||
}
|
||||
|
||||
return $directory.\DIRECTORY_SEPARATOR.$class->getFilename();
|
||||
}
|
||||
|
||||
private function writeClasses(): void
|
||||
{
|
||||
foreach ($this->classes as $class) {
|
||||
$this->buildConstructor($class);
|
||||
$this->buildToArray($class);
|
||||
if ($class->getProperties()) {
|
||||
$class->addProperty('_usedProperties', null, '[]');
|
||||
}
|
||||
$this->buildSetExtraKey($class);
|
||||
|
||||
file_put_contents($this->getFullPath($class), $class->build());
|
||||
}
|
||||
|
||||
$this->classes = [];
|
||||
}
|
||||
|
||||
private function buildNode(NodeInterface $node, ClassBuilder $class, string $namespace): void
|
||||
{
|
||||
if (!$node instanceof ArrayNode) {
|
||||
throw new \LogicException('The node was expected to be an ArrayNode. This Configuration includes an edge case not supported yet.');
|
||||
}
|
||||
|
||||
foreach ($node->getChildren() as $child) {
|
||||
match (true) {
|
||||
$child instanceof ScalarNode => $this->handleScalarNode($child, $class),
|
||||
$child instanceof PrototypedArrayNode => $this->handlePrototypedArrayNode($child, $class, $namespace),
|
||||
$child instanceof VariableNode => $this->handleVariableNode($child, $class),
|
||||
$child instanceof ArrayNode => $this->handleArrayNode($child, $class, $namespace),
|
||||
default => throw new \RuntimeException(sprintf('Unknown node "%s".', $child::class)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $namespace): void
|
||||
{
|
||||
$childClass = new ClassBuilder($namespace, $node->getName());
|
||||
$childClass->setAllowExtraKeys($node->shouldIgnoreExtraKeys());
|
||||
$class->addRequire($childClass);
|
||||
$this->classes[] = $childClass;
|
||||
|
||||
$hasNormalizationClosures = $this->hasNormalizationClosures($node);
|
||||
$comment = $this->getComment($node);
|
||||
if ($hasNormalizationClosures) {
|
||||
$comment = sprintf(" * @template TValue\n * @param TValue \$value\n%s", $comment);
|
||||
$comment .= sprintf(' * @return %s|$this'."\n", $childClass->getFqcn());
|
||||
$comment .= sprintf(' * @psalm-return (TValue is array ? %s : static)'."\n ", $childClass->getFqcn());
|
||||
}
|
||||
if ('' !== $comment) {
|
||||
$comment = "/**\n$comment*/\n";
|
||||
}
|
||||
|
||||
$property = $class->addProperty(
|
||||
$node->getName(),
|
||||
$this->getType($childClass->getFqcn(), $hasNormalizationClosures)
|
||||
);
|
||||
$nodeTypes = $this->getParameterTypes($node);
|
||||
$body = $hasNormalizationClosures ? '
|
||||
COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
|
||||
{
|
||||
if (!\is_array($value)) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!$this->PROPERTY instanceof CLASS) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = new CLASS($value);
|
||||
} elseif (0 < \func_num_args()) {
|
||||
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
|
||||
}
|
||||
|
||||
return $this->PROPERTY;
|
||||
}' : '
|
||||
COMMENTpublic function NAME(array $value = []): CLASS
|
||||
{
|
||||
if (null === $this->PROPERTY) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = new CLASS($value);
|
||||
} elseif (0 < \func_num_args()) {
|
||||
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
|
||||
}
|
||||
|
||||
return $this->PROPERTY;
|
||||
}';
|
||||
$class->addUse(InvalidConfigurationException::class);
|
||||
$class->addMethod($node->getName(), $body, [
|
||||
'COMMENT' => $comment,
|
||||
'PROPERTY' => $property->getName(),
|
||||
'CLASS' => $childClass->getFqcn(),
|
||||
'PARAM_TYPE' => \in_array('mixed', $nodeTypes, true) ? 'mixed' : implode('|', $nodeTypes),
|
||||
]);
|
||||
|
||||
$this->buildNode($node, $childClass, $this->getSubNamespace($childClass));
|
||||
}
|
||||
|
||||
private function handleVariableNode(VariableNode $node, ClassBuilder $class): void
|
||||
{
|
||||
$comment = $this->getComment($node);
|
||||
$property = $class->addProperty($node->getName());
|
||||
$class->addUse(ParamConfigurator::class);
|
||||
|
||||
$body = '
|
||||
/**
|
||||
COMMENT *
|
||||
* @return $this
|
||||
*/
|
||||
public function NAME(mixed $valueDEFAULT): static
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = $value;
|
||||
|
||||
return $this;
|
||||
}';
|
||||
$class->addMethod($node->getName(), $body, [
|
||||
'PROPERTY' => $property->getName(),
|
||||
'COMMENT' => $comment,
|
||||
'DEFAULT' => $node->hasDefaultValue() ? ' = '.var_export($node->getDefaultValue(), true) : '',
|
||||
]);
|
||||
}
|
||||
|
||||
private function handlePrototypedArrayNode(PrototypedArrayNode $node, ClassBuilder $class, string $namespace): void
|
||||
{
|
||||
$name = $this->getSingularName($node);
|
||||
$prototype = $node->getPrototype();
|
||||
$methodName = $name;
|
||||
$hasNormalizationClosures = $this->hasNormalizationClosures($node) || $this->hasNormalizationClosures($prototype);
|
||||
|
||||
$nodeParameterTypes = $this->getParameterTypes($node);
|
||||
$prototypeParameterTypes = $this->getParameterTypes($prototype);
|
||||
if (!$prototype instanceof ArrayNode || ($prototype instanceof PrototypedArrayNode && $prototype->getPrototype() instanceof ScalarNode)) {
|
||||
$class->addUse(ParamConfigurator::class);
|
||||
$property = $class->addProperty($node->getName());
|
||||
if (null === $key = $node->getKeyAttribute()) {
|
||||
// This is an array of values; don't use singular name
|
||||
$nodeTypesWithoutArray = array_filter($nodeParameterTypes, static fn ($type) => 'array' !== $type);
|
||||
$body = '
|
||||
/**
|
||||
* @param ParamConfigurator|list<ParamConfigurator|PROTOTYPE_TYPE>EXTRA_TYPE $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function NAME(PARAM_TYPE $value): static
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = $value;
|
||||
|
||||
return $this;
|
||||
}';
|
||||
|
||||
$class->addMethod($node->getName(), $body, [
|
||||
'PROPERTY' => $property->getName(),
|
||||
'PROTOTYPE_TYPE' => implode('|', $prototypeParameterTypes),
|
||||
'EXTRA_TYPE' => $nodeTypesWithoutArray ? '|'.implode('|', $nodeTypesWithoutArray) : '',
|
||||
'PARAM_TYPE' => \in_array('mixed', $nodeParameterTypes, true) ? 'mixed' : 'ParamConfigurator|'.implode('|', $nodeParameterTypes),
|
||||
]);
|
||||
} else {
|
||||
$body = '
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function NAME(string $VAR, TYPE $VALUE): static
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY[$VAR] = $VALUE;
|
||||
|
||||
return $this;
|
||||
}';
|
||||
|
||||
$class->addMethod($methodName, $body, [
|
||||
'PROPERTY' => $property->getName(),
|
||||
'TYPE' => \in_array('mixed', $prototypeParameterTypes, true) ? 'mixed' : 'ParamConfigurator|'.implode('|', $prototypeParameterTypes),
|
||||
'VAR' => '' === $key ? 'key' : $key,
|
||||
'VALUE' => 'value' === $key ? 'data' : 'value',
|
||||
]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$childClass = new ClassBuilder($namespace, $name);
|
||||
if ($prototype instanceof ArrayNode) {
|
||||
$childClass->setAllowExtraKeys($prototype->shouldIgnoreExtraKeys());
|
||||
}
|
||||
$class->addRequire($childClass);
|
||||
$this->classes[] = $childClass;
|
||||
|
||||
$property = $class->addProperty(
|
||||
$node->getName(),
|
||||
$this->getType($childClass->getFqcn().'[]', $hasNormalizationClosures)
|
||||
);
|
||||
|
||||
$comment = $this->getComment($node);
|
||||
if ($hasNormalizationClosures) {
|
||||
$comment = sprintf(" * @template TValue\n * @param TValue \$value\n%s", $comment);
|
||||
$comment .= sprintf(' * @return %s|$this'."\n", $childClass->getFqcn());
|
||||
$comment .= sprintf(' * @psalm-return (TValue is array ? %s : static)'."\n ", $childClass->getFqcn());
|
||||
}
|
||||
if ('' !== $comment) {
|
||||
$comment = "/**\n$comment*/\n";
|
||||
}
|
||||
|
||||
if (null === $key = $node->getKeyAttribute()) {
|
||||
$body = $hasNormalizationClosures ? '
|
||||
COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
if (!\is_array($value)) {
|
||||
$this->PROPERTY[] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->PROPERTY[] = new CLASS($value);
|
||||
}' : '
|
||||
COMMENTpublic function NAME(array $value = []): CLASS
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
|
||||
return $this->PROPERTY[] = new CLASS($value);
|
||||
}';
|
||||
$class->addMethod($methodName, $body, [
|
||||
'COMMENT' => $comment,
|
||||
'PROPERTY' => $property->getName(),
|
||||
'CLASS' => $childClass->getFqcn(),
|
||||
'PARAM_TYPE' => \in_array('mixed', $nodeParameterTypes, true) ? 'mixed' : implode('|', $nodeParameterTypes),
|
||||
]);
|
||||
} else {
|
||||
$body = $hasNormalizationClosures ? '
|
||||
COMMENTpublic function NAME(string $VAR, PARAM_TYPE $VALUE = []): CLASS|static
|
||||
{
|
||||
if (!\is_array($VALUE)) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY[$VAR] = $VALUE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!isset($this->PROPERTY[$VAR]) || !$this->PROPERTY[$VAR] instanceof CLASS) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY[$VAR] = new CLASS($VALUE);
|
||||
} elseif (1 < \func_num_args()) {
|
||||
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
|
||||
}
|
||||
|
||||
return $this->PROPERTY[$VAR];
|
||||
}' : '
|
||||
COMMENTpublic function NAME(string $VAR, array $VALUE = []): CLASS
|
||||
{
|
||||
if (!isset($this->PROPERTY[$VAR])) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY[$VAR] = new CLASS($VALUE);
|
||||
} elseif (1 < \func_num_args()) {
|
||||
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
|
||||
}
|
||||
|
||||
return $this->PROPERTY[$VAR];
|
||||
}';
|
||||
$class->addUse(InvalidConfigurationException::class);
|
||||
$class->addMethod($methodName, str_replace('$value', '$VAR', $body), [
|
||||
'COMMENT' => $comment, 'PROPERTY' => $property->getName(),
|
||||
'CLASS' => $childClass->getFqcn(),
|
||||
'VAR' => '' === $key ? 'key' : $key,
|
||||
'VALUE' => 'value' === $key ? 'data' : 'value',
|
||||
'PARAM_TYPE' => \in_array('mixed', $prototypeParameterTypes, true) ? 'mixed' : implode('|', $prototypeParameterTypes),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->buildNode($prototype, $childClass, $namespace.'\\'.$childClass->getName());
|
||||
}
|
||||
|
||||
private function handleScalarNode(ScalarNode $node, ClassBuilder $class): void
|
||||
{
|
||||
$comment = $this->getComment($node);
|
||||
$property = $class->addProperty($node->getName());
|
||||
$class->addUse(ParamConfigurator::class);
|
||||
|
||||
$body = '
|
||||
/**
|
||||
COMMENT * @return $this
|
||||
*/
|
||||
public function NAME($value): static
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = $value;
|
||||
|
||||
return $this;
|
||||
}';
|
||||
|
||||
$class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'COMMENT' => $comment]);
|
||||
}
|
||||
|
||||
private function getParameterTypes(NodeInterface $node): array
|
||||
{
|
||||
$paramTypes = [];
|
||||
if ($node instanceof BaseNode) {
|
||||
$types = $node->getNormalizedTypes();
|
||||
if (\in_array(ExprBuilder::TYPE_ANY, $types, true)) {
|
||||
$paramTypes[] = 'mixed';
|
||||
}
|
||||
if (\in_array(ExprBuilder::TYPE_STRING, $types, true)) {
|
||||
$paramTypes[] = 'string';
|
||||
}
|
||||
}
|
||||
if ($node instanceof BooleanNode) {
|
||||
$paramTypes[] = 'bool';
|
||||
} elseif ($node instanceof IntegerNode) {
|
||||
$paramTypes[] = 'int';
|
||||
} elseif ($node instanceof FloatNode) {
|
||||
$paramTypes[] = 'float';
|
||||
} elseif ($node instanceof EnumNode) {
|
||||
$paramTypes[] = 'mixed';
|
||||
} elseif ($node instanceof ArrayNode) {
|
||||
$paramTypes[] = 'array';
|
||||
} elseif ($node instanceof VariableNode) {
|
||||
$paramTypes[] = 'mixed';
|
||||
}
|
||||
|
||||
return array_unique($paramTypes);
|
||||
}
|
||||
|
||||
private function getComment(BaseNode $node): string
|
||||
{
|
||||
$comment = '';
|
||||
if ('' !== $info = (string) $node->getInfo()) {
|
||||
$comment .= ' * '.$info."\n";
|
||||
}
|
||||
|
||||
if (!$node instanceof ArrayNode) {
|
||||
foreach ((array) ($node->getExample() ?? []) as $example) {
|
||||
$comment .= ' * @example '.$example."\n";
|
||||
}
|
||||
|
||||
if ('' !== $default = $node->getDefaultValue()) {
|
||||
$comment .= ' * @default '.(null === $default ? 'null' : var_export($default, true))."\n";
|
||||
}
|
||||
|
||||
if ($node instanceof EnumNode) {
|
||||
$comment .= sprintf(' * @param ParamConfigurator|%s $value', implode('|', array_unique(array_map(fn ($a) => !$a instanceof \UnitEnum ? var_export($a, true) : '\\'.ltrim(var_export($a, true), '\\'), $node->getValues()))))."\n";
|
||||
} else {
|
||||
$parameterTypes = $this->getParameterTypes($node);
|
||||
$comment .= ' * @param ParamConfigurator|'.implode('|', $parameterTypes).' $value'."\n";
|
||||
}
|
||||
} else {
|
||||
foreach ((array) ($node->getExample() ?? []) as $example) {
|
||||
$comment .= ' * @example '.json_encode($example)."\n";
|
||||
}
|
||||
|
||||
if ($node->hasDefaultValue() && [] != $default = $node->getDefaultValue()) {
|
||||
$comment .= ' * @default '.json_encode($default)."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($node->isDeprecated()) {
|
||||
$comment .= ' * @deprecated '.$node->getDeprecation($node->getName(), $node->getParent()->getName())['message']."\n";
|
||||
}
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a good singular name.
|
||||
*/
|
||||
private function getSingularName(PrototypedArrayNode $node): string
|
||||
{
|
||||
$name = $node->getName();
|
||||
if (!str_ends_with($name, 's')) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$parent = $node->getParent();
|
||||
$mappings = $parent instanceof ArrayNode ? $parent->getXmlRemappings() : [];
|
||||
foreach ($mappings as $map) {
|
||||
if ($map[1] === $name) {
|
||||
$name = $map[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function buildToArray(ClassBuilder $class): void
|
||||
{
|
||||
$body = '$output = [];';
|
||||
foreach ($class->getProperties() as $p) {
|
||||
$code = '$this->PROPERTY';
|
||||
if (null !== $p->getType()) {
|
||||
if ($p->isArray()) {
|
||||
$code = $p->areScalarsAllowed()
|
||||
? 'array_map(fn ($v) => $v instanceof CLASS ? $v->toArray() : $v, $this->PROPERTY)'
|
||||
: 'array_map(fn ($v) => $v->toArray(), $this->PROPERTY)'
|
||||
;
|
||||
} else {
|
||||
$code = $p->areScalarsAllowed()
|
||||
? '$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY'
|
||||
: '$this->PROPERTY->toArray()'
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
$body .= strtr('
|
||||
if (isset($this->_usedProperties[\'PROPERTY\'])) {
|
||||
$output[\'ORG_NAME\'] = '.$code.';
|
||||
}', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName(), 'CLASS' => $p->getType()]);
|
||||
}
|
||||
|
||||
$extraKeys = $class->shouldAllowExtraKeys() ? ' + $this->_extraKeys' : '';
|
||||
|
||||
$class->addMethod('toArray', '
|
||||
public function NAME(): array
|
||||
{
|
||||
'.$body.'
|
||||
|
||||
return $output'.$extraKeys.';
|
||||
}');
|
||||
}
|
||||
|
||||
private function buildConstructor(ClassBuilder $class): void
|
||||
{
|
||||
$body = '';
|
||||
foreach ($class->getProperties() as $p) {
|
||||
$code = '$value[\'ORG_NAME\']';
|
||||
if (null !== $p->getType()) {
|
||||
if ($p->isArray()) {
|
||||
$code = $p->areScalarsAllowed()
|
||||
? 'array_map(fn ($v) => \is_array($v) ? new '.$p->getType().'($v) : $v, $value[\'ORG_NAME\'])'
|
||||
: 'array_map(fn ($v) => new '.$p->getType().'($v), $value[\'ORG_NAME\'])'
|
||||
;
|
||||
} else {
|
||||
$code = $p->areScalarsAllowed()
|
||||
? '\is_array($value[\'ORG_NAME\']) ? new '.$p->getType().'($value[\'ORG_NAME\']) : $value[\'ORG_NAME\']'
|
||||
: 'new '.$p->getType().'($value[\'ORG_NAME\'])'
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
$body .= strtr('
|
||||
if (array_key_exists(\'ORG_NAME\', $value)) {
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
$this->PROPERTY = '.$code.';
|
||||
unset($value[\'ORG_NAME\']);
|
||||
}
|
||||
', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName()]);
|
||||
}
|
||||
|
||||
if ($class->shouldAllowExtraKeys()) {
|
||||
$body .= '
|
||||
$this->_extraKeys = $value;
|
||||
';
|
||||
} else {
|
||||
$body .= '
|
||||
if ([] !== $value) {
|
||||
throw new InvalidConfigurationException(sprintf(\'The following keys are not supported by "%s": \', __CLASS__).implode(\', \', array_keys($value)));
|
||||
}';
|
||||
|
||||
$class->addUse(InvalidConfigurationException::class);
|
||||
}
|
||||
|
||||
$class->addMethod('__construct', '
|
||||
public function __construct(array $value = [])
|
||||
{'.$body.'
|
||||
}');
|
||||
}
|
||||
|
||||
private function buildSetExtraKey(ClassBuilder $class): void
|
||||
{
|
||||
if (!$class->shouldAllowExtraKeys()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$class->addUse(ParamConfigurator::class);
|
||||
|
||||
$class->addProperty('_extraKeys');
|
||||
|
||||
$class->addMethod('set', '
|
||||
/**
|
||||
* @param ParamConfigurator|mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function NAME(string $key, mixed $value): static
|
||||
{
|
||||
$this->_extraKeys[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}');
|
||||
}
|
||||
|
||||
private function getSubNamespace(ClassBuilder $rootClass): string
|
||||
{
|
||||
return sprintf('%s\\%s', $rootClass->getNamespace(), substr($rootClass->getName(), 0, -6));
|
||||
}
|
||||
|
||||
private function hasNormalizationClosures(NodeInterface $node): bool
|
||||
{
|
||||
try {
|
||||
$r = new \ReflectionProperty($node, 'normalizationClosures');
|
||||
} catch (\ReflectionException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [] !== $r->getValue($node);
|
||||
}
|
||||
|
||||
private function getType(string $classType, bool $hasNormalizationClosures): string
|
||||
{
|
||||
return $classType.($hasNormalizationClosures ? '|scalar' : '');
|
||||
}
|
||||
}
|
27
plugins/simplesaml/lib/vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php
vendored
Normal file
27
plugins/simplesaml/lib/vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
|
||||
/**
|
||||
* Generates ConfigBuilders to help create valid config.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface ConfigBuilderGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @return \Closure that will return the root config class
|
||||
*/
|
||||
public function build(ConfigurationInterface $configuration): \Closure;
|
||||
}
|
30
plugins/simplesaml/lib/vendor/symfony/config/Builder/ConfigBuilderInterface.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/config/Builder/ConfigBuilderInterface.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Builder;
|
||||
|
||||
/**
|
||||
* A ConfigBuilder provides helper methods to build a large complex array.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface ConfigBuilderInterface
|
||||
{
|
||||
/**
|
||||
* Gets all configuration represented as an array.
|
||||
*/
|
||||
public function toArray(): array;
|
||||
|
||||
/**
|
||||
* Gets the alias for the extension which config we are building.
|
||||
*/
|
||||
public function getExtensionAlias(): string;
|
||||
}
|
34
plugins/simplesaml/lib/vendor/symfony/config/Builder/Method.php
vendored
Normal file
34
plugins/simplesaml/lib/vendor/symfony/config/Builder/Method.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Builder;
|
||||
|
||||
/**
|
||||
* Represents a method when building classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class Method
|
||||
{
|
||||
private string $content;
|
||||
|
||||
public function __construct(string $content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
}
|
86
plugins/simplesaml/lib/vendor/symfony/config/Builder/Property.php
vendored
Normal file
86
plugins/simplesaml/lib/vendor/symfony/config/Builder/Property.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Builder;
|
||||
|
||||
/**
|
||||
* Represents a property when building classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class Property
|
||||
{
|
||||
private string $name;
|
||||
private string $originalName;
|
||||
private bool $array = false;
|
||||
private bool $scalarsAllowed = false;
|
||||
private ?string $type = null;
|
||||
private ?string $content = null;
|
||||
|
||||
public function __construct(string $originalName, string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->originalName = $originalName;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getOriginalName(): string
|
||||
{
|
||||
return $this->originalName;
|
||||
}
|
||||
|
||||
public function setType(string $type): void
|
||||
{
|
||||
$this->array = false;
|
||||
$this->type = $type;
|
||||
|
||||
if (str_ends_with($type, '|scalar')) {
|
||||
$this->scalarsAllowed = true;
|
||||
$this->type = $type = substr($type, 0, -7);
|
||||
}
|
||||
|
||||
if (str_ends_with($type, '[]')) {
|
||||
$this->array = true;
|
||||
$this->type = substr($type, 0, -2);
|
||||
}
|
||||
}
|
||||
|
||||
public function getType(): ?string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getContent(): ?string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function setContent(string $content): void
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function isArray(): bool
|
||||
{
|
||||
return $this->array;
|
||||
}
|
||||
|
||||
public function areScalarsAllowed(): bool
|
||||
{
|
||||
return $this->scalarsAllowed;
|
||||
}
|
||||
}
|
153
plugins/simplesaml/lib/vendor/symfony/config/CHANGELOG.md
vendored
Normal file
153
plugins/simplesaml/lib/vendor/symfony/config/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
6.3
|
||||
---
|
||||
|
||||
* Allow enum values in `EnumNode`
|
||||
|
||||
6.2
|
||||
---
|
||||
|
||||
* Deprecate calling `NodeBuilder::setParent()` without any arguments
|
||||
* Add a more accurate typehint in generated PHP config
|
||||
|
||||
6.1
|
||||
---
|
||||
|
||||
* Allow using environment variables in `EnumNode`
|
||||
* Add Node's information in generated Config
|
||||
* Add `DefinitionFileLoader` class to load a TreeBuilder definition from an external file
|
||||
* Add `DefinitionConfigurator` helper
|
||||
|
||||
6.0
|
||||
---
|
||||
|
||||
* Remove `BaseNode::getDeprecationMessage()`
|
||||
|
||||
5.3.0
|
||||
-----
|
||||
|
||||
* Add support for generating `ConfigBuilder` for extensions
|
||||
|
||||
5.1.0
|
||||
-----
|
||||
|
||||
* updated the signature of method `NodeDefinition::setDeprecated()` to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`
|
||||
* updated the signature of method `BaseNode::setDeprecated()` to `BaseNode::setDeprecation(string $package, string $version, string $message)`
|
||||
* deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node
|
||||
* deprecated `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
||||
* Dropped support for constructing a `TreeBuilder` without passing root node information.
|
||||
* Removed the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead
|
||||
* Added method `getChildNodeDefinitions()` to ParentNodeDefinitionInterface
|
||||
* Removed `FileLoaderLoadException`, use `LoaderLoadException` instead
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
* added a way to exclude patterns of resources from being imported by the `import()` method
|
||||
|
||||
4.3.0
|
||||
-----
|
||||
|
||||
* deprecated using environment variables with `cannotBeEmpty()` if the value is validated with `validate()`
|
||||
* made `Resource\*` classes final and not implement `Serializable` anymore
|
||||
* deprecated the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
* deprecated constructing a `TreeBuilder` without passing root node information
|
||||
* renamed `FileLoaderLoadException` to `LoaderLoadException`
|
||||
|
||||
4.1.0
|
||||
-----
|
||||
|
||||
* added `setPathSeparator` method to `NodeBuilder` class
|
||||
* added third `$pathSeparator` constructor argument to `BaseNode`
|
||||
* the `Processor` class has been made final
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
* removed `ConfigCachePass`
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added `setDeprecated()` method to indicate a deprecated node
|
||||
* added `XmlUtils::parse()` method to parse an XML string
|
||||
* deprecated `ConfigCachePass`
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* added `ReflectionClassResource` class
|
||||
* added second `$exists` constructor argument to `ClassExistenceResource`
|
||||
* made `ClassExistenceResource` work with interfaces and traits
|
||||
* added `ConfigCachePass` (originally in FrameworkBundle)
|
||||
* added `castToArray()` helper to turn any config value into an array
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
||||
* removed `ReferenceDumper` class
|
||||
* removed the `ResourceInterface::isFresh()` method
|
||||
* removed `BCResourceInterfaceChecker` class
|
||||
* removed `ResourceInterface::getResource()` method
|
||||
|
||||
2.8.0
|
||||
-----
|
||||
|
||||
The edge case of defining just one value for nodes of type Enum is now allowed:
|
||||
|
||||
```php
|
||||
$rootNode
|
||||
->children()
|
||||
->enumNode('variable')
|
||||
->values(['value'])
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
```
|
||||
|
||||
Before: `InvalidArgumentException` (variable must contain at least two
|
||||
distinct elements).
|
||||
After: the code will work as expected and it will restrict the values of the
|
||||
`variable` option to just `value`.
|
||||
|
||||
* deprecated the `ResourceInterface::isFresh()` method. If you implement custom resource types and they
|
||||
can be validated that way, make them implement the new `SelfCheckingResourceInterface`.
|
||||
* deprecated the getResource() method in ResourceInterface. You can still call this method
|
||||
on concrete classes implementing the interface, but it does not make sense at the interface
|
||||
level as you need to know about the particular type of resource at hand to understand the
|
||||
semantics of the returned value.
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
||||
* added `ConfigCacheInterface`, `ConfigCacheFactoryInterface` and a basic `ConfigCacheFactory`
|
||||
implementation to delegate creation of ConfigCache instances
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
* added `ArrayNodeDefinition::canBeEnabled()` and `ArrayNodeDefinition::canBeDisabled()`
|
||||
to ease configuration when some sections are respectively disabled / enabled
|
||||
by default.
|
||||
* added a `normalizeKeys()` method for array nodes (to avoid key normalization)
|
||||
* added numerical type handling for config definitions
|
||||
* added convenience methods for optional configuration sections to `ArrayNodeDefinition`
|
||||
* added a utils class for XML manipulations
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
* added a way to add documentation on configuration
|
||||
* implemented `Serializable` on resources
|
||||
* `LoaderResolverInterface` is now used instead of `LoaderResolver` for type
|
||||
hinting
|
60
plugins/simplesaml/lib/vendor/symfony/config/ConfigCache.php
vendored
Normal file
60
plugins/simplesaml/lib/vendor/symfony/config/ConfigCache.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
use Symfony\Component\Config\Resource\SelfCheckingResourceChecker;
|
||||
|
||||
/**
|
||||
* ConfigCache caches arbitrary content in files on disk.
|
||||
*
|
||||
* When in debug mode, those metadata resources that implement
|
||||
* \Symfony\Component\Config\Resource\SelfCheckingResourceInterface will
|
||||
* be used to check cache freshness.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
class ConfigCache extends ResourceCheckerConfigCache
|
||||
{
|
||||
private bool $debug;
|
||||
|
||||
/**
|
||||
* @param string $file The absolute cache path
|
||||
* @param bool $debug Whether debugging is enabled or not
|
||||
*/
|
||||
public function __construct(string $file, bool $debug)
|
||||
{
|
||||
$this->debug = $debug;
|
||||
|
||||
$checkers = [];
|
||||
if (true === $this->debug) {
|
||||
$checkers = [new SelfCheckingResourceChecker()];
|
||||
}
|
||||
|
||||
parent::__construct($file, $checkers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the cache is still fresh.
|
||||
*
|
||||
* This implementation always returns true when debug is off and the
|
||||
* cache file exists.
|
||||
*/
|
||||
public function isFresh(): bool
|
||||
{
|
||||
if (!$this->debug && is_file($this->getPath())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::isFresh();
|
||||
}
|
||||
}
|
44
plugins/simplesaml/lib/vendor/symfony/config/ConfigCacheFactory.php
vendored
Normal file
44
plugins/simplesaml/lib/vendor/symfony/config/ConfigCacheFactory.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
/**
|
||||
* Basic implementation of ConfigCacheFactoryInterface that
|
||||
* creates an instance of the default ConfigCache.
|
||||
*
|
||||
* This factory and/or cache <em>do not</em> support cache validation
|
||||
* by means of ResourceChecker instances (that is, service-based).
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
class ConfigCacheFactory implements ConfigCacheFactoryInterface
|
||||
{
|
||||
private bool $debug;
|
||||
|
||||
/**
|
||||
* @param bool $debug The debug flag to pass to ConfigCache
|
||||
*/
|
||||
public function __construct(bool $debug)
|
||||
{
|
||||
$this->debug = $debug;
|
||||
}
|
||||
|
||||
public function cache(string $file, callable $callback): ConfigCacheInterface
|
||||
{
|
||||
$cache = new ConfigCache($file, $this->debug);
|
||||
if (!$cache->isFresh()) {
|
||||
$callback($cache);
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
}
|
30
plugins/simplesaml/lib/vendor/symfony/config/ConfigCacheFactoryInterface.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/config/ConfigCacheFactoryInterface.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
/**
|
||||
* Interface for a ConfigCache factory. This factory creates
|
||||
* an instance of ConfigCacheInterface and initializes the
|
||||
* cache if necessary.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
interface ConfigCacheFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a cache instance and (re-)initializes it if necessary.
|
||||
*
|
||||
* @param string $file The absolute cache file path
|
||||
* @param callable $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback
|
||||
*/
|
||||
public function cache(string $file, callable $callable): ConfigCacheInterface;
|
||||
}
|
47
plugins/simplesaml/lib/vendor/symfony/config/ConfigCacheInterface.php
vendored
Normal file
47
plugins/simplesaml/lib/vendor/symfony/config/ConfigCacheInterface.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
|
||||
/**
|
||||
* Interface for ConfigCache.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
interface ConfigCacheInterface
|
||||
{
|
||||
/**
|
||||
* Gets the cache file path.
|
||||
*/
|
||||
public function getPath(): string;
|
||||
|
||||
/**
|
||||
* Checks if the cache is still fresh.
|
||||
*
|
||||
* This check should take the metadata passed to the write() method into consideration.
|
||||
*/
|
||||
public function isFresh(): bool;
|
||||
|
||||
/**
|
||||
* Writes the given content into the cache file. Metadata will be stored
|
||||
* independently and can be used to check cache freshness at a later time.
|
||||
*
|
||||
* @param string $content The content to write into the cache
|
||||
* @param ResourceInterface[]|null $metadata An array of ResourceInterface instances
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException When the cache file cannot be written
|
||||
*/
|
||||
public function write(string $content, ?array $metadata = null);
|
||||
}
|
402
plugins/simplesaml/lib/vendor/symfony/config/Definition/ArrayNode.php
vendored
Normal file
402
plugins/simplesaml/lib/vendor/symfony/config/Definition/ArrayNode.php
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
|
||||
|
||||
/**
|
||||
* Represents an Array node in the config tree.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
{
|
||||
protected $xmlRemappings = [];
|
||||
protected $children = [];
|
||||
protected $allowFalse = false;
|
||||
protected $allowNewKeys = true;
|
||||
protected $addIfNotSet = false;
|
||||
protected $performDeepMerging = true;
|
||||
protected $ignoreExtraKeys = false;
|
||||
protected $removeExtraKeys = true;
|
||||
protected $normalizeKeys = true;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setNormalizeKeys(bool $normalizeKeys)
|
||||
{
|
||||
$this->normalizeKeys = $normalizeKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
|
||||
* After running this method, all keys are normalized to foo_bar.
|
||||
*
|
||||
* If you have a mixed key like foo-bar_moo, it will not be altered.
|
||||
* The key will also not be altered if the target key already exists.
|
||||
*/
|
||||
protected function preNormalize(mixed $value): mixed
|
||||
{
|
||||
if (!$this->normalizeKeys || !\is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$normalized = [];
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
if (str_contains($k, '-') && !str_contains($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
|
||||
$normalized[$normalizedKey] = $v;
|
||||
} else {
|
||||
$normalized[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the children of this node.
|
||||
*
|
||||
* @return array<string, NodeInterface>
|
||||
*/
|
||||
public function getChildren(): array
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the xml remappings that should be performed.
|
||||
*
|
||||
* @param array $remappings An array of the form [[string, string]]
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setXmlRemappings(array $remappings)
|
||||
{
|
||||
$this->xmlRemappings = $remappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the xml remappings that should be performed.
|
||||
*
|
||||
* @return array an array of the form [[string, string]]
|
||||
*/
|
||||
public function getXmlRemappings(): array
|
||||
{
|
||||
return $this->xmlRemappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to add default values for this array if it has not been
|
||||
* defined in any of the configuration files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAddIfNotSet(bool $boolean)
|
||||
{
|
||||
$this->addIfNotSet = $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether false is allowed as value indicating that the array should be unset.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAllowFalse(bool $allow)
|
||||
{
|
||||
$this->allowFalse = $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether new keys can be defined in subsequent configurations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAllowNewKeys(bool $allow)
|
||||
{
|
||||
$this->allowNewKeys = $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if deep merging should occur.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPerformDeepMerging(bool $boolean)
|
||||
{
|
||||
$this->performDeepMerging = $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether extra keys should just be ignored without an exception.
|
||||
*
|
||||
* @param bool $boolean To allow extra keys
|
||||
* @param bool $remove To remove extra keys
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setIgnoreExtraKeys(bool $boolean, bool $remove = true)
|
||||
{
|
||||
$this->ignoreExtraKeys = $boolean;
|
||||
$this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when extra keys should be ignored without an exception.
|
||||
*/
|
||||
public function shouldIgnoreExtraKeys(): bool
|
||||
{
|
||||
return $this->ignoreExtraKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setName(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function hasDefaultValue(): bool
|
||||
{
|
||||
return $this->addIfNotSet;
|
||||
}
|
||||
|
||||
public function getDefaultValue(): mixed
|
||||
{
|
||||
if (!$this->hasDefaultValue()) {
|
||||
throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
|
||||
}
|
||||
|
||||
$defaults = [];
|
||||
foreach ($this->children as $name => $child) {
|
||||
if ($child->hasDefaultValue()) {
|
||||
$defaults[$name] = $child->getDefaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child node.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException when the child node has no name
|
||||
* @throws \InvalidArgumentException when the child node's name is not unique
|
||||
*/
|
||||
public function addChild(NodeInterface $node)
|
||||
{
|
||||
$name = $node->getName();
|
||||
if ('' === $name) {
|
||||
throw new \InvalidArgumentException('Child nodes must be named.');
|
||||
}
|
||||
if (isset($this->children[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
|
||||
}
|
||||
|
||||
$this->children[$name] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws UnsetKeyException
|
||||
* @throws InvalidConfigurationException if the node doesn't have enough children
|
||||
*/
|
||||
protected function finalizeValue(mixed $value): mixed
|
||||
{
|
||||
if (false === $value) {
|
||||
throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), json_encode($value)));
|
||||
}
|
||||
|
||||
foreach ($this->children as $name => $child) {
|
||||
if (!\array_key_exists($name, $value)) {
|
||||
if ($child->isRequired()) {
|
||||
$message = sprintf('The child config "%s" under "%s" must be configured', $name, $this->getPath());
|
||||
if ($child->getInfo()) {
|
||||
$message .= sprintf(': %s', $child->getInfo());
|
||||
} else {
|
||||
$message .= '.';
|
||||
}
|
||||
$ex = new InvalidConfigurationException($message);
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
if ($child->hasDefaultValue()) {
|
||||
$value[$name] = $child->getDefaultValue();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($child->isDeprecated()) {
|
||||
$deprecation = $child->getDeprecation($name, $this->getPath());
|
||||
trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
|
||||
}
|
||||
|
||||
try {
|
||||
$value[$name] = $child->finalize($value[$name]);
|
||||
} catch (UnsetKeyException) {
|
||||
unset($value[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
if (!\is_array($value) && (!$this->allowFalse || false !== $value)) {
|
||||
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "array", but got "%s"', $this->getPath(), get_debug_type($value)));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$ex->addHint($hint);
|
||||
}
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidConfigurationException
|
||||
*/
|
||||
protected function normalizeValue(mixed $value): mixed
|
||||
{
|
||||
if (false === $value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = $this->remapXml($value);
|
||||
|
||||
$normalized = [];
|
||||
foreach ($value as $name => $val) {
|
||||
if (isset($this->children[$name])) {
|
||||
try {
|
||||
$normalized[$name] = $this->children[$name]->normalize($val);
|
||||
} catch (UnsetKeyException) {
|
||||
}
|
||||
unset($value[$name]);
|
||||
} elseif (!$this->removeExtraKeys) {
|
||||
$normalized[$name] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
// if extra fields are present, throw exception
|
||||
if (\count($value) && !$this->ignoreExtraKeys) {
|
||||
$proposals = array_keys($this->children);
|
||||
sort($proposals);
|
||||
$guesses = [];
|
||||
|
||||
foreach (array_keys($value) as $subject) {
|
||||
$minScore = \INF;
|
||||
foreach ($proposals as $proposal) {
|
||||
$distance = levenshtein($subject, $proposal);
|
||||
if ($distance <= $minScore && $distance < 3) {
|
||||
$guesses[$proposal] = $distance;
|
||||
$minScore = $distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === \count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());
|
||||
|
||||
if (\count($guesses)) {
|
||||
asort($guesses);
|
||||
$msg .= sprintf('. Did you mean "%s"?', implode('", "', array_keys($guesses)));
|
||||
} else {
|
||||
$msg .= sprintf('. Available option%s %s "%s".', 1 === \count($proposals) ? '' : 's', 1 === \count($proposals) ? 'is' : 'are', implode('", "', $proposals));
|
||||
}
|
||||
|
||||
$ex = new InvalidConfigurationException($msg);
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remaps multiple singular values to a single plural value.
|
||||
*/
|
||||
protected function remapXml(array $value): array
|
||||
{
|
||||
foreach ($this->xmlRemappings as [$singular, $plural]) {
|
||||
if (!isset($value[$singular])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
|
||||
unset($value[$singular]);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidConfigurationException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function mergeValues(mixed $leftSide, mixed $rightSide): mixed
|
||||
{
|
||||
if (false === $rightSide) {
|
||||
// if this is still false after the last config has been merged the
|
||||
// finalization pass will take care of removing this key entirely
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === $leftSide || !$this->performDeepMerging) {
|
||||
return $rightSide;
|
||||
}
|
||||
|
||||
foreach ($rightSide as $k => $v) {
|
||||
// no conflict
|
||||
if (!\array_key_exists($k, $leftSide)) {
|
||||
if (!$this->allowNewKeys) {
|
||||
$ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file. If you are trying to overwrite an element, make sure you redefine it with the same name.', $this->getPath()));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
$leftSide[$k] = $v;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($this->children[$k])) {
|
||||
if (!$this->ignoreExtraKeys || $this->removeExtraKeys) {
|
||||
throw new \RuntimeException('merge() expects a normalized config array.');
|
||||
}
|
||||
|
||||
$leftSide[$k] = $v;
|
||||
continue;
|
||||
}
|
||||
|
||||
$leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
|
||||
}
|
||||
|
||||
return $leftSide;
|
||||
}
|
||||
|
||||
protected function allowPlaceholders(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
542
plugins/simplesaml/lib/vendor/symfony/config/Definition/BaseNode.php
vendored
Normal file
542
plugins/simplesaml/lib/vendor/symfony/config/Definition/BaseNode.php
vendored
Normal file
@@ -0,0 +1,542 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
|
||||
|
||||
/**
|
||||
* The base node class.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class BaseNode implements NodeInterface
|
||||
{
|
||||
public const DEFAULT_PATH_SEPARATOR = '.';
|
||||
|
||||
private static array $placeholderUniquePrefixes = [];
|
||||
private static array $placeholders = [];
|
||||
|
||||
protected $name;
|
||||
protected $parent;
|
||||
protected $normalizationClosures = [];
|
||||
protected $normalizedTypes = [];
|
||||
protected $finalValidationClosures = [];
|
||||
protected $allowOverwrite = true;
|
||||
protected $required = false;
|
||||
protected $deprecation = [];
|
||||
protected $equivalentValues = [];
|
||||
protected $attributes = [];
|
||||
protected $pathSeparator;
|
||||
|
||||
private mixed $handlingPlaceholder = null;
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException if the name contains a period
|
||||
*/
|
||||
public function __construct(?string $name, ?NodeInterface $parent = null, string $pathSeparator = self::DEFAULT_PATH_SEPARATOR)
|
||||
{
|
||||
if (str_contains($name = (string) $name, $pathSeparator)) {
|
||||
throw new \InvalidArgumentException('The name must not contain ".'.$pathSeparator.'".');
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
$this->parent = $parent;
|
||||
$this->pathSeparator = $pathSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register possible (dummy) values for a dynamic placeholder value.
|
||||
*
|
||||
* Matching configuration values will be processed with a provided value, one by one. After a provided value is
|
||||
* successfully processed the configuration value is returned as is, thus preserving the placeholder.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function setPlaceholder(string $placeholder, array $values): void
|
||||
{
|
||||
if (!$values) {
|
||||
throw new \InvalidArgumentException('At least one value must be provided.');
|
||||
}
|
||||
|
||||
self::$placeholders[$placeholder] = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a common prefix for dynamic placeholder values.
|
||||
*
|
||||
* Matching configuration values will be skipped from being processed and are returned as is, thus preserving the
|
||||
* placeholder. An exact match provided by {@see setPlaceholder()} might take precedence.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function setPlaceholderUniquePrefix(string $prefix): void
|
||||
{
|
||||
self::$placeholderUniquePrefixes[] = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all current placeholders available.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function resetPlaceholders(): void
|
||||
{
|
||||
self::$placeholderUniquePrefixes = [];
|
||||
self::$placeholders = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setAttribute(string $key, mixed $value)
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
|
||||
public function getAttribute(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return $this->attributes[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function hasAttribute(string $key): bool
|
||||
{
|
||||
return isset($this->attributes[$key]);
|
||||
}
|
||||
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeAttribute(string $key)
|
||||
{
|
||||
unset($this->attributes[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an info message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setInfo(string $info)
|
||||
{
|
||||
$this->setAttribute('info', $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns info message.
|
||||
*/
|
||||
public function getInfo(): ?string
|
||||
{
|
||||
return $this->getAttribute('info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the example configuration for this node.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setExample(string|array $example)
|
||||
{
|
||||
$this->setAttribute('example', $example);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the example configuration for this node.
|
||||
*/
|
||||
public function getExample(): string|array|null
|
||||
{
|
||||
return $this->getAttribute('example');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an equivalent value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addEquivalentValue(mixed $originalValue, mixed $equivalentValue)
|
||||
{
|
||||
$this->equivalentValues[] = [$originalValue, $equivalentValue];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this node as required.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setRequired(bool $boolean)
|
||||
{
|
||||
$this->required = $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this node as deprecated.
|
||||
*
|
||||
* You can use %node% and %path% placeholders in your message to display,
|
||||
* respectively, the node name and its complete path.
|
||||
*
|
||||
* @param string $package The name of the composer package that is triggering the deprecation
|
||||
* @param string $version The version of the package that introduced the deprecation
|
||||
* @param string $message the deprecation message to use
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDeprecated(string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.')
|
||||
{
|
||||
$this->deprecation = [
|
||||
'package' => $package,
|
||||
'version' => $version,
|
||||
'message' => $message,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this node can be overridden.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAllowOverwrite(bool $allow)
|
||||
{
|
||||
$this->allowOverwrite = $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the closures used for normalization.
|
||||
*
|
||||
* @param \Closure[] $closures An array of Closures used for normalization
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setNormalizationClosures(array $closures)
|
||||
{
|
||||
$this->normalizationClosures = $closures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of types supported by normalization.
|
||||
*
|
||||
* see ExprBuilder::TYPE_* constants.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setNormalizedTypes(array $types)
|
||||
{
|
||||
$this->normalizedTypes = $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of types supported by normalization.
|
||||
*
|
||||
* see ExprBuilder::TYPE_* constants.
|
||||
*/
|
||||
public function getNormalizedTypes(): array
|
||||
{
|
||||
return $this->normalizedTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the closures used for final validation.
|
||||
*
|
||||
* @param \Closure[] $closures An array of Closures used for final validation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFinalValidationClosures(array $closures)
|
||||
{
|
||||
$this->finalValidationClosures = $closures;
|
||||
}
|
||||
|
||||
public function isRequired(): bool
|
||||
{
|
||||
return $this->required;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this node is deprecated.
|
||||
*/
|
||||
public function isDeprecated(): bool
|
||||
{
|
||||
return (bool) $this->deprecation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $node The configuration node name
|
||||
* @param string $path The path of the node
|
||||
*/
|
||||
public function getDeprecation(string $node, string $path): array
|
||||
{
|
||||
return [
|
||||
'package' => $this->deprecation['package'],
|
||||
'version' => $this->deprecation['version'],
|
||||
'message' => strtr($this->deprecation['message'], ['%node%' => $node, '%path%' => $path]),
|
||||
];
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
return $this->parent->getPath().$this->pathSeparator.$this->name;
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
final public function merge(mixed $leftSide, mixed $rightSide): mixed
|
||||
{
|
||||
if (!$this->allowOverwrite) {
|
||||
throw new ForbiddenOverwriteException(sprintf('Configuration path "%s" cannot be overwritten. You have to define all options for this path, and any of its sub-paths in one configuration section.', $this->getPath()));
|
||||
}
|
||||
|
||||
if ($leftSide !== $leftPlaceholders = self::resolvePlaceholderValue($leftSide)) {
|
||||
foreach ($leftPlaceholders as $leftPlaceholder) {
|
||||
$this->handlingPlaceholder = $leftSide;
|
||||
try {
|
||||
$this->merge($leftPlaceholder, $rightSide);
|
||||
} finally {
|
||||
$this->handlingPlaceholder = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $rightSide;
|
||||
}
|
||||
|
||||
if ($rightSide !== $rightPlaceholders = self::resolvePlaceholderValue($rightSide)) {
|
||||
foreach ($rightPlaceholders as $rightPlaceholder) {
|
||||
$this->handlingPlaceholder = $rightSide;
|
||||
try {
|
||||
$this->merge($leftSide, $rightPlaceholder);
|
||||
} finally {
|
||||
$this->handlingPlaceholder = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $rightSide;
|
||||
}
|
||||
|
||||
$this->doValidateType($leftSide);
|
||||
$this->doValidateType($rightSide);
|
||||
|
||||
return $this->mergeValues($leftSide, $rightSide);
|
||||
}
|
||||
|
||||
final public function normalize(mixed $value): mixed
|
||||
{
|
||||
$value = $this->preNormalize($value);
|
||||
|
||||
// run custom normalization closures
|
||||
foreach ($this->normalizationClosures as $closure) {
|
||||
$value = $closure($value);
|
||||
}
|
||||
|
||||
// resolve placeholder value
|
||||
if ($value !== $placeholders = self::resolvePlaceholderValue($value)) {
|
||||
foreach ($placeholders as $placeholder) {
|
||||
$this->handlingPlaceholder = $value;
|
||||
try {
|
||||
$this->normalize($placeholder);
|
||||
} finally {
|
||||
$this->handlingPlaceholder = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// replace value with their equivalent
|
||||
foreach ($this->equivalentValues as $data) {
|
||||
if ($data[0] === $value) {
|
||||
$value = $data[1];
|
||||
}
|
||||
}
|
||||
|
||||
// validate type
|
||||
$this->doValidateType($value);
|
||||
|
||||
// normalize value
|
||||
return $this->normalizeValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the value before any other normalization is applied.
|
||||
*/
|
||||
protected function preNormalize(mixed $value): mixed
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns parent node for this node.
|
||||
*/
|
||||
public function getParent(): ?NodeInterface
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
final public function finalize(mixed $value): mixed
|
||||
{
|
||||
if ($value !== $placeholders = self::resolvePlaceholderValue($value)) {
|
||||
foreach ($placeholders as $placeholder) {
|
||||
$this->handlingPlaceholder = $value;
|
||||
try {
|
||||
$this->finalize($placeholder);
|
||||
} finally {
|
||||
$this->handlingPlaceholder = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->doValidateType($value);
|
||||
|
||||
$value = $this->finalizeValue($value);
|
||||
|
||||
// Perform validation on the final value if a closure has been set.
|
||||
// The closure is also allowed to return another value.
|
||||
foreach ($this->finalValidationClosures as $closure) {
|
||||
try {
|
||||
$value = $closure($value);
|
||||
} catch (Exception $e) {
|
||||
if ($e instanceof UnsetKeyException && null !== $this->handlingPlaceholder) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": ', $this->getPath()).$e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the type of a Node.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws InvalidTypeException when the value is invalid
|
||||
*/
|
||||
abstract protected function validateType(mixed $value);
|
||||
|
||||
/**
|
||||
* Normalizes the value.
|
||||
*/
|
||||
abstract protected function normalizeValue(mixed $value): mixed;
|
||||
|
||||
/**
|
||||
* Merges two values together.
|
||||
*/
|
||||
abstract protected function mergeValues(mixed $leftSide, mixed $rightSide): mixed;
|
||||
|
||||
/**
|
||||
* Finalizes a value.
|
||||
*/
|
||||
abstract protected function finalizeValue(mixed $value): mixed;
|
||||
|
||||
/**
|
||||
* Tests if placeholder values are allowed for this node.
|
||||
*/
|
||||
protected function allowPlaceholders(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a placeholder is being handled currently.
|
||||
*/
|
||||
protected function isHandlingPlaceholder(): bool
|
||||
{
|
||||
return null !== $this->handlingPlaceholder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets allowed dynamic types for this node.
|
||||
*/
|
||||
protected function getValidPlaceholderTypes(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private static function resolvePlaceholderValue(mixed $value): mixed
|
||||
{
|
||||
if (\is_string($value)) {
|
||||
if (isset(self::$placeholders[$value])) {
|
||||
return self::$placeholders[$value];
|
||||
}
|
||||
|
||||
foreach (self::$placeholderUniquePrefixes as $placeholderUniquePrefix) {
|
||||
if (str_starts_with($value, $placeholderUniquePrefix)) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function doValidateType(mixed $value): void
|
||||
{
|
||||
if (null !== $this->handlingPlaceholder && !$this->allowPlaceholders()) {
|
||||
$e = new InvalidTypeException(sprintf('A dynamic value is not compatible with a "%s" node type at path "%s".', static::class, $this->getPath()));
|
||||
$e->setPath($this->getPath());
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (null === $this->handlingPlaceholder || null === $value) {
|
||||
$this->validateType($value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$knownTypes = array_keys(self::$placeholders[$this->handlingPlaceholder]);
|
||||
$validTypes = $this->getValidPlaceholderTypes();
|
||||
|
||||
if ($validTypes && array_diff($knownTypes, $validTypes)) {
|
||||
$e = new InvalidTypeException(sprintf(
|
||||
'Invalid type for path "%s". Expected %s, but got %s.',
|
||||
$this->getPath(),
|
||||
1 === \count($validTypes) ? '"'.reset($validTypes).'"' : 'one of "'.implode('", "', $validTypes).'"',
|
||||
1 === \count($knownTypes) ? '"'.reset($knownTypes).'"' : 'one of "'.implode('", "', $knownTypes).'"'
|
||||
));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$e->addHint($hint);
|
||||
}
|
||||
$e->setPath($this->getPath());
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->validateType($value);
|
||||
}
|
||||
}
|
49
plugins/simplesaml/lib/vendor/symfony/config/Definition/BooleanNode.php
vendored
Normal file
49
plugins/simplesaml/lib/vendor/symfony/config/Definition/BooleanNode.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
|
||||
/**
|
||||
* This node represents a Boolean value in the config tree.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class BooleanNode extends ScalarNode
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
if (!\is_bool($value)) {
|
||||
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "bool", but got "%s".', $this->getPath(), get_debug_type($value)));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$ex->addHint($hint);
|
||||
}
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
protected function isValueEmpty(mixed $value): bool
|
||||
{
|
||||
// a boolean value cannot be empty
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getValidPlaceholderTypes(): array
|
||||
{
|
||||
return ['bool'];
|
||||
}
|
||||
}
|
516
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php
vendored
Normal file
516
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,516 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\ArrayNode;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
use Symfony\Component\Config\Definition\PrototypedArrayNode;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining an array node.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
|
||||
{
|
||||
protected $performDeepMerging = true;
|
||||
protected $ignoreExtraKeys = false;
|
||||
protected $removeExtraKeys = true;
|
||||
protected $children = [];
|
||||
protected $prototype;
|
||||
protected $atLeastOne = false;
|
||||
protected $allowNewKeys = true;
|
||||
protected $key;
|
||||
protected $removeKeyItem;
|
||||
protected $addDefaults = false;
|
||||
protected $addDefaultChildren = false;
|
||||
protected $nodeBuilder;
|
||||
protected $normalizeKeys = true;
|
||||
|
||||
public function __construct(?string $name, ?NodeParentInterface $parent = null)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
$this->nullEquivalent = [];
|
||||
$this->trueEquivalent = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setBuilder(NodeBuilder $builder)
|
||||
{
|
||||
$this->nodeBuilder = $builder;
|
||||
}
|
||||
|
||||
public function children(): NodeBuilder
|
||||
{
|
||||
return $this->getNodeBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a prototype for child nodes.
|
||||
*/
|
||||
public function prototype(string $type): NodeDefinition
|
||||
{
|
||||
return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
|
||||
}
|
||||
|
||||
public function variablePrototype(): VariableNodeDefinition
|
||||
{
|
||||
return $this->prototype('variable');
|
||||
}
|
||||
|
||||
public function scalarPrototype(): ScalarNodeDefinition
|
||||
{
|
||||
return $this->prototype('scalar');
|
||||
}
|
||||
|
||||
public function booleanPrototype(): BooleanNodeDefinition
|
||||
{
|
||||
return $this->prototype('boolean');
|
||||
}
|
||||
|
||||
public function integerPrototype(): IntegerNodeDefinition
|
||||
{
|
||||
return $this->prototype('integer');
|
||||
}
|
||||
|
||||
public function floatPrototype(): FloatNodeDefinition
|
||||
{
|
||||
return $this->prototype('float');
|
||||
}
|
||||
|
||||
public function arrayPrototype(): self
|
||||
{
|
||||
return $this->prototype('array');
|
||||
}
|
||||
|
||||
public function enumPrototype(): EnumNodeDefinition
|
||||
{
|
||||
return $this->prototype('enum');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the default value if the node is not set in the configuration.
|
||||
*
|
||||
* This method is applicable to concrete nodes only (not to prototype nodes).
|
||||
* If this function has been called and the node is not set during the finalization
|
||||
* phase, it's default value will be derived from its children default values.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDefaultsIfNotSet(): static
|
||||
{
|
||||
$this->addDefaults = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds children with a default value when none are defined.
|
||||
*
|
||||
* This method is applicable to prototype nodes only.
|
||||
*
|
||||
* @param int|string|array|null $children The number of children|The child name|The children names to be added
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDefaultChildrenIfNoneSet(int|string|array|null $children = null): static
|
||||
{
|
||||
$this->addDefaultChildren = $children;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires the node to have at least one element.
|
||||
*
|
||||
* This method is applicable to prototype nodes only.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function requiresAtLeastOneElement(): static
|
||||
{
|
||||
$this->atLeastOne = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallows adding news keys in a subsequent configuration.
|
||||
*
|
||||
* If used all keys have to be defined in the same configuration file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disallowNewKeysInSubsequentConfigs(): static
|
||||
{
|
||||
$this->allowNewKeys = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a normalization rule for XML configurations.
|
||||
*
|
||||
* @param string $singular The key to remap
|
||||
* @param string|null $plural The plural of the key for irregular plurals
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fixXmlConfig(string $singular, ?string $plural = null): static
|
||||
{
|
||||
$this->normalization()->remap($singular, $plural);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute which value is to be used as key.
|
||||
*
|
||||
* This is useful when you have an indexed array that should be an
|
||||
* associative array. You can select an item from within the array
|
||||
* to be the key of the particular item. For example, if "id" is the
|
||||
* "key", then:
|
||||
*
|
||||
* [
|
||||
* ['id' => 'my_name', 'foo' => 'bar'],
|
||||
* ];
|
||||
*
|
||||
* becomes
|
||||
*
|
||||
* [
|
||||
* 'my_name' => ['foo' => 'bar'],
|
||||
* ];
|
||||
*
|
||||
* If you'd like "'id' => 'my_name'" to still be present in the resulting
|
||||
* array, then you can set the second argument of this method to false.
|
||||
*
|
||||
* This method is applicable to prototype nodes only.
|
||||
*
|
||||
* @param string $name The name of the key
|
||||
* @param bool $removeKeyItem Whether or not the key item should be removed
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useAttributeAsKey(string $name, bool $removeKeyItem = true): static
|
||||
{
|
||||
$this->key = $name;
|
||||
$this->removeKeyItem = $removeKeyItem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the node can be unset.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function canBeUnset(bool $allow = true): static
|
||||
{
|
||||
$this->merge()->allowUnset($allow);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an "enabled" boolean to enable the current section.
|
||||
*
|
||||
* By default, the section is disabled. If any configuration is specified then
|
||||
* the node will be automatically enabled:
|
||||
*
|
||||
* enableableArrayNode: {enabled: true, ...} # The config is enabled & default values get overridden
|
||||
* enableableArrayNode: ~ # The config is enabled & use the default values
|
||||
* enableableArrayNode: true # The config is enabled & use the default values
|
||||
* enableableArrayNode: {other: value, ...} # The config is enabled & default values get overridden
|
||||
* enableableArrayNode: {enabled: false, ...} # The config is disabled
|
||||
* enableableArrayNode: false # The config is disabled
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function canBeEnabled(): static
|
||||
{
|
||||
$this
|
||||
->addDefaultsIfNotSet()
|
||||
->treatFalseLike(['enabled' => false])
|
||||
->treatTrueLike(['enabled' => true])
|
||||
->treatNullLike(['enabled' => true])
|
||||
->beforeNormalization()
|
||||
->ifArray()
|
||||
->then(function (array $v) {
|
||||
$v['enabled'] ??= true;
|
||||
|
||||
return $v;
|
||||
})
|
||||
->end()
|
||||
->children()
|
||||
->booleanNode('enabled')
|
||||
->defaultFalse()
|
||||
;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an "enabled" boolean to enable the current section.
|
||||
*
|
||||
* By default, the section is enabled.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function canBeDisabled(): static
|
||||
{
|
||||
$this
|
||||
->addDefaultsIfNotSet()
|
||||
->treatFalseLike(['enabled' => false])
|
||||
->treatTrueLike(['enabled' => true])
|
||||
->treatNullLike(['enabled' => true])
|
||||
->children()
|
||||
->booleanNode('enabled')
|
||||
->defaultTrue()
|
||||
;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the deep merging of the node.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function performNoDeepMerging(): static
|
||||
{
|
||||
$this->performDeepMerging = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows extra config keys to be specified under an array without
|
||||
* throwing an exception.
|
||||
*
|
||||
* Those config values are ignored and removed from the resulting
|
||||
* array. This should be used only in special cases where you want
|
||||
* to send an entire configuration array through a special tree that
|
||||
* processes only part of the array.
|
||||
*
|
||||
* @param bool $remove Whether to remove the extra keys
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ignoreExtraKeys(bool $remove = true): static
|
||||
{
|
||||
$this->ignoreExtraKeys = true;
|
||||
$this->removeExtraKeys = $remove;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to enable key normalization.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function normalizeKeys(bool $bool): static
|
||||
{
|
||||
$this->normalizeKeys = $bool;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function append(NodeDefinition $node): static
|
||||
{
|
||||
$this->children[$node->name] = $node->setParent($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a node builder to be used to add children and prototype.
|
||||
*/
|
||||
protected function getNodeBuilder(): NodeBuilder
|
||||
{
|
||||
$this->nodeBuilder ??= new NodeBuilder();
|
||||
|
||||
return $this->nodeBuilder->setParent($this);
|
||||
}
|
||||
|
||||
protected function createNode(): NodeInterface
|
||||
{
|
||||
if (!isset($this->prototype)) {
|
||||
$node = new ArrayNode($this->name, $this->parent, $this->pathSeparator);
|
||||
|
||||
$this->validateConcreteNode($node);
|
||||
|
||||
$node->setAddIfNotSet($this->addDefaults);
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$child->parent = $node;
|
||||
$node->addChild($child->getNode());
|
||||
}
|
||||
} else {
|
||||
$node = new PrototypedArrayNode($this->name, $this->parent, $this->pathSeparator);
|
||||
|
||||
$this->validatePrototypeNode($node);
|
||||
|
||||
if (null !== $this->key) {
|
||||
$node->setKeyAttribute($this->key, $this->removeKeyItem);
|
||||
}
|
||||
|
||||
if (true === $this->atLeastOne || false === $this->allowEmptyValue) {
|
||||
$node->setMinNumberOfElements(1);
|
||||
}
|
||||
|
||||
if ($this->default) {
|
||||
if (!\is_array($this->defaultValue)) {
|
||||
throw new \InvalidArgumentException(sprintf('%s: the default value of an array node has to be an array.', $node->getPath()));
|
||||
}
|
||||
|
||||
$node->setDefaultValue($this->defaultValue);
|
||||
}
|
||||
|
||||
if (false !== $this->addDefaultChildren) {
|
||||
$node->setAddChildrenIfNoneSet($this->addDefaultChildren);
|
||||
if ($this->prototype instanceof static && !isset($this->prototype->prototype)) {
|
||||
$this->prototype->addDefaultsIfNotSet();
|
||||
}
|
||||
}
|
||||
|
||||
$this->prototype->parent = $node;
|
||||
$node->setPrototype($this->prototype->getNode());
|
||||
}
|
||||
|
||||
$node->setAllowNewKeys($this->allowNewKeys);
|
||||
$node->addEquivalentValue(null, $this->nullEquivalent);
|
||||
$node->addEquivalentValue(true, $this->trueEquivalent);
|
||||
$node->addEquivalentValue(false, $this->falseEquivalent);
|
||||
$node->setPerformDeepMerging($this->performDeepMerging);
|
||||
$node->setRequired($this->required);
|
||||
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
|
||||
$node->setNormalizeKeys($this->normalizeKeys);
|
||||
|
||||
if ($this->deprecation) {
|
||||
$node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
|
||||
}
|
||||
|
||||
if (isset($this->normalization)) {
|
||||
$node->setNormalizationClosures($this->normalization->before);
|
||||
$node->setNormalizedTypes($this->normalization->declaredTypes);
|
||||
$node->setXmlRemappings($this->normalization->remappings);
|
||||
}
|
||||
|
||||
if (isset($this->merge)) {
|
||||
$node->setAllowOverwrite($this->merge->allowOverwrite);
|
||||
$node->setAllowFalse($this->merge->allowFalse);
|
||||
}
|
||||
|
||||
if (isset($this->validation)) {
|
||||
$node->setFinalValidationClosures($this->validation->rules);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the configuration of a concrete node.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws InvalidDefinitionException
|
||||
*/
|
||||
protected function validateConcreteNode(ArrayNode $node)
|
||||
{
|
||||
$path = $node->getPath();
|
||||
|
||||
if (null !== $this->key) {
|
||||
throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s".', $path));
|
||||
}
|
||||
|
||||
if (false === $this->allowEmptyValue) {
|
||||
throw new InvalidDefinitionException(sprintf('->cannotBeEmpty() is not applicable to concrete nodes at path "%s".', $path));
|
||||
}
|
||||
|
||||
if (true === $this->atLeastOne) {
|
||||
throw new InvalidDefinitionException(sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s".', $path));
|
||||
}
|
||||
|
||||
if ($this->default) {
|
||||
throw new InvalidDefinitionException(sprintf('->defaultValue() is not applicable to concrete nodes at path "%s".', $path));
|
||||
}
|
||||
|
||||
if (false !== $this->addDefaultChildren) {
|
||||
throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s".', $path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the configuration of a prototype node.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws InvalidDefinitionException
|
||||
*/
|
||||
protected function validatePrototypeNode(PrototypedArrayNode $node)
|
||||
{
|
||||
$path = $node->getPath();
|
||||
|
||||
if ($this->addDefaults) {
|
||||
throw new InvalidDefinitionException(sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s".', $path));
|
||||
}
|
||||
|
||||
if (false !== $this->addDefaultChildren) {
|
||||
if ($this->default) {
|
||||
throw new InvalidDefinitionException(sprintf('A default value and default children might not be used together at path "%s".', $path));
|
||||
}
|
||||
|
||||
if (null !== $this->key && (null === $this->addDefaultChildren || \is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
|
||||
throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s".', $path));
|
||||
}
|
||||
|
||||
if (null === $this->key && (\is_string($this->addDefaultChildren) || \is_array($this->addDefaultChildren))) {
|
||||
throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s".', $path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeDefinition[]
|
||||
*/
|
||||
public function getChildNodeDefinitions(): array
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a node defined by the given $nodePath.
|
||||
*
|
||||
* @param string $nodePath The path of the node to find. e.g "doctrine.orm.mappings"
|
||||
*/
|
||||
public function find(string $nodePath): NodeDefinition
|
||||
{
|
||||
$firstPathSegment = (false === $pathSeparatorPos = strpos($nodePath, $this->pathSeparator))
|
||||
? $nodePath
|
||||
: substr($nodePath, 0, $pathSeparatorPos);
|
||||
|
||||
if (null === $node = ($this->children[$firstPathSegment] ?? null)) {
|
||||
throw new \RuntimeException(sprintf('Node with name "%s" does not exist in the current node "%s".', $firstPathSegment, $this->name));
|
||||
}
|
||||
|
||||
if (false === $pathSeparatorPos) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
return $node->find(substr($nodePath, $pathSeparatorPos + \strlen($this->pathSeparator)));
|
||||
}
|
||||
}
|
46
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php
vendored
Normal file
46
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\BooleanNode;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining a node.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class BooleanNodeDefinition extends ScalarNodeDefinition
|
||||
{
|
||||
public function __construct(?string $name, ?NodeParentInterface $parent = null)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
$this->nullEquivalent = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a Node.
|
||||
*/
|
||||
protected function instantiateNode(): BooleanNode
|
||||
{
|
||||
return new BooleanNode($this->name, $this->parent, $this->pathSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidDefinitionException
|
||||
*/
|
||||
public function cannotBeEmpty(): static
|
||||
{
|
||||
throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to BooleanNodeDefinition.');
|
||||
}
|
||||
}
|
27
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php
vendored
Normal file
27
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* An interface that can be implemented by nodes which build other nodes.
|
||||
*
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*/
|
||||
interface BuilderAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets a custom children builder.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setBuilder(NodeBuilder $builder);
|
||||
}
|
52
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php
vendored
Normal file
52
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\EnumNode;
|
||||
|
||||
/**
|
||||
* Enum Node Definition.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class EnumNodeDefinition extends ScalarNodeDefinition
|
||||
{
|
||||
private array $values;
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function values(array $values): static
|
||||
{
|
||||
if (!$values) {
|
||||
throw new \InvalidArgumentException('->values() must be called with at least one value.');
|
||||
}
|
||||
|
||||
$this->values = $values;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a Node.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function instantiateNode(): EnumNode
|
||||
{
|
||||
if (!isset($this->values)) {
|
||||
throw new \RuntimeException('You must call ->values() on enum nodes.');
|
||||
}
|
||||
|
||||
return new EnumNode($this->name, $this->parent, $this->values, $this->pathSeparator);
|
||||
}
|
||||
}
|
252
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ExprBuilder.php
vendored
Normal file
252
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ExprBuilder.php
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
|
||||
|
||||
/**
|
||||
* This class builds an if expression.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class ExprBuilder
|
||||
{
|
||||
public const TYPE_ANY = 'any';
|
||||
public const TYPE_STRING = 'string';
|
||||
public const TYPE_NULL = 'null';
|
||||
public const TYPE_ARRAY = 'array';
|
||||
|
||||
protected $node;
|
||||
|
||||
public $allowedTypes;
|
||||
public $ifPart;
|
||||
public $thenPart;
|
||||
|
||||
public function __construct(NodeDefinition $node)
|
||||
{
|
||||
$this->node = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the expression as being always used.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function always(?\Closure $then = null): static
|
||||
{
|
||||
$this->ifPart = static fn () => true;
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
|
||||
if (null !== $then) {
|
||||
$this->thenPart = $then;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a closure to use as tests.
|
||||
*
|
||||
* The default one tests if the value is true.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifTrue(?\Closure $closure = null): static
|
||||
{
|
||||
$this->ifPart = $closure ?? static fn ($v) => true === $v;
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the value is a string.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifString(): static
|
||||
{
|
||||
$this->ifPart = \is_string(...);
|
||||
$this->allowedTypes = self::TYPE_STRING;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the value is null.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifNull(): static
|
||||
{
|
||||
$this->ifPart = \is_null(...);
|
||||
$this->allowedTypes = self::TYPE_NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the value is empty.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifEmpty(): static
|
||||
{
|
||||
$this->ifPart = static fn ($v) => empty($v);
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the value is an array.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifArray(): static
|
||||
{
|
||||
$this->ifPart = \is_array(...);
|
||||
$this->allowedTypes = self::TYPE_ARRAY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the value is in an array.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifInArray(array $array): static
|
||||
{
|
||||
$this->ifPart = static fn ($v) => \in_array($v, $array, true);
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the value is not in an array.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifNotInArray(array $array): static
|
||||
{
|
||||
$this->ifPart = static fn ($v) => !\in_array($v, $array, true);
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms variables of any type into an array.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function castToArray(): static
|
||||
{
|
||||
$this->ifPart = static fn ($v) => !\is_array($v);
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
$this->thenPart = static fn ($v) => [$v];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the closure to run if the test pass.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function then(\Closure $closure): static
|
||||
{
|
||||
$this->thenPart = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a closure returning an empty array.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function thenEmptyArray(): static
|
||||
{
|
||||
$this->thenPart = static fn () => [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a closure marking the value as invalid at processing time.
|
||||
*
|
||||
* if you want to add the value of the node in your message just use a %s placeholder.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function thenInvalid(string $message): static
|
||||
{
|
||||
$this->thenPart = static fn ($v) => throw new \InvalidArgumentException(sprintf($message, json_encode($v)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a closure unsetting this key of the array at processing time.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws UnsetKeyException
|
||||
*/
|
||||
public function thenUnset(): static
|
||||
{
|
||||
$this->thenPart = static fn () => throw new UnsetKeyException('Unsetting key.');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the related node.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function end(): NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition
|
||||
{
|
||||
if (null === $this->ifPart) {
|
||||
throw new \RuntimeException('You must specify an if part.');
|
||||
}
|
||||
if (null === $this->thenPart) {
|
||||
throw new \RuntimeException('You must specify a then part.');
|
||||
}
|
||||
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the expressions.
|
||||
*
|
||||
* @param ExprBuilder[] $expressions An array of ExprBuilder instances to build
|
||||
*/
|
||||
public static function buildExpressions(array $expressions): array
|
||||
{
|
||||
foreach ($expressions as $k => $expr) {
|
||||
if ($expr instanceof self) {
|
||||
$if = $expr->ifPart;
|
||||
$then = $expr->thenPart;
|
||||
$expressions[$k] = static fn ($v) => $if($v) ? $then($v) : $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $expressions;
|
||||
}
|
||||
}
|
30
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\FloatNode;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining a float node.
|
||||
*
|
||||
* @author Jeanmonod David <david.jeanmonod@gmail.com>
|
||||
*/
|
||||
class FloatNodeDefinition extends NumericNodeDefinition
|
||||
{
|
||||
/**
|
||||
* Instantiates a Node.
|
||||
*/
|
||||
protected function instantiateNode(): FloatNode
|
||||
{
|
||||
return new FloatNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator);
|
||||
}
|
||||
}
|
30
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\IntegerNode;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining an integer node.
|
||||
*
|
||||
* @author Jeanmonod David <david.jeanmonod@gmail.com>
|
||||
*/
|
||||
class IntegerNodeDefinition extends NumericNodeDefinition
|
||||
{
|
||||
/**
|
||||
* Instantiates a Node.
|
||||
*/
|
||||
protected function instantiateNode(): IntegerNode
|
||||
{
|
||||
return new IntegerNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator);
|
||||
}
|
||||
}
|
61
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/MergeBuilder.php
vendored
Normal file
61
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/MergeBuilder.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* This class builds merge conditions.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class MergeBuilder
|
||||
{
|
||||
protected $node;
|
||||
public $allowFalse = false;
|
||||
public $allowOverwrite = true;
|
||||
|
||||
public function __construct(NodeDefinition $node)
|
||||
{
|
||||
$this->node = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the node can be unset.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function allowUnset(bool $allow = true): static
|
||||
{
|
||||
$this->allowFalse = $allow;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the node can be overwritten.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function denyOverwrite(bool $deny = true): static
|
||||
{
|
||||
$this->allowOverwrite = !$deny;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the related node.
|
||||
*/
|
||||
public function end(): NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
}
|
204
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NodeBuilder.php
vendored
Normal file
204
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NodeBuilder.php
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for building a node.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class NodeBuilder implements NodeParentInterface
|
||||
{
|
||||
protected $parent;
|
||||
protected $nodeMapping;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->nodeMapping = [
|
||||
'variable' => VariableNodeDefinition::class,
|
||||
'scalar' => ScalarNodeDefinition::class,
|
||||
'boolean' => BooleanNodeDefinition::class,
|
||||
'integer' => IntegerNodeDefinition::class,
|
||||
'float' => FloatNodeDefinition::class,
|
||||
'array' => ArrayNodeDefinition::class,
|
||||
'enum' => EnumNodeDefinition::class,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent node.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(?ParentNodeDefinitionInterface $parent = null): static
|
||||
{
|
||||
if (1 > \func_num_args()) {
|
||||
trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
|
||||
}
|
||||
$this->parent = $parent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child array node.
|
||||
*/
|
||||
public function arrayNode(string $name): ArrayNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'array');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child scalar node.
|
||||
*/
|
||||
public function scalarNode(string $name): ScalarNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'scalar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child Boolean node.
|
||||
*/
|
||||
public function booleanNode(string $name): BooleanNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'boolean');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child integer node.
|
||||
*/
|
||||
public function integerNode(string $name): IntegerNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'integer');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child float node.
|
||||
*/
|
||||
public function floatNode(string $name): FloatNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'float');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child EnumNode.
|
||||
*/
|
||||
public function enumNode(string $name): EnumNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'enum');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child variable node.
|
||||
*/
|
||||
public function variableNode(string $name): VariableNodeDefinition
|
||||
{
|
||||
return $this->node($name, 'variable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent node.
|
||||
*
|
||||
* @return NodeDefinition&ParentNodeDefinitionInterface
|
||||
*/
|
||||
public function end()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child node.
|
||||
*
|
||||
* @throws \RuntimeException When the node type is not registered
|
||||
* @throws \RuntimeException When the node class is not found
|
||||
*/
|
||||
public function node(?string $name, string $type): NodeDefinition
|
||||
{
|
||||
$class = $this->getNodeClass($type);
|
||||
|
||||
$node = new $class($name);
|
||||
|
||||
$this->append($node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a node definition.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $node = new ArrayNodeDefinition('name')
|
||||
* ->children()
|
||||
* ->scalarNode('foo')->end()
|
||||
* ->scalarNode('baz')->end()
|
||||
* ->append($this->getBarNodeDefinition())
|
||||
* ->end()
|
||||
* ;
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function append(NodeDefinition $node): static
|
||||
{
|
||||
if ($node instanceof BuilderAwareInterface) {
|
||||
$builder = clone $this;
|
||||
$builder->setParent(null);
|
||||
$node->setBuilder($builder);
|
||||
}
|
||||
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->append($node);
|
||||
// Make this builder the node parent to allow for a fluid interface
|
||||
$node->setParent($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or overrides a node Type.
|
||||
*
|
||||
* @param string $type The name of the type
|
||||
* @param string $class The fully qualified name the node definition class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setNodeClass(string $type, string $class): static
|
||||
{
|
||||
$this->nodeMapping[strtolower($type)] = $class;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name of the node definition.
|
||||
*
|
||||
* @throws \RuntimeException When the node type is not registered
|
||||
* @throws \RuntimeException When the node class is not found
|
||||
*/
|
||||
protected function getNodeClass(string $type): string
|
||||
{
|
||||
$type = strtolower($type);
|
||||
|
||||
if (!isset($this->nodeMapping[$type])) {
|
||||
throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
|
||||
}
|
||||
|
||||
$class = $this->nodeMapping[$type];
|
||||
|
||||
if (!class_exists($class)) {
|
||||
throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
}
|
336
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NodeDefinition.php
vendored
Normal file
336
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NodeDefinition.php
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\BaseNode;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining a node.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class NodeDefinition implements NodeParentInterface
|
||||
{
|
||||
protected $name;
|
||||
protected $normalization;
|
||||
protected $validation;
|
||||
protected $defaultValue;
|
||||
protected $default = false;
|
||||
protected $required = false;
|
||||
protected $deprecation = [];
|
||||
protected $merge;
|
||||
protected $allowEmptyValue = true;
|
||||
protected $nullEquivalent;
|
||||
protected $trueEquivalent = true;
|
||||
protected $falseEquivalent = false;
|
||||
protected $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR;
|
||||
protected $parent;
|
||||
protected $attributes = [];
|
||||
|
||||
public function __construct(?string $name, ?NodeParentInterface $parent = null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent node.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(NodeParentInterface $parent): static
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets info message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function info(string $info): static
|
||||
{
|
||||
return $this->attribute('info', $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets example configuration.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function example(string|array $example): static
|
||||
{
|
||||
return $this->attribute('example', $example);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an attribute on the node.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function attribute(string $key, mixed $value): static
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent node.
|
||||
*/
|
||||
public function end(): NodeParentInterface|NodeBuilder|self|ArrayNodeDefinition|VariableNodeDefinition|null
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the node.
|
||||
*/
|
||||
public function getNode(bool $forceRootNode = false): NodeInterface
|
||||
{
|
||||
if ($forceRootNode) {
|
||||
$this->parent = null;
|
||||
}
|
||||
|
||||
if (isset($this->normalization)) {
|
||||
$allowedTypes = [];
|
||||
foreach ($this->normalization->before as $expr) {
|
||||
$allowedTypes[] = $expr->allowedTypes;
|
||||
}
|
||||
$allowedTypes = array_unique($allowedTypes);
|
||||
$this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before);
|
||||
$this->normalization->declaredTypes = $allowedTypes;
|
||||
}
|
||||
|
||||
if (isset($this->validation)) {
|
||||
$this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules);
|
||||
}
|
||||
|
||||
$node = $this->createNode();
|
||||
if ($node instanceof BaseNode) {
|
||||
$node->setAttributes($this->attributes);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function defaultValue(mixed $value): static
|
||||
{
|
||||
$this->default = true;
|
||||
$this->defaultValue = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node as required.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function isRequired(): static
|
||||
{
|
||||
$this->required = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node as deprecated.
|
||||
*
|
||||
* @param string $package The name of the composer package that is triggering the deprecation
|
||||
* @param string $version The version of the package that introduced the deprecation
|
||||
* @param string $message the deprecation message to use
|
||||
*
|
||||
* You can use %node% and %path% placeholders in your message to display,
|
||||
* respectively, the node name and its complete path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDeprecated(string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.'): static
|
||||
{
|
||||
$this->deprecation = [
|
||||
'package' => $package,
|
||||
'version' => $version,
|
||||
'message' => $message,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the equivalent value used when the node contains null.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function treatNullLike(mixed $value): static
|
||||
{
|
||||
$this->nullEquivalent = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the equivalent value used when the node contains true.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function treatTrueLike(mixed $value): static
|
||||
{
|
||||
$this->trueEquivalent = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the equivalent value used when the node contains false.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function treatFalseLike(mixed $value): static
|
||||
{
|
||||
$this->falseEquivalent = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets null as the default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function defaultNull(): static
|
||||
{
|
||||
return $this->defaultValue(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets true as the default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function defaultTrue(): static
|
||||
{
|
||||
return $this->defaultValue(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets false as the default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function defaultFalse(): static
|
||||
{
|
||||
return $this->defaultValue(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an expression to run before the normalization.
|
||||
*/
|
||||
public function beforeNormalization(): ExprBuilder
|
||||
{
|
||||
return $this->normalization()->before();
|
||||
}
|
||||
|
||||
/**
|
||||
* Denies the node value being empty.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cannotBeEmpty(): static
|
||||
{
|
||||
$this->allowEmptyValue = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an expression to run for the validation.
|
||||
*
|
||||
* The expression receives the value of the node and must return it. It can
|
||||
* modify it.
|
||||
* An exception should be thrown when the node is not valid.
|
||||
*/
|
||||
public function validate(): ExprBuilder
|
||||
{
|
||||
return $this->validation()->rule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the node can be overwritten.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cannotBeOverwritten(bool $deny = true): static
|
||||
{
|
||||
$this->merge()->denyOverwrite($deny);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the builder for validation rules.
|
||||
*/
|
||||
protected function validation(): ValidationBuilder
|
||||
{
|
||||
return $this->validation ??= new ValidationBuilder($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the builder for merging rules.
|
||||
*/
|
||||
protected function merge(): MergeBuilder
|
||||
{
|
||||
return $this->merge ??= new MergeBuilder($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the builder for normalization rules.
|
||||
*/
|
||||
protected function normalization(): NormalizationBuilder
|
||||
{
|
||||
return $this->normalization ??= new NormalizationBuilder($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate and configure the node according to this definition.
|
||||
*
|
||||
* @throws InvalidDefinitionException When the definition is invalid
|
||||
*/
|
||||
abstract protected function createNode(): NodeInterface;
|
||||
|
||||
/**
|
||||
* Set PathSeparator to use.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPathSeparator(string $separator): static
|
||||
{
|
||||
if ($this instanceof ParentNodeDefinitionInterface) {
|
||||
foreach ($this->getChildNodeDefinitions() as $child) {
|
||||
$child->setPathSeparator($separator);
|
||||
}
|
||||
}
|
||||
|
||||
$this->pathSeparator = $separator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NodeParentInterface.php
vendored
Normal file
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NodeParentInterface.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* An interface that must be implemented by all node parents.
|
||||
*
|
||||
* @author Victor Berchet <victor@suumit.com>
|
||||
*/
|
||||
interface NodeParentInterface
|
||||
{
|
||||
}
|
61
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php
vendored
Normal file
61
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* This class builds normalization conditions.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class NormalizationBuilder
|
||||
{
|
||||
protected $node;
|
||||
public $before = [];
|
||||
public $declaredTypes = [];
|
||||
public $remappings = [];
|
||||
|
||||
public function __construct(NodeDefinition $node)
|
||||
{
|
||||
$this->node = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a key to remap to its plural form.
|
||||
*
|
||||
* @param string $key The key to remap
|
||||
* @param string|null $plural The plural of the key in case of irregular plural
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function remap(string $key, ?string $plural = null): static
|
||||
{
|
||||
$this->remappings[] = [$key, null === $plural ? $key.'s' : $plural];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a closure to run before the normalization or an expression builder to build it if null is provided.
|
||||
*
|
||||
* @return ExprBuilder|$this
|
||||
*/
|
||||
public function before(?\Closure $closure = null): ExprBuilder|static
|
||||
{
|
||||
if (null !== $closure) {
|
||||
$this->before[] = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->before[] = new ExprBuilder($this->node);
|
||||
}
|
||||
}
|
67
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php
vendored
Normal file
67
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||
|
||||
/**
|
||||
* Abstract class that contains common code of integer and float node definitions.
|
||||
*
|
||||
* @author David Jeanmonod <david.jeanmonod@gmail.com>
|
||||
*/
|
||||
abstract class NumericNodeDefinition extends ScalarNodeDefinition
|
||||
{
|
||||
protected $min;
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* Ensures that the value is smaller than the given reference.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \InvalidArgumentException when the constraint is inconsistent
|
||||
*/
|
||||
public function max(int|float $max): static
|
||||
{
|
||||
if (isset($this->min) && $this->min > $max) {
|
||||
throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s).', $max, $this->min));
|
||||
}
|
||||
$this->max = $max;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the value is bigger than the given reference.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \InvalidArgumentException when the constraint is inconsistent
|
||||
*/
|
||||
public function min(int|float $min): static
|
||||
{
|
||||
if (isset($this->max) && $this->max < $min) {
|
||||
throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s).', $min, $this->max));
|
||||
}
|
||||
$this->min = $min;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidDefinitionException
|
||||
*/
|
||||
public function cannotBeEmpty(): static
|
||||
{
|
||||
throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to NumericNodeDefinition.');
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* An interface that must be implemented by nodes which can have children.
|
||||
*
|
||||
* @author Victor Berchet <victor@suumit.com>
|
||||
*/
|
||||
interface ParentNodeDefinitionInterface extends BuilderAwareInterface
|
||||
{
|
||||
/**
|
||||
* Returns a builder to add children nodes.
|
||||
*/
|
||||
public function children(): NodeBuilder;
|
||||
|
||||
/**
|
||||
* Appends a node definition.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $node = $parentNode
|
||||
* ->children()
|
||||
* ->scalarNode('foo')->end()
|
||||
* ->scalarNode('baz')->end()
|
||||
* ->append($this->getBarNodeDefinition())
|
||||
* ->end()
|
||||
* ;
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function append(NodeDefinition $node): static;
|
||||
|
||||
/**
|
||||
* Gets the child node definitions.
|
||||
*
|
||||
* @return NodeDefinition[]
|
||||
*/
|
||||
public function getChildNodeDefinitions(): array;
|
||||
}
|
30
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\ScalarNode;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining a node.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ScalarNodeDefinition extends VariableNodeDefinition
|
||||
{
|
||||
/**
|
||||
* Instantiate a Node.
|
||||
*/
|
||||
protected function instantiateNode(): ScalarNode
|
||||
{
|
||||
return new ScalarNode($this->name, $this->parent, $this->pathSeparator);
|
||||
}
|
||||
}
|
67
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/TreeBuilder.php
vendored
Normal file
67
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/TreeBuilder.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
|
||||
/**
|
||||
* This is the entry class for building a config tree.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class TreeBuilder implements NodeParentInterface
|
||||
{
|
||||
/**
|
||||
* @var NodeInterface|null
|
||||
*/
|
||||
protected $tree;
|
||||
|
||||
/**
|
||||
* @var NodeDefinition
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
public function __construct(string $name, string $type = 'array', ?NodeBuilder $builder = null)
|
||||
{
|
||||
$builder ??= new NodeBuilder();
|
||||
$this->root = $builder->node($name, $type)->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeDefinition|ArrayNodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array')
|
||||
*/
|
||||
public function getRootNode(): NodeDefinition|ArrayNodeDefinition
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the tree.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function buildTree(): NodeInterface
|
||||
{
|
||||
return $this->tree ??= $this->root->getNode(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setPathSeparator(string $separator)
|
||||
{
|
||||
// unset last built as changing path separator changes all nodes
|
||||
$this->tree = null;
|
||||
|
||||
$this->root->setPathSeparator($separator);
|
||||
}
|
||||
}
|
44
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ValidationBuilder.php
vendored
Normal file
44
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/ValidationBuilder.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
/**
|
||||
* This class builds validation conditions.
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class ValidationBuilder
|
||||
{
|
||||
protected $node;
|
||||
public $rules = [];
|
||||
|
||||
public function __construct(NodeDefinition $node)
|
||||
{
|
||||
$this->node = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a closure to run as normalization or an expression builder to build it if null is provided.
|
||||
*
|
||||
* @return ExprBuilder|$this
|
||||
*/
|
||||
public function rule(?\Closure $closure = null): ExprBuilder|static
|
||||
{
|
||||
if (null !== $closure) {
|
||||
$this->rules[] = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->rules[] = new ExprBuilder($this->node);
|
||||
}
|
||||
}
|
64
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php
vendored
Normal file
64
plugins/simplesaml/lib/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Builder;
|
||||
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
use Symfony\Component\Config\Definition\VariableNode;
|
||||
|
||||
/**
|
||||
* This class provides a fluent interface for defining a node.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class VariableNodeDefinition extends NodeDefinition
|
||||
{
|
||||
/**
|
||||
* Instantiate a Node.
|
||||
*/
|
||||
protected function instantiateNode(): VariableNode
|
||||
{
|
||||
return new VariableNode($this->name, $this->parent, $this->pathSeparator);
|
||||
}
|
||||
|
||||
protected function createNode(): NodeInterface
|
||||
{
|
||||
$node = $this->instantiateNode();
|
||||
|
||||
if (isset($this->normalization)) {
|
||||
$node->setNormalizationClosures($this->normalization->before);
|
||||
}
|
||||
|
||||
if (isset($this->merge)) {
|
||||
$node->setAllowOverwrite($this->merge->allowOverwrite);
|
||||
}
|
||||
|
||||
if (true === $this->default) {
|
||||
$node->setDefaultValue($this->defaultValue);
|
||||
}
|
||||
|
||||
$node->setAllowEmptyValue($this->allowEmptyValue);
|
||||
$node->addEquivalentValue(null, $this->nullEquivalent);
|
||||
$node->addEquivalentValue(true, $this->trueEquivalent);
|
||||
$node->addEquivalentValue(false, $this->falseEquivalent);
|
||||
$node->setRequired($this->required);
|
||||
|
||||
if ($this->deprecation) {
|
||||
$node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']);
|
||||
}
|
||||
|
||||
if (isset($this->validation)) {
|
||||
$node->setFinalValidationClosures($this->validation->rules);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
25
plugins/simplesaml/lib/vendor/symfony/config/Definition/ConfigurableInterface.php
vendored
Normal file
25
plugins/simplesaml/lib/vendor/symfony/config/Definition/ConfigurableInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
|
||||
|
||||
/**
|
||||
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||
*/
|
||||
interface ConfigurableInterface
|
||||
{
|
||||
/**
|
||||
* Generates the configuration tree builder.
|
||||
*/
|
||||
public function configure(DefinitionConfigurator $definition): void;
|
||||
}
|
45
plugins/simplesaml/lib/vendor/symfony/config/Definition/Configuration.php
vendored
Normal file
45
plugins/simplesaml/lib/vendor/symfony/config/Definition/Configuration.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
|
||||
use Symfony\Component\Config\Definition\Loader\DefinitionFileLoader;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class Configuration implements ConfigurationInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ConfigurableInterface $subject,
|
||||
private ?ContainerBuilder $container,
|
||||
private string $alias,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getConfigTreeBuilder(): TreeBuilder
|
||||
{
|
||||
$treeBuilder = new TreeBuilder($this->alias);
|
||||
$file = (new \ReflectionObject($this->subject))->getFileName();
|
||||
$loader = new DefinitionFileLoader($treeBuilder, new FileLocator(\dirname($file)), $this->container);
|
||||
$configurator = new DefinitionConfigurator($treeBuilder, $loader, $file, $file);
|
||||
|
||||
$this->subject->configure($configurator);
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
}
|
29
plugins/simplesaml/lib/vendor/symfony/config/Definition/ConfigurationInterface.php
vendored
Normal file
29
plugins/simplesaml/lib/vendor/symfony/config/Definition/ConfigurationInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
|
||||
/**
|
||||
* Configuration interface.
|
||||
*
|
||||
* @author Victor Berchet <victor@suumit.com>
|
||||
*/
|
||||
interface ConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* Generates the configuration tree builder.
|
||||
*
|
||||
* @return TreeBuilder
|
||||
*/
|
||||
public function getConfigTreeBuilder();
|
||||
}
|
47
plugins/simplesaml/lib/vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php
vendored
Normal file
47
plugins/simplesaml/lib/vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Configurator;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\Loader\DefinitionFileLoader;
|
||||
|
||||
/**
|
||||
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||
*/
|
||||
class DefinitionConfigurator
|
||||
{
|
||||
public function __construct(
|
||||
private TreeBuilder $treeBuilder,
|
||||
private DefinitionFileLoader $loader,
|
||||
private string $path,
|
||||
private string $file,
|
||||
) {
|
||||
}
|
||||
|
||||
public function import(string $resource, ?string $type = null, bool $ignoreErrors = false): void
|
||||
{
|
||||
$this->loader->setCurrentDir(\dirname($this->path));
|
||||
$this->loader->import($resource, $type, $ignoreErrors, $this->file);
|
||||
}
|
||||
|
||||
public function rootNode(): NodeDefinition|ArrayNodeDefinition
|
||||
{
|
||||
return $this->treeBuilder->getRootNode();
|
||||
}
|
||||
|
||||
public function setPathSeparator(string $separator): void
|
||||
{
|
||||
$this->treeBuilder->setPathSeparator($separator);
|
||||
}
|
||||
}
|
299
plugins/simplesaml/lib/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php
vendored
Normal file
299
plugins/simplesaml/lib/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Dumper;
|
||||
|
||||
use Symfony\Component\Config\Definition\ArrayNode;
|
||||
use Symfony\Component\Config\Definition\BaseNode;
|
||||
use Symfony\Component\Config\Definition\BooleanNode;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\EnumNode;
|
||||
use Symfony\Component\Config\Definition\FloatNode;
|
||||
use Symfony\Component\Config\Definition\IntegerNode;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
use Symfony\Component\Config\Definition\PrototypedArrayNode;
|
||||
use Symfony\Component\Config\Definition\ScalarNode;
|
||||
|
||||
/**
|
||||
* Dumps an XML reference configuration for the given configuration/node instance.
|
||||
*
|
||||
* @author Wouter J <waldio.webdesign@gmail.com>
|
||||
*/
|
||||
class XmlReferenceDumper
|
||||
{
|
||||
private ?string $reference = null;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dump(ConfigurationInterface $configuration, ?string $namespace = null)
|
||||
{
|
||||
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dumpNode(NodeInterface $node, ?string $namespace = null)
|
||||
{
|
||||
$this->reference = '';
|
||||
$this->writeNode($node, 0, true, $namespace);
|
||||
$ref = $this->reference;
|
||||
$this->reference = null;
|
||||
|
||||
return $ref;
|
||||
}
|
||||
|
||||
private function writeNode(NodeInterface $node, int $depth = 0, bool $root = false, ?string $namespace = null): void
|
||||
{
|
||||
$rootName = ($root ? 'config' : $node->getName());
|
||||
$rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null));
|
||||
|
||||
// xml remapping
|
||||
if ($node->getParent()) {
|
||||
$remapping = array_filter($node->getParent()->getXmlRemappings(), fn (array $mapping) => $rootName === $mapping[1]);
|
||||
|
||||
if (\count($remapping)) {
|
||||
[$singular] = current($remapping);
|
||||
$rootName = $singular;
|
||||
}
|
||||
}
|
||||
$rootName = str_replace('_', '-', $rootName);
|
||||
|
||||
$rootAttributes = [];
|
||||
$rootAttributeComments = [];
|
||||
$rootChildren = [];
|
||||
$rootComments = [];
|
||||
|
||||
if ($node instanceof ArrayNode) {
|
||||
$children = $node->getChildren();
|
||||
|
||||
// comments about the root node
|
||||
if ($rootInfo = $node->getInfo()) {
|
||||
$rootComments[] = $rootInfo;
|
||||
}
|
||||
|
||||
if ($rootNamespace) {
|
||||
$rootComments[] = 'Namespace: '.$rootNamespace;
|
||||
}
|
||||
|
||||
// render prototyped nodes
|
||||
if ($node instanceof PrototypedArrayNode) {
|
||||
$prototype = $node->getPrototype();
|
||||
|
||||
$info = 'prototype';
|
||||
if (null !== $prototype->getInfo()) {
|
||||
$info .= ': '.$prototype->getInfo();
|
||||
}
|
||||
array_unshift($rootComments, $info);
|
||||
|
||||
if ($key = $node->getKeyAttribute()) {
|
||||
$rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
|
||||
}
|
||||
|
||||
if ($prototype instanceof PrototypedArrayNode) {
|
||||
$prototype->setName($key ?? '');
|
||||
$children = [$key => $prototype];
|
||||
} elseif ($prototype instanceof ArrayNode) {
|
||||
$children = $prototype->getChildren();
|
||||
} else {
|
||||
if ($prototype->hasDefaultValue()) {
|
||||
$prototypeValue = $prototype->getDefaultValue();
|
||||
} else {
|
||||
$prototypeValue = match ($prototype::class) {
|
||||
ScalarNode::class => 'scalar value',
|
||||
FloatNode::class,
|
||||
IntegerNode::class => 'numeric value',
|
||||
BooleanNode::class => 'true|false',
|
||||
EnumNode::class => $prototype->getPermissibleValues('|'),
|
||||
default => 'value',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get attributes and elements
|
||||
foreach ($children as $child) {
|
||||
if ($child instanceof ArrayNode) {
|
||||
// get elements
|
||||
$rootChildren[] = $child;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// get attributes
|
||||
|
||||
// metadata
|
||||
$name = str_replace('_', '-', $child->getName());
|
||||
$value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
|
||||
|
||||
// comments
|
||||
$comments = [];
|
||||
if ($child instanceof BaseNode && $info = $child->getInfo()) {
|
||||
$comments[] = $info;
|
||||
}
|
||||
|
||||
if ($child instanceof BaseNode && $example = $child->getExample()) {
|
||||
$comments[] = 'Example: '.(\is_array($example) ? implode(', ', $example) : $example);
|
||||
}
|
||||
|
||||
if ($child->isRequired()) {
|
||||
$comments[] = 'Required';
|
||||
}
|
||||
|
||||
if ($child instanceof BaseNode && $child->isDeprecated()) {
|
||||
$deprecation = $child->getDeprecation($child->getName(), $node->getPath());
|
||||
$comments[] = sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
|
||||
}
|
||||
|
||||
if ($child instanceof EnumNode) {
|
||||
$comments[] = 'One of '.$child->getPermissibleValues('; ');
|
||||
}
|
||||
|
||||
if (\count($comments)) {
|
||||
$rootAttributeComments[$name] = implode(";\n", $comments);
|
||||
}
|
||||
|
||||
// default values
|
||||
if ($child->hasDefaultValue()) {
|
||||
$value = $child->getDefaultValue();
|
||||
}
|
||||
|
||||
// append attribute
|
||||
$rootAttributes[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// render comments
|
||||
|
||||
// root node comment
|
||||
if (\count($rootComments)) {
|
||||
foreach ($rootComments as $comment) {
|
||||
$this->writeLine('<!-- '.$comment.' -->', $depth);
|
||||
}
|
||||
}
|
||||
|
||||
// attribute comments
|
||||
if (\count($rootAttributeComments)) {
|
||||
foreach ($rootAttributeComments as $attrName => $comment) {
|
||||
$commentDepth = $depth + 4 + \strlen($attrName) + 2;
|
||||
$commentLines = explode("\n", $comment);
|
||||
$multiline = (\count($commentLines) > 1);
|
||||
$comment = implode(\PHP_EOL.str_repeat(' ', $commentDepth), $commentLines);
|
||||
|
||||
if ($multiline) {
|
||||
$this->writeLine('<!--', $depth);
|
||||
$this->writeLine($attrName.': '.$comment, $depth + 4);
|
||||
$this->writeLine('-->', $depth);
|
||||
} else {
|
||||
$this->writeLine('<!-- '.$attrName.': '.$comment.' -->', $depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render start tag + attributes
|
||||
$rootIsVariablePrototype = isset($prototypeValue);
|
||||
$rootIsEmptyTag = (0 === \count($rootChildren) && !$rootIsVariablePrototype);
|
||||
$rootOpenTag = '<'.$rootName;
|
||||
if (1 >= ($attributesCount = \count($rootAttributes))) {
|
||||
if (1 === $attributesCount) {
|
||||
$rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
|
||||
}
|
||||
|
||||
$rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';
|
||||
|
||||
if ($rootIsVariablePrototype) {
|
||||
$rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
|
||||
}
|
||||
|
||||
$this->writeLine($rootOpenTag, $depth);
|
||||
} else {
|
||||
$this->writeLine($rootOpenTag, $depth);
|
||||
|
||||
$i = 1;
|
||||
|
||||
foreach ($rootAttributes as $attrName => $attrValue) {
|
||||
$attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));
|
||||
|
||||
$this->writeLine($attr, $depth + 4);
|
||||
|
||||
if ($attributesCount === $i++) {
|
||||
$this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth);
|
||||
|
||||
if ($rootIsVariablePrototype) {
|
||||
$rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render children tags
|
||||
foreach ($rootChildren as $child) {
|
||||
$this->writeLine('');
|
||||
$this->writeNode($child, $depth + 4);
|
||||
}
|
||||
|
||||
// render end tag
|
||||
if (!$rootIsEmptyTag && !$rootIsVariablePrototype) {
|
||||
$this->writeLine('');
|
||||
|
||||
$rootEndTag = '</'.$rootName.'>';
|
||||
$this->writeLine($rootEndTag, $depth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a single config reference line.
|
||||
*/
|
||||
private function writeLine(string $text, int $indent = 0): void
|
||||
{
|
||||
$indent = \strlen($text) + $indent;
|
||||
$format = '%'.$indent.'s';
|
||||
|
||||
$this->reference .= sprintf($format, $text).\PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the string conversion of the value.
|
||||
*/
|
||||
private function writeValue(mixed $value): string
|
||||
{
|
||||
if ('%%%%not_defined%%%%' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (\is_string($value) || is_numeric($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (false === $value) {
|
||||
return 'false';
|
||||
}
|
||||
|
||||
if (true === $value) {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (empty($value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
return implode(',', $value);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
254
plugins/simplesaml/lib/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php
vendored
Normal file
254
plugins/simplesaml/lib/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Dumper;
|
||||
|
||||
use Symfony\Component\Config\Definition\ArrayNode;
|
||||
use Symfony\Component\Config\Definition\BaseNode;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\EnumNode;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
use Symfony\Component\Config\Definition\PrototypedArrayNode;
|
||||
use Symfony\Component\Config\Definition\ScalarNode;
|
||||
use Symfony\Component\Yaml\Inline;
|
||||
|
||||
/**
|
||||
* Dumps a Yaml reference configuration for the given configuration/node instance.
|
||||
*
|
||||
* @author Kevin Bond <kevinbond@gmail.com>
|
||||
*/
|
||||
class YamlReferenceDumper
|
||||
{
|
||||
private ?string $reference = null;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dump(ConfigurationInterface $configuration)
|
||||
{
|
||||
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dumpAtPath(ConfigurationInterface $configuration, string $path)
|
||||
{
|
||||
$rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree();
|
||||
|
||||
foreach (explode('.', $path) as $step) {
|
||||
if (!$node instanceof ArrayNode) {
|
||||
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
|
||||
}
|
||||
|
||||
/** @var NodeInterface[] $children */
|
||||
$children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren();
|
||||
|
||||
foreach ($children as $child) {
|
||||
if ($child->getName() === $step) {
|
||||
$node = $child;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
|
||||
}
|
||||
|
||||
return $this->dumpNode($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dumpNode(NodeInterface $node)
|
||||
{
|
||||
$this->reference = '';
|
||||
$this->writeNode($node);
|
||||
$ref = $this->reference;
|
||||
$this->reference = null;
|
||||
|
||||
return $ref;
|
||||
}
|
||||
|
||||
private function writeNode(NodeInterface $node, ?NodeInterface $parentNode = null, int $depth = 0, bool $prototypedArray = false): void
|
||||
{
|
||||
$comments = [];
|
||||
$default = '';
|
||||
$defaultArray = null;
|
||||
$children = null;
|
||||
$example = null;
|
||||
if ($node instanceof BaseNode) {
|
||||
$example = $node->getExample();
|
||||
}
|
||||
|
||||
// defaults
|
||||
if ($node instanceof ArrayNode) {
|
||||
$children = $node->getChildren();
|
||||
|
||||
if ($node instanceof PrototypedArrayNode) {
|
||||
$children = $this->getPrototypeChildren($node);
|
||||
}
|
||||
|
||||
if (!$children && !($node->hasDefaultValue() && \count($defaultArray = $node->getDefaultValue()))) {
|
||||
$default = '[]';
|
||||
}
|
||||
} elseif ($node instanceof EnumNode) {
|
||||
$comments[] = 'One of '.$node->getPermissibleValues('; ');
|
||||
$default = $node->hasDefaultValue() ? Inline::dump($node->getDefaultValue()) : '~';
|
||||
} else {
|
||||
$default = '~';
|
||||
|
||||
if ($node->hasDefaultValue()) {
|
||||
$default = $node->getDefaultValue();
|
||||
|
||||
if (\is_array($default)) {
|
||||
if (\count($defaultArray = $node->getDefaultValue())) {
|
||||
$default = '';
|
||||
} elseif (!\is_array($example)) {
|
||||
$default = '[]';
|
||||
}
|
||||
} else {
|
||||
$default = Inline::dump($default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// required?
|
||||
if ($node->isRequired()) {
|
||||
$comments[] = 'Required';
|
||||
}
|
||||
|
||||
// deprecated?
|
||||
if ($node instanceof BaseNode && $node->isDeprecated()) {
|
||||
$deprecation = $node->getDeprecation($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath());
|
||||
$comments[] = sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
|
||||
}
|
||||
|
||||
// example
|
||||
if ($example && !\is_array($example)) {
|
||||
$comments[] = 'Example: '.Inline::dump($example);
|
||||
}
|
||||
|
||||
$default = '' != (string) $default ? ' '.$default : '';
|
||||
$comments = \count($comments) ? '# '.implode(', ', $comments) : '';
|
||||
|
||||
$key = $prototypedArray ? '-' : $node->getName().':';
|
||||
$text = rtrim(sprintf('%-21s%s %s', $key, $default, $comments), ' ');
|
||||
|
||||
if ($node instanceof BaseNode && $info = $node->getInfo()) {
|
||||
$this->writeLine('');
|
||||
// indenting multi-line info
|
||||
$info = str_replace("\n", sprintf("\n%".($depth * 4).'s# ', ' '), $info);
|
||||
$this->writeLine('# '.$info, $depth * 4);
|
||||
}
|
||||
|
||||
$this->writeLine($text, $depth * 4);
|
||||
|
||||
// output defaults
|
||||
if ($defaultArray) {
|
||||
$this->writeLine('');
|
||||
|
||||
$message = \count($defaultArray) > 1 ? 'Defaults' : 'Default';
|
||||
|
||||
$this->writeLine('# '.$message.':', $depth * 4 + 4);
|
||||
|
||||
$this->writeArray($defaultArray, $depth + 1);
|
||||
}
|
||||
|
||||
if (\is_array($example)) {
|
||||
$this->writeLine('');
|
||||
|
||||
$message = \count($example) > 1 ? 'Examples' : 'Example';
|
||||
|
||||
$this->writeLine('# '.$message.':', $depth * 4 + 4);
|
||||
|
||||
$this->writeArray(array_map(Inline::dump(...), $example), $depth + 1, true);
|
||||
}
|
||||
|
||||
if ($children) {
|
||||
foreach ($children as $childNode) {
|
||||
$this->writeNode($childNode, $node, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a single config reference line.
|
||||
*/
|
||||
private function writeLine(string $text, int $indent = 0): void
|
||||
{
|
||||
$indent = \strlen($text) + $indent;
|
||||
$format = '%'.$indent.'s';
|
||||
|
||||
$this->reference .= sprintf($format, $text)."\n";
|
||||
}
|
||||
|
||||
private function writeArray(array $array, int $depth, bool $asComment = false): void
|
||||
{
|
||||
$isIndexed = array_is_list($array);
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
if (\is_array($value)) {
|
||||
$val = '';
|
||||
} else {
|
||||
$val = $value;
|
||||
}
|
||||
|
||||
$prefix = $asComment ? '# ' : '';
|
||||
|
||||
if ($isIndexed) {
|
||||
$this->writeLine($prefix.'- '.$val, $depth * 4);
|
||||
} else {
|
||||
$this->writeLine(sprintf('%s%-20s %s', $prefix, $key.':', $val), $depth * 4);
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
$this->writeArray($value, $depth + 1, $asComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getPrototypeChildren(PrototypedArrayNode $node): array
|
||||
{
|
||||
$prototype = $node->getPrototype();
|
||||
$key = $node->getKeyAttribute();
|
||||
|
||||
// Do not expand prototype if it isn't an array node nor uses attribute as key
|
||||
if (!$key && !$prototype instanceof ArrayNode) {
|
||||
return $node->getChildren();
|
||||
}
|
||||
|
||||
if ($prototype instanceof ArrayNode) {
|
||||
$keyNode = new ArrayNode($key, $node);
|
||||
$children = $prototype->getChildren();
|
||||
|
||||
if ($prototype instanceof PrototypedArrayNode && $prototype->getKeyAttribute()) {
|
||||
$children = $this->getPrototypeChildren($prototype);
|
||||
}
|
||||
|
||||
// add children
|
||||
foreach ($children as $childNode) {
|
||||
$keyNode->addChild($childNode);
|
||||
}
|
||||
} else {
|
||||
$keyNode = new ScalarNode($key, $node);
|
||||
}
|
||||
|
||||
$info = 'Prototype';
|
||||
if (null !== $prototype->getInfo()) {
|
||||
$info .= ': '.$prototype->getInfo();
|
||||
}
|
||||
$keyNode->setInfo($info);
|
||||
|
||||
return [$key => $keyNode];
|
||||
}
|
||||
}
|
96
plugins/simplesaml/lib/vendor/symfony/config/Definition/EnumNode.php
vendored
Normal file
96
plugins/simplesaml/lib/vendor/symfony/config/Definition/EnumNode.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
|
||||
/**
|
||||
* Node which only allows a finite set of values.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class EnumNode extends ScalarNode
|
||||
{
|
||||
private array $values;
|
||||
|
||||
public function __construct(?string $name, ?NodeInterface $parent = null, array $values = [], string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
|
||||
{
|
||||
if (!$values) {
|
||||
throw new \InvalidArgumentException('$values must contain at least one element.');
|
||||
}
|
||||
|
||||
foreach ($values as $value) {
|
||||
if (null === $value || \is_scalar($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$value instanceof \UnitEnum) {
|
||||
throw new \InvalidArgumentException(sprintf('"%s" only supports scalar, enum, or null values, "%s" given.', __CLASS__, get_debug_type($value)));
|
||||
}
|
||||
|
||||
if ($value::class !== ($enumClass ??= $value::class)) {
|
||||
throw new \InvalidArgumentException(sprintf('"%s" only supports one type of enum, "%s" and "%s" passed.', __CLASS__, $enumClass, $value::class));
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($name, $parent, $pathSeparator);
|
||||
$this->values = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function getPermissibleValues(string $separator): string
|
||||
{
|
||||
return implode($separator, array_unique(array_map(static function (mixed $value): string {
|
||||
if (!$value instanceof \UnitEnum) {
|
||||
return json_encode($value);
|
||||
}
|
||||
|
||||
return ltrim(var_export($value, true), '\\');
|
||||
}, $this->values)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
if ($value instanceof \UnitEnum) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::validateType($value);
|
||||
}
|
||||
|
||||
protected function finalizeValue(mixed $value): mixed
|
||||
{
|
||||
$value = parent::finalizeValue($value);
|
||||
|
||||
if (!\in_array($value, $this->values, true)) {
|
||||
$ex = new InvalidConfigurationException(sprintf('The value %s is not allowed for path "%s". Permissible values: %s', json_encode($value), $this->getPath(), $this->getPermissibleValues(', ')));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
22
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php
vendored
Normal file
22
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown whenever the key of an array is not unique. This can
|
||||
* only be the case if the configuration is coming from an XML file.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class DuplicateKeyException extends InvalidConfigurationException
|
||||
{
|
||||
}
|
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/Exception.php
vendored
Normal file
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/Exception.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* Base exception for all configuration exceptions.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class Exception extends \RuntimeException
|
||||
{
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a configuration path is overwritten from a
|
||||
* subsequent configuration file, but the entry node specifically forbids this.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ForbiddenOverwriteException extends InvalidConfigurationException
|
||||
{
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* A very general exception which can be thrown whenever non of the more specific
|
||||
* exceptions is suitable.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class InvalidConfigurationException extends Exception
|
||||
{
|
||||
private ?string $path = null;
|
||||
private bool $containsHints = false;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setPath(string $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
public function getPath(): ?string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds extra information that is suffixed to the original exception message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addHint(string $hint)
|
||||
{
|
||||
if (!$this->containsHints) {
|
||||
$this->message .= "\nHint: ".$hint;
|
||||
$this->containsHints = true;
|
||||
} else {
|
||||
$this->message .= ', '.$hint;
|
||||
}
|
||||
}
|
||||
}
|
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php
vendored
Normal file
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when an error is detected in a node Definition.
|
||||
*
|
||||
* @author Victor Berchet <victor.berchet@suumit.com>
|
||||
*/
|
||||
class InvalidDefinitionException extends Exception
|
||||
{
|
||||
}
|
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/InvalidTypeException.php
vendored
Normal file
21
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/InvalidTypeException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown if an invalid type is encountered.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class InvalidTypeException extends InvalidConfigurationException
|
||||
{
|
||||
}
|
22
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/UnsetKeyException.php
vendored
Normal file
22
plugins/simplesaml/lib/vendor/symfony/config/Definition/Exception/UnsetKeyException.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Exception;
|
||||
|
||||
/**
|
||||
* This exception is usually not encountered by the end-user, but only used
|
||||
* internally to signal the parent scope to unset a key.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class UnsetKeyException extends Exception
|
||||
{
|
||||
}
|
48
plugins/simplesaml/lib/vendor/symfony/config/Definition/FloatNode.php
vendored
Normal file
48
plugins/simplesaml/lib/vendor/symfony/config/Definition/FloatNode.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
|
||||
/**
|
||||
* This node represents a float value in the config tree.
|
||||
*
|
||||
* @author Jeanmonod David <david.jeanmonod@gmail.com>
|
||||
*/
|
||||
class FloatNode extends NumericNode
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
// Integers are also accepted, we just cast them
|
||||
if (\is_int($value)) {
|
||||
$value = (float) $value;
|
||||
}
|
||||
|
||||
if (!\is_float($value)) {
|
||||
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "float", but got "%s".', $this->getPath(), get_debug_type($value)));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$ex->addHint($hint);
|
||||
}
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getValidPlaceholderTypes(): array
|
||||
{
|
||||
return ['float'];
|
||||
}
|
||||
}
|
43
plugins/simplesaml/lib/vendor/symfony/config/Definition/IntegerNode.php
vendored
Normal file
43
plugins/simplesaml/lib/vendor/symfony/config/Definition/IntegerNode.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
|
||||
/**
|
||||
* This node represents an integer value in the config tree.
|
||||
*
|
||||
* @author Jeanmonod David <david.jeanmonod@gmail.com>
|
||||
*/
|
||||
class IntegerNode extends NumericNode
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
if (!\is_int($value)) {
|
||||
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "int", but got "%s".', $this->getPath(), get_debug_type($value)));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$ex->addHint($hint);
|
||||
}
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getValidPlaceholderTypes(): array
|
||||
{
|
||||
return ['int'];
|
||||
}
|
||||
}
|
103
plugins/simplesaml/lib/vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php
vendored
Normal file
103
plugins/simplesaml/lib/vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition\Loader;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
|
||||
use Symfony\Component\Config\FileLocatorInterface;
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* DefinitionFileLoader loads config definitions from a PHP file.
|
||||
*
|
||||
* The PHP file is required.
|
||||
*
|
||||
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||
*/
|
||||
class DefinitionFileLoader extends FileLoader
|
||||
{
|
||||
public function __construct(
|
||||
private TreeBuilder $treeBuilder,
|
||||
FileLocatorInterface $locator,
|
||||
private ?ContainerBuilder $container = null,
|
||||
) {
|
||||
parent::__construct($locator);
|
||||
}
|
||||
|
||||
public function load(mixed $resource, ?string $type = null): mixed
|
||||
{
|
||||
// the loader variable is exposed to the included file below
|
||||
$loader = $this;
|
||||
|
||||
$path = $this->locator->locate($resource);
|
||||
$this->setCurrentDir(\dirname($path));
|
||||
$this->container?->fileExists($path);
|
||||
|
||||
// the closure forbids access to the private scope in the included file
|
||||
$load = \Closure::bind(static function ($file) use ($loader) {
|
||||
return include $file;
|
||||
}, null, ProtectedDefinitionFileLoader::class);
|
||||
|
||||
$callback = $load($path);
|
||||
|
||||
if (\is_object($callback) && \is_callable($callback)) {
|
||||
$this->executeCallback($callback, new DefinitionConfigurator($this->treeBuilder, $this, $path, $resource), $path);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function supports(mixed $resource, ?string $type = null): bool
|
||||
{
|
||||
if (!\is_string($resource)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === $type && 'php' === pathinfo($resource, \PATHINFO_EXTENSION)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return 'php' === $type;
|
||||
}
|
||||
|
||||
private function executeCallback(callable $callback, DefinitionConfigurator $configurator, string $path): void
|
||||
{
|
||||
$callback = $callback(...);
|
||||
|
||||
$arguments = [];
|
||||
$r = new \ReflectionFunction($callback);
|
||||
|
||||
foreach ($r->getParameters() as $parameter) {
|
||||
$reflectionType = $parameter->getType();
|
||||
|
||||
if (!$reflectionType instanceof \ReflectionNamedType) {
|
||||
throw new \InvalidArgumentException(sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s").', $parameter->getName(), $path, DefinitionConfigurator::class));
|
||||
}
|
||||
|
||||
$arguments[] = match ($reflectionType->getName()) {
|
||||
DefinitionConfigurator::class => $configurator,
|
||||
TreeBuilder::class => $this->treeBuilder,
|
||||
FileLoader::class, self::class => $this,
|
||||
};
|
||||
}
|
||||
|
||||
$callback(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class ProtectedDefinitionFileLoader extends DefinitionFileLoader
|
||||
{
|
||||
}
|
77
plugins/simplesaml/lib/vendor/symfony/config/Definition/NodeInterface.php
vendored
Normal file
77
plugins/simplesaml/lib/vendor/symfony/config/Definition/NodeInterface.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
|
||||
/**
|
||||
* Common Interface among all nodes.
|
||||
*
|
||||
* In most cases, it is better to inherit from BaseNode instead of implementing
|
||||
* this interface yourself.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface NodeInterface
|
||||
{
|
||||
/**
|
||||
* Returns the name of the node.
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Returns the path of the node.
|
||||
*/
|
||||
public function getPath(): string;
|
||||
|
||||
/**
|
||||
* Returns true when the node is required.
|
||||
*/
|
||||
public function isRequired(): bool;
|
||||
|
||||
/**
|
||||
* Returns true when the node has a default value.
|
||||
*/
|
||||
public function hasDefaultValue(): bool;
|
||||
|
||||
/**
|
||||
* Returns the default value of the node.
|
||||
*
|
||||
* @throws \RuntimeException if the node has no default value
|
||||
*/
|
||||
public function getDefaultValue(): mixed;
|
||||
|
||||
/**
|
||||
* Normalizes a value.
|
||||
*
|
||||
* @throws InvalidTypeException if the value type is invalid
|
||||
*/
|
||||
public function normalize(mixed $value): mixed;
|
||||
|
||||
/**
|
||||
* Merges two values together.
|
||||
*
|
||||
* @throws ForbiddenOverwriteException if the configuration path cannot be overwritten
|
||||
* @throws InvalidTypeException if the value type is invalid
|
||||
*/
|
||||
public function merge(mixed $leftSide, mixed $rightSide): mixed;
|
||||
|
||||
/**
|
||||
* Finalizes a value.
|
||||
*
|
||||
* @throws InvalidTypeException if the value type is invalid
|
||||
* @throws InvalidConfigurationException if the value is invalid configuration
|
||||
*/
|
||||
public function finalize(mixed $value): mixed;
|
||||
}
|
58
plugins/simplesaml/lib/vendor/symfony/config/Definition/NumericNode.php
vendored
Normal file
58
plugins/simplesaml/lib/vendor/symfony/config/Definition/NumericNode.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
|
||||
/**
|
||||
* This node represents a numeric value in the config tree.
|
||||
*
|
||||
* @author David Jeanmonod <david.jeanmonod@gmail.com>
|
||||
*/
|
||||
class NumericNode extends ScalarNode
|
||||
{
|
||||
protected $min;
|
||||
protected $max;
|
||||
|
||||
public function __construct(?string $name, ?NodeInterface $parent = null, int|float|null $min = null, int|float|null $max = null, string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
|
||||
{
|
||||
parent::__construct($name, $parent, $pathSeparator);
|
||||
$this->min = $min;
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
protected function finalizeValue(mixed $value): mixed
|
||||
{
|
||||
$value = parent::finalizeValue($value);
|
||||
|
||||
$errorMsg = null;
|
||||
if (isset($this->min) && $value < $this->min) {
|
||||
$errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min);
|
||||
}
|
||||
if (isset($this->max) && $value > $this->max) {
|
||||
$errorMsg = sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max);
|
||||
}
|
||||
if (isset($errorMsg)) {
|
||||
$ex = new InvalidConfigurationException($errorMsg);
|
||||
$ex->setPath($this->getPath());
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function isValueEmpty(mixed $value): bool
|
||||
{
|
||||
// a numeric value cannot be empty
|
||||
return false;
|
||||
}
|
||||
}
|
89
plugins/simplesaml/lib/vendor/symfony/config/Definition/Processor.php
vendored
Normal file
89
plugins/simplesaml/lib/vendor/symfony/config/Definition/Processor.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
/**
|
||||
* This class is the entry point for config normalization/merging/finalization.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class Processor
|
||||
{
|
||||
/**
|
||||
* Processes an array of configurations.
|
||||
*
|
||||
* @param array $configs An array of configuration items to process
|
||||
*/
|
||||
public function process(NodeInterface $configTree, array $configs): array
|
||||
{
|
||||
$currentConfig = [];
|
||||
foreach ($configs as $config) {
|
||||
$config = $configTree->normalize($config);
|
||||
$currentConfig = $configTree->merge($currentConfig, $config);
|
||||
}
|
||||
|
||||
return $configTree->finalize($currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an array of configurations.
|
||||
*
|
||||
* @param array $configs An array of configuration items to process
|
||||
*/
|
||||
public function processConfiguration(ConfigurationInterface $configuration, array $configs): array
|
||||
{
|
||||
return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a configuration entry.
|
||||
*
|
||||
* This method returns a normalize configuration array for a given key
|
||||
* to remove the differences due to the original format (YAML and XML mainly).
|
||||
*
|
||||
* Here is an example.
|
||||
*
|
||||
* The configuration in XML:
|
||||
*
|
||||
* <twig:extension>twig.extension.foo</twig:extension>
|
||||
* <twig:extension>twig.extension.bar</twig:extension>
|
||||
*
|
||||
* And the same configuration in YAML:
|
||||
*
|
||||
* extensions: ['twig.extension.foo', 'twig.extension.bar']
|
||||
*
|
||||
* @param array $config A config array
|
||||
* @param string $key The key to normalize
|
||||
* @param string|null $plural The plural form of the key if it is irregular
|
||||
*/
|
||||
public static function normalizeConfig(array $config, string $key, ?string $plural = null): array
|
||||
{
|
||||
$plural ??= $key.'s';
|
||||
|
||||
if (isset($config[$plural])) {
|
||||
return $config[$plural];
|
||||
}
|
||||
|
||||
if (isset($config[$key])) {
|
||||
if (\is_string($config[$key]) || !\is_int(key($config[$key]))) {
|
||||
// only one
|
||||
return [$config[$key]];
|
||||
}
|
||||
|
||||
return $config[$key];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
27
plugins/simplesaml/lib/vendor/symfony/config/Definition/PrototypeNodeInterface.php
vendored
Normal file
27
plugins/simplesaml/lib/vendor/symfony/config/Definition/PrototypeNodeInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
/**
|
||||
* This interface must be implemented by nodes which can be used as prototypes.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface PrototypeNodeInterface extends NodeInterface
|
||||
{
|
||||
/**
|
||||
* Sets the name of the node.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setName(string $name);
|
||||
}
|
343
plugins/simplesaml/lib/vendor/symfony/config/Definition/PrototypedArrayNode.php
vendored
Normal file
343
plugins/simplesaml/lib/vendor/symfony/config/Definition/PrototypedArrayNode.php
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
|
||||
|
||||
/**
|
||||
* Represents a prototyped Array node in the config tree.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class PrototypedArrayNode extends ArrayNode
|
||||
{
|
||||
protected $prototype;
|
||||
protected $keyAttribute;
|
||||
protected $removeKeyAttribute = false;
|
||||
protected $minNumberOfElements = 0;
|
||||
protected $defaultValue = [];
|
||||
protected $defaultChildren;
|
||||
/**
|
||||
* @var NodeInterface[] An array of the prototypes of the simplified value children
|
||||
*/
|
||||
private array $valuePrototypes = [];
|
||||
|
||||
/**
|
||||
* Sets the minimum number of elements that a prototype based node must
|
||||
* contain. By default this is zero, meaning no elements.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMinNumberOfElements(int $number)
|
||||
{
|
||||
$this->minNumberOfElements = $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute which value is to be used as key.
|
||||
*
|
||||
* This is useful when you have an indexed array that should be an
|
||||
* associative array. You can select an item from within the array
|
||||
* to be the key of the particular item. For example, if "id" is the
|
||||
* "key", then:
|
||||
*
|
||||
* [
|
||||
* ['id' => 'my_name', 'foo' => 'bar'],
|
||||
* ];
|
||||
*
|
||||
* becomes
|
||||
*
|
||||
* [
|
||||
* 'my_name' => ['foo' => 'bar'],
|
||||
* ];
|
||||
*
|
||||
* If you'd like "'id' => 'my_name'" to still be present in the resulting
|
||||
* array, then you can set the second argument of this method to false.
|
||||
*
|
||||
* @param string $attribute The name of the attribute which value is to be used as a key
|
||||
* @param bool $remove Whether or not to remove the key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setKeyAttribute(string $attribute, bool $remove = true)
|
||||
{
|
||||
$this->keyAttribute = $attribute;
|
||||
$this->removeKeyAttribute = $remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the name of the attribute which value should be used as key.
|
||||
*/
|
||||
public function getKeyAttribute(): ?string
|
||||
{
|
||||
return $this->keyAttribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default value of this node.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValue(array $value)
|
||||
{
|
||||
$this->defaultValue = $value;
|
||||
}
|
||||
|
||||
public function hasDefaultValue(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds default children when none are set.
|
||||
*
|
||||
* @param int|string|array|null $children The number of children|The child name|The children names to be added
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAddChildrenIfNoneSet(int|string|array|null $children = ['defaults'])
|
||||
{
|
||||
if (null === $children) {
|
||||
$this->defaultChildren = ['defaults'];
|
||||
} else {
|
||||
$this->defaultChildren = \is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default value could be either explicited or derived from the prototype
|
||||
* default value.
|
||||
*/
|
||||
public function getDefaultValue(): mixed
|
||||
{
|
||||
if (null !== $this->defaultChildren) {
|
||||
$default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : [];
|
||||
$defaults = [];
|
||||
foreach (array_values($this->defaultChildren) as $i => $name) {
|
||||
$defaults[null === $this->keyAttribute ? $i : $name] = $default;
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
return $this->defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node prototype.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPrototype(PrototypeNodeInterface $node)
|
||||
{
|
||||
$this->prototype = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the prototype.
|
||||
*/
|
||||
public function getPrototype(): PrototypeNodeInterface
|
||||
{
|
||||
return $this->prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable adding concrete children for prototyped nodes.
|
||||
*
|
||||
* @return never
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function addChild(NodeInterface $node)
|
||||
{
|
||||
throw new Exception('A prototyped array node cannot have concrete children.');
|
||||
}
|
||||
|
||||
protected function finalizeValue(mixed $value): mixed
|
||||
{
|
||||
if (false === $value) {
|
||||
throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), json_encode($value)));
|
||||
}
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
$prototype = $this->getPrototypeForChild($k);
|
||||
try {
|
||||
$value[$k] = $prototype->finalize($v);
|
||||
} catch (UnsetKeyException) {
|
||||
unset($value[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($value) < $this->minNumberOfElements) {
|
||||
$ex = new InvalidConfigurationException(sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DuplicateKeyException
|
||||
*/
|
||||
protected function normalizeValue(mixed $value): mixed
|
||||
{
|
||||
if (false === $value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = $this->remapXml($value);
|
||||
|
||||
$isList = array_is_list($value);
|
||||
$normalized = [];
|
||||
foreach ($value as $k => $v) {
|
||||
if (null !== $this->keyAttribute && \is_array($v)) {
|
||||
if (!isset($v[$this->keyAttribute]) && \is_int($k) && $isList) {
|
||||
$ex = new InvalidConfigurationException(sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath()));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
} elseif (isset($v[$this->keyAttribute])) {
|
||||
$k = $v[$this->keyAttribute];
|
||||
|
||||
if (\is_float($k)) {
|
||||
$k = var_export($k, true);
|
||||
}
|
||||
|
||||
// remove the key attribute when required
|
||||
if ($this->removeKeyAttribute) {
|
||||
unset($v[$this->keyAttribute]);
|
||||
}
|
||||
|
||||
// if only "value" is left
|
||||
if (array_keys($v) === ['value']) {
|
||||
$v = $v['value'];
|
||||
if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && \array_key_exists('value', $children)) {
|
||||
$valuePrototype = current($this->valuePrototypes) ?: clone $children['value'];
|
||||
$valuePrototype->parent = $this;
|
||||
$originalClosures = $this->prototype->normalizationClosures;
|
||||
if (\is_array($originalClosures)) {
|
||||
$valuePrototypeClosures = $valuePrototype->normalizationClosures;
|
||||
$valuePrototype->normalizationClosures = \is_array($valuePrototypeClosures) ? array_merge($originalClosures, $valuePrototypeClosures) : $originalClosures;
|
||||
}
|
||||
$this->valuePrototypes[$k] = $valuePrototype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (\array_key_exists($k, $normalized)) {
|
||||
$ex = new DuplicateKeyException(sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath()));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
$prototype = $this->getPrototypeForChild($k);
|
||||
if (null !== $this->keyAttribute || !$isList) {
|
||||
$normalized[$k] = $prototype->normalize($v);
|
||||
} else {
|
||||
$normalized[] = $prototype->normalize($v);
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
protected function mergeValues(mixed $leftSide, mixed $rightSide): mixed
|
||||
{
|
||||
if (false === $rightSide) {
|
||||
// if this is still false after the last config has been merged the
|
||||
// finalization pass will take care of removing this key entirely
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === $leftSide || !$this->performDeepMerging) {
|
||||
return $rightSide;
|
||||
}
|
||||
|
||||
$isList = array_is_list($rightSide);
|
||||
foreach ($rightSide as $k => $v) {
|
||||
// prototype, and key is irrelevant there are no named keys, append the element
|
||||
if (null === $this->keyAttribute && $isList) {
|
||||
$leftSide[] = $v;
|
||||
continue;
|
||||
}
|
||||
|
||||
// no conflict
|
||||
if (!\array_key_exists($k, $leftSide)) {
|
||||
if (!$this->allowNewKeys) {
|
||||
$ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file.', $this->getPath()));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
$leftSide[$k] = $v;
|
||||
continue;
|
||||
}
|
||||
|
||||
$prototype = $this->getPrototypeForChild($k);
|
||||
$leftSide[$k] = $prototype->merge($leftSide[$k], $v);
|
||||
}
|
||||
|
||||
return $leftSide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a prototype for the child node that is associated to $key in the value array.
|
||||
* For general child nodes, this will be $this->prototype.
|
||||
* But if $this->removeKeyAttribute is true and there are only two keys in the child node:
|
||||
* one is same as this->keyAttribute and the other is 'value', then the prototype will be different.
|
||||
*
|
||||
* For example, assume $this->keyAttribute is 'name' and the value array is as follows:
|
||||
*
|
||||
* [
|
||||
* [
|
||||
* 'name' => 'name001',
|
||||
* 'value' => 'value001'
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* Now, the key is 0 and the child node is:
|
||||
*
|
||||
* [
|
||||
* 'name' => 'name001',
|
||||
* 'value' => 'value001'
|
||||
* ]
|
||||
*
|
||||
* When normalizing the value array, the 'name' element will removed from the child node
|
||||
* and its value becomes the new key of the child node:
|
||||
*
|
||||
* [
|
||||
* 'name001' => ['value' => 'value001']
|
||||
* ]
|
||||
*
|
||||
* Now only 'value' element is left in the child node which can be further simplified into a string:
|
||||
*
|
||||
* ['name001' => 'value001']
|
||||
*
|
||||
* Now, the key becomes 'name001' and the child node becomes 'value001' and
|
||||
* the prototype of child node 'name001' should be a ScalarNode instead of an ArrayNode instance.
|
||||
*/
|
||||
private function getPrototypeForChild(string $key): mixed
|
||||
{
|
||||
$prototype = $this->valuePrototypes[$key] ?? $this->prototype;
|
||||
$prototype->setName($key);
|
||||
|
||||
return $prototype;
|
||||
}
|
||||
}
|
61
plugins/simplesaml/lib/vendor/symfony/config/Definition/ScalarNode.php
vendored
Normal file
61
plugins/simplesaml/lib/vendor/symfony/config/Definition/ScalarNode.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
|
||||
|
||||
/**
|
||||
* This node represents a scalar value in the config tree.
|
||||
*
|
||||
* The following values are considered scalars:
|
||||
* * booleans
|
||||
* * strings
|
||||
* * null
|
||||
* * integers
|
||||
* * floats
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ScalarNode extends VariableNode
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
if (!\is_scalar($value) && null !== $value) {
|
||||
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "scalar", but got "%s".', $this->getPath(), get_debug_type($value)));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$ex->addHint($hint);
|
||||
}
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
protected function isValueEmpty(mixed $value): bool
|
||||
{
|
||||
// assume environment variables are never empty (which in practice is likely to be true during runtime)
|
||||
// not doing so breaks many configs that are valid today
|
||||
if ($this->isHandlingPlaceholder()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return null === $value || '' === $value;
|
||||
}
|
||||
|
||||
protected function getValidPlaceholderTypes(): array
|
||||
{
|
||||
return ['bool', 'int', 'float', 'string'];
|
||||
}
|
||||
}
|
128
plugins/simplesaml/lib/vendor/symfony/config/Definition/VariableNode.php
vendored
Normal file
128
plugins/simplesaml/lib/vendor/symfony/config/Definition/VariableNode.php
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Definition;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
|
||||
/**
|
||||
* This node represents a value of variable type in the config tree.
|
||||
*
|
||||
* This node is intended for values of arbitrary type.
|
||||
* Any PHP type is accepted as a value.
|
||||
*
|
||||
* @author Jeremy Mikola <jmikola@gmail.com>
|
||||
*/
|
||||
class VariableNode extends BaseNode implements PrototypeNodeInterface
|
||||
{
|
||||
protected $defaultValueSet = false;
|
||||
protected $defaultValue;
|
||||
protected $allowEmptyValue = true;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValue(mixed $value)
|
||||
{
|
||||
$this->defaultValueSet = true;
|
||||
$this->defaultValue = $value;
|
||||
}
|
||||
|
||||
public function hasDefaultValue(): bool
|
||||
{
|
||||
return $this->defaultValueSet;
|
||||
}
|
||||
|
||||
public function getDefaultValue(): mixed
|
||||
{
|
||||
$v = $this->defaultValue;
|
||||
|
||||
return $v instanceof \Closure ? $v() : $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this node is allowed to have an empty value.
|
||||
*
|
||||
* @param bool $boolean True if this entity will accept empty values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAllowEmptyValue(bool $boolean)
|
||||
{
|
||||
$this->allowEmptyValue = $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setName(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function validateType(mixed $value)
|
||||
{
|
||||
}
|
||||
|
||||
protected function finalizeValue(mixed $value): mixed
|
||||
{
|
||||
// deny environment variables only when using custom validators
|
||||
// this avoids ever passing an empty value to final validation closures
|
||||
if (!$this->allowEmptyValue && $this->isHandlingPlaceholder() && $this->finalValidationClosures) {
|
||||
$e = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an environment variable when empty values are not allowed by definition and are validated.', $this->getPath()));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$e->addHint($hint);
|
||||
}
|
||||
$e->setPath($this->getPath());
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (!$this->allowEmptyValue && $this->isValueEmpty($value)) {
|
||||
$ex = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an empty value, but got %s.', $this->getPath(), json_encode($value)));
|
||||
if ($hint = $this->getInfo()) {
|
||||
$ex->addHint($hint);
|
||||
}
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function normalizeValue(mixed $value): mixed
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function mergeValues(mixed $leftSide, mixed $rightSide): mixed
|
||||
{
|
||||
return $rightSide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates if the given value is to be treated as empty.
|
||||
*
|
||||
* By default, PHP's empty() function is used to test for emptiness. This
|
||||
* method may be overridden by subtypes to better match their understanding
|
||||
* of empty data.
|
||||
*
|
||||
* @see finalizeValue()
|
||||
*/
|
||||
protected function isValueEmpty(mixed $value): bool
|
||||
{
|
||||
return empty($value);
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Exception;
|
||||
|
||||
/**
|
||||
* Exception class for when a circular reference is detected when importing resources.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FileLoaderImportCircularReferenceException extends LoaderLoadException
|
||||
{
|
||||
public function __construct(array $resources, int $code = 0, ?\Throwable $previous = null)
|
||||
{
|
||||
$message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);
|
||||
|
||||
\Exception::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
37
plugins/simplesaml/lib/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php
vendored
Normal file
37
plugins/simplesaml/lib/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Exception;
|
||||
|
||||
/**
|
||||
* File locator exception if a file does not exist.
|
||||
*
|
||||
* @author Leo Feyer <https://github.com/leofeyer>
|
||||
*/
|
||||
class FileLocatorFileNotFoundException extends \InvalidArgumentException
|
||||
{
|
||||
private array $paths;
|
||||
|
||||
public function __construct(string $message = '', int $code = 0, ?\Throwable $previous = null, array $paths = [])
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
|
||||
$this->paths = $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
}
|
115
plugins/simplesaml/lib/vendor/symfony/config/Exception/LoaderLoadException.php
vendored
Normal file
115
plugins/simplesaml/lib/vendor/symfony/config/Exception/LoaderLoadException.php
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Exception;
|
||||
|
||||
/**
|
||||
* Exception class for when a resource cannot be loaded or imported.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@thatsquality.com>
|
||||
*/
|
||||
class LoaderLoadException extends \Exception
|
||||
{
|
||||
/**
|
||||
* @param mixed $resource The resource that could not be imported
|
||||
* @param string|null $sourceResource The original resource importing the new resource
|
||||
* @param int $code The error code
|
||||
* @param \Throwable|null $previous A previous exception
|
||||
* @param string|null $type The type of resource
|
||||
*/
|
||||
public function __construct(mixed $resource, ?string $sourceResource = null, int $code = 0, ?\Throwable $previous = null, ?string $type = null)
|
||||
{
|
||||
if (!\is_string($resource)) {
|
||||
try {
|
||||
$resource = json_encode($resource, \JSON_THROW_ON_ERROR);
|
||||
} catch (\JsonException) {
|
||||
$resource = sprintf('resource of type "%s"', get_debug_type($resource));
|
||||
}
|
||||
}
|
||||
|
||||
$message = '';
|
||||
if ($previous) {
|
||||
// Include the previous exception, to help the user see what might be the underlying cause
|
||||
|
||||
// Trim the trailing period of the previous message. We only want 1 period remove so no rtrim...
|
||||
if (str_ends_with($previous->getMessage(), '.')) {
|
||||
$trimmedMessage = substr($previous->getMessage(), 0, -1);
|
||||
$message .= sprintf('%s', $trimmedMessage).' in ';
|
||||
} else {
|
||||
$message .= sprintf('%s', $previous->getMessage()).' in ';
|
||||
}
|
||||
$message .= $resource.' ';
|
||||
|
||||
// show tweaked trace to complete the human readable sentence
|
||||
if (null === $sourceResource) {
|
||||
$message .= sprintf('(which is loaded in resource "%s")', $resource);
|
||||
} else {
|
||||
$message .= sprintf('(which is being imported from "%s")', $sourceResource);
|
||||
}
|
||||
$message .= '.';
|
||||
|
||||
// if there's no previous message, present it the default way
|
||||
} elseif (null === $sourceResource) {
|
||||
$message .= sprintf('Cannot load resource "%s".', $resource);
|
||||
} else {
|
||||
$message .= sprintf('Cannot import resource "%s" from "%s".', $resource, $sourceResource);
|
||||
}
|
||||
|
||||
// Is the resource located inside a bundle?
|
||||
if ('@' === $resource[0]) {
|
||||
$parts = explode(\DIRECTORY_SEPARATOR, $resource);
|
||||
$bundle = substr($parts[0], 1);
|
||||
$message .= sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
|
||||
$message .= sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource);
|
||||
} elseif (null !== $type) {
|
||||
$message .= sprintf(' Make sure there is a loader supporting the "%s" type.', $type);
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function varToString(mixed $var)
|
||||
{
|
||||
if (\is_object($var)) {
|
||||
return sprintf('Object(%s)', $var::class);
|
||||
}
|
||||
|
||||
if (\is_array($var)) {
|
||||
$a = [];
|
||||
foreach ($var as $k => $v) {
|
||||
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
||||
}
|
||||
|
||||
return sprintf('Array(%s)', implode(', ', $a));
|
||||
}
|
||||
|
||||
if (\is_resource($var)) {
|
||||
return sprintf('Resource(%s)', get_resource_type($var));
|
||||
}
|
||||
|
||||
if (null === $var) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (false === $var) {
|
||||
return 'false';
|
||||
}
|
||||
|
||||
if (true === $var) {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
return (string) $var;
|
||||
}
|
||||
}
|
97
plugins/simplesaml/lib/vendor/symfony/config/FileLocator.php
vendored
Normal file
97
plugins/simplesaml/lib/vendor/symfony/config/FileLocator.php
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
|
||||
|
||||
/**
|
||||
* FileLocator uses an array of pre-defined paths to find files.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FileLocator implements FileLocatorInterface
|
||||
{
|
||||
protected $paths;
|
||||
|
||||
/**
|
||||
* @param string|string[] $paths A path or an array of paths where to look for resources
|
||||
*/
|
||||
public function __construct(string|array $paths = [])
|
||||
{
|
||||
$this->paths = (array) $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|string[]
|
||||
*
|
||||
* @psalm-return ($first is true ? string : string[])
|
||||
*/
|
||||
public function locate(string $name, ?string $currentPath = null, bool $first = true)
|
||||
{
|
||||
if ('' === $name) {
|
||||
throw new \InvalidArgumentException('An empty file name is not valid to be located.');
|
||||
}
|
||||
|
||||
if ($this->isAbsolutePath($name)) {
|
||||
if (!file_exists($name)) {
|
||||
throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist.', $name), 0, null, [$name]);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
$paths = $this->paths;
|
||||
|
||||
if (null !== $currentPath) {
|
||||
array_unshift($paths, $currentPath);
|
||||
}
|
||||
|
||||
$paths = array_unique($paths);
|
||||
$filepaths = $notfound = [];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (@file_exists($file = $path.\DIRECTORY_SEPARATOR.$name)) {
|
||||
if (true === $first) {
|
||||
return $file;
|
||||
}
|
||||
$filepaths[] = $file;
|
||||
} else {
|
||||
$notfound[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$filepaths) {
|
||||
throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist (in: "%s").', $name, implode('", "', $paths)), 0, null, $notfound);
|
||||
}
|
||||
|
||||
return $filepaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the file path is an absolute path.
|
||||
*/
|
||||
private function isAbsolutePath(string $file): bool
|
||||
{
|
||||
if ('/' === $file[0] || '\\' === $file[0]
|
||||
|| (\strlen($file) > 3 && ctype_alpha($file[0])
|
||||
&& ':' === $file[1]
|
||||
&& ('\\' === $file[2] || '/' === $file[2])
|
||||
)
|
||||
|| parse_url($file, \PHP_URL_SCHEME)
|
||||
|| str_starts_with($file, 'phar:///') // "parse_url()" doesn't handle absolute phar path, despite being valid
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
36
plugins/simplesaml/lib/vendor/symfony/config/FileLocatorInterface.php
vendored
Normal file
36
plugins/simplesaml/lib/vendor/symfony/config/FileLocatorInterface.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface FileLocatorInterface
|
||||
{
|
||||
/**
|
||||
* Returns a full path for a given file name.
|
||||
*
|
||||
* @param string $name The file name to locate
|
||||
* @param string|null $currentPath The current path
|
||||
* @param bool $first Whether to return the first occurrence or an array of filenames
|
||||
*
|
||||
* @return string|string[] The full path to the file or an array of file paths
|
||||
*
|
||||
* @throws \InvalidArgumentException If $name is empty
|
||||
* @throws FileLocatorFileNotFoundException If a file is not found
|
||||
*
|
||||
* @psalm-return ($first is true ? string : string[])
|
||||
*/
|
||||
public function locate(string $name, ?string $currentPath = null, bool $first = true);
|
||||
}
|
19
plugins/simplesaml/lib/vendor/symfony/config/LICENSE
vendored
Normal file
19
plugins/simplesaml/lib/vendor/symfony/config/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2004-present Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
44
plugins/simplesaml/lib/vendor/symfony/config/Loader/DelegatingLoader.php
vendored
Normal file
44
plugins/simplesaml/lib/vendor/symfony/config/Loader/DelegatingLoader.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
use Symfony\Component\Config\Exception\LoaderLoadException;
|
||||
|
||||
/**
|
||||
* DelegatingLoader delegates loading to other loaders using a loader resolver.
|
||||
*
|
||||
* This loader acts as an array of LoaderInterface objects - each having
|
||||
* a chance to load a given resource (handled by the resolver)
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DelegatingLoader extends Loader
|
||||
{
|
||||
public function __construct(LoaderResolverInterface $resolver)
|
||||
{
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
public function load(mixed $resource, ?string $type = null): mixed
|
||||
{
|
||||
if (false === $loader = $this->resolver->resolve($resource, $type)) {
|
||||
throw new LoaderLoadException($resource, null, 0, null, $type);
|
||||
}
|
||||
|
||||
return $loader->load($resource, $type);
|
||||
}
|
||||
|
||||
public function supports(mixed $resource, ?string $type = null): bool
|
||||
{
|
||||
return false !== $this->resolver->resolve($resource, $type);
|
||||
}
|
||||
}
|
22
plugins/simplesaml/lib/vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php
vendored
Normal file
22
plugins/simplesaml/lib/vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
/**
|
||||
* A loader that can be scoped to a given filesystem directory.
|
||||
*
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*/
|
||||
interface DirectoryAwareLoaderInterface
|
||||
{
|
||||
public function forDirectory(string $currentDirectory): static;
|
||||
}
|
188
plugins/simplesaml/lib/vendor/symfony/config/Loader/FileLoader.php
vendored
Normal file
188
plugins/simplesaml/lib/vendor/symfony/config/Loader/FileLoader.php
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
|
||||
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
|
||||
use Symfony\Component\Config\Exception\LoaderLoadException;
|
||||
use Symfony\Component\Config\FileLocatorInterface;
|
||||
use Symfony\Component\Config\Resource\FileExistenceResource;
|
||||
use Symfony\Component\Config\Resource\GlobResource;
|
||||
|
||||
/**
|
||||
* FileLoader is the abstract class used by all built-in loaders that are file based.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class FileLoader extends Loader
|
||||
{
|
||||
protected static $loading = [];
|
||||
|
||||
protected $locator;
|
||||
|
||||
private ?string $currentDir = null;
|
||||
|
||||
public function __construct(FileLocatorInterface $locator, ?string $env = null)
|
||||
{
|
||||
$this->locator = $locator;
|
||||
parent::__construct($env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current directory.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCurrentDir(string $dir)
|
||||
{
|
||||
$this->currentDir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file locator used by this loader.
|
||||
*/
|
||||
public function getLocator(): FileLocatorInterface
|
||||
{
|
||||
return $this->locator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a resource.
|
||||
*
|
||||
* @param mixed $resource A Resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
* @param bool $ignoreErrors Whether to ignore import errors or not
|
||||
* @param string|null $sourceResource The original resource importing the new resource
|
||||
* @param string|string[]|null $exclude Glob patterns to exclude from the import
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws LoaderLoadException
|
||||
* @throws FileLoaderImportCircularReferenceException
|
||||
* @throws FileLocatorFileNotFoundException
|
||||
*/
|
||||
public function import(mixed $resource, ?string $type = null, bool $ignoreErrors = false, ?string $sourceResource = null, string|array|null $exclude = null)
|
||||
{
|
||||
if (\is_string($resource) && \strlen($resource) !== ($i = strcspn($resource, '*?{[')) && !str_contains($resource, "\n")) {
|
||||
$excluded = [];
|
||||
foreach ((array) $exclude as $pattern) {
|
||||
foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) {
|
||||
// normalize Windows slashes and remove trailing slashes
|
||||
$excluded[rtrim(str_replace('\\', '/', $path), '/')] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
$isSubpath = 0 !== $i && str_contains(substr($resource, 0, $i), '/');
|
||||
foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath, false, $excluded) as $path => $info) {
|
||||
if (null !== $res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource)) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
$isSubpath = true;
|
||||
}
|
||||
|
||||
if ($isSubpath) {
|
||||
return isset($ret[1]) ? $ret : ($ret[0] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->doImport($resource, $type, $ignoreErrors, $sourceResource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected function glob(string $pattern, bool $recursive, array|GlobResource|null &$resource = null, bool $ignoreErrors = false, bool $forExclusion = false, array $excluded = []): iterable
|
||||
{
|
||||
if (\strlen($pattern) === $i = strcspn($pattern, '*?{[')) {
|
||||
$prefix = $pattern;
|
||||
$pattern = '';
|
||||
} elseif (0 === $i || !str_contains(substr($pattern, 0, $i), '/')) {
|
||||
$prefix = '.';
|
||||
$pattern = '/'.$pattern;
|
||||
} else {
|
||||
$prefix = \dirname(substr($pattern, 0, 1 + $i));
|
||||
$pattern = substr($pattern, \strlen($prefix));
|
||||
}
|
||||
|
||||
try {
|
||||
$prefix = $this->locator->locate($prefix, $this->currentDir, true);
|
||||
} catch (FileLocatorFileNotFoundException $e) {
|
||||
if (!$ignoreErrors) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$resource = [];
|
||||
foreach ($e->getPaths() as $path) {
|
||||
$resource[] = new FileExistenceResource($path);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
$resource = new GlobResource($prefix, $pattern, $recursive, $forExclusion, $excluded);
|
||||
|
||||
yield from $resource;
|
||||
}
|
||||
|
||||
private function doImport(mixed $resource, ?string $type = null, bool $ignoreErrors = false, ?string $sourceResource = null): mixed
|
||||
{
|
||||
try {
|
||||
$loader = $this->resolve($resource, $type);
|
||||
|
||||
if ($loader instanceof DirectoryAwareLoaderInterface) {
|
||||
$loader = $loader->forDirectory($this->currentDir);
|
||||
}
|
||||
|
||||
if (!$loader instanceof self) {
|
||||
return $loader->load($resource, $type);
|
||||
}
|
||||
|
||||
if (null !== $this->currentDir) {
|
||||
$resource = $loader->getLocator()->locate($resource, $this->currentDir, false);
|
||||
}
|
||||
|
||||
$resources = \is_array($resource) ? $resource : [$resource];
|
||||
for ($i = 0; $i < $resourcesCount = \count($resources); ++$i) {
|
||||
if (isset(self::$loading[$resources[$i]])) {
|
||||
if ($i == $resourcesCount - 1) {
|
||||
throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
|
||||
}
|
||||
} else {
|
||||
$resource = $resources[$i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
self::$loading[$resource] = true;
|
||||
|
||||
try {
|
||||
$ret = $loader->load($resource, $type);
|
||||
} finally {
|
||||
unset(self::$loading[$resource]);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
} catch (FileLoaderImportCircularReferenceException $e) {
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
if (!$ignoreErrors) {
|
||||
// prevent embedded imports from nesting multiple exceptions
|
||||
if ($e instanceof LoaderLoadException) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
throw new LoaderLoadException($resource, $sourceResource, 0, $e, $type);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
30
plugins/simplesaml/lib/vendor/symfony/config/Loader/GlobFileLoader.php
vendored
Normal file
30
plugins/simplesaml/lib/vendor/symfony/config/Loader/GlobFileLoader.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
/**
|
||||
* GlobFileLoader loads files from a glob pattern.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class GlobFileLoader extends FileLoader
|
||||
{
|
||||
public function load(mixed $resource, ?string $type = null): mixed
|
||||
{
|
||||
return $this->import($resource);
|
||||
}
|
||||
|
||||
public function supports(mixed $resource, ?string $type = null): bool
|
||||
{
|
||||
return 'glob' === $type;
|
||||
}
|
||||
}
|
73
plugins/simplesaml/lib/vendor/symfony/config/Loader/Loader.php
vendored
Normal file
73
plugins/simplesaml/lib/vendor/symfony/config/Loader/Loader.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
use Symfony\Component\Config\Exception\LoaderLoadException;
|
||||
|
||||
/**
|
||||
* Loader is the abstract class used by all built-in loaders.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Loader implements LoaderInterface
|
||||
{
|
||||
protected $resolver;
|
||||
protected $env;
|
||||
|
||||
public function __construct(?string $env = null)
|
||||
{
|
||||
$this->env = $env;
|
||||
}
|
||||
|
||||
public function getResolver(): LoaderResolverInterface
|
||||
{
|
||||
return $this->resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setResolver(LoaderResolverInterface $resolver)
|
||||
{
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a resource.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function import(mixed $resource, ?string $type = null)
|
||||
{
|
||||
return $this->resolve($resource, $type)->load($resource, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a loader able to load an imported resource.
|
||||
*
|
||||
* @throws LoaderLoadException If no loader is found
|
||||
*/
|
||||
public function resolve(mixed $resource, ?string $type = null): LoaderInterface
|
||||
{
|
||||
if ($this->supports($resource, $type)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);
|
||||
|
||||
if (false === $loader) {
|
||||
throw new LoaderLoadException($resource, null, 0, null, $type);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
52
plugins/simplesaml/lib/vendor/symfony/config/Loader/LoaderInterface.php
vendored
Normal file
52
plugins/simplesaml/lib/vendor/symfony/config/Loader/LoaderInterface.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
/**
|
||||
* LoaderInterface is the interface implemented by all loader classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Loads a resource.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Exception If something went wrong
|
||||
*/
|
||||
public function load(mixed $resource, ?string $type = null);
|
||||
|
||||
/**
|
||||
* Returns whether this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(mixed $resource, ?string $type = null);
|
||||
|
||||
/**
|
||||
* Gets the loader resolver.
|
||||
*
|
||||
* @return LoaderResolverInterface
|
||||
*/
|
||||
public function getResolver();
|
||||
|
||||
/**
|
||||
* Sets the loader resolver.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setResolver(LoaderResolverInterface $resolver);
|
||||
}
|
68
plugins/simplesaml/lib/vendor/symfony/config/Loader/LoaderResolver.php
vendored
Normal file
68
plugins/simplesaml/lib/vendor/symfony/config/Loader/LoaderResolver.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
/**
|
||||
* LoaderResolver selects a loader for a given resource.
|
||||
*
|
||||
* A resource can be anything (e.g. a full path to a config file or a Closure).
|
||||
* Each loader determines whether it can load a resource and how.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class LoaderResolver implements LoaderResolverInterface
|
||||
{
|
||||
/**
|
||||
* @var LoaderInterface[] An array of LoaderInterface objects
|
||||
*/
|
||||
private array $loaders = [];
|
||||
|
||||
/**
|
||||
* @param LoaderInterface[] $loaders An array of loaders
|
||||
*/
|
||||
public function __construct(array $loaders = [])
|
||||
{
|
||||
foreach ($loaders as $loader) {
|
||||
$this->addLoader($loader);
|
||||
}
|
||||
}
|
||||
|
||||
public function resolve(mixed $resource, ?string $type = null): LoaderInterface|false
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
if ($loader->supports($resource, $type)) {
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addLoader(LoaderInterface $loader)
|
||||
{
|
||||
$this->loaders[] = $loader;
|
||||
$loader->setResolver($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered loaders.
|
||||
*
|
||||
* @return LoaderInterface[]
|
||||
*/
|
||||
public function getLoaders(): array
|
||||
{
|
||||
return $this->loaders;
|
||||
}
|
||||
}
|
27
plugins/simplesaml/lib/vendor/symfony/config/Loader/LoaderResolverInterface.php
vendored
Normal file
27
plugins/simplesaml/lib/vendor/symfony/config/Loader/LoaderResolverInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
/**
|
||||
* LoaderResolverInterface selects a loader for a given resource.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface LoaderResolverInterface
|
||||
{
|
||||
/**
|
||||
* Returns a loader able to load the resource.
|
||||
*
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*/
|
||||
public function resolve(mixed $resource, ?string $type = null): LoaderInterface|false;
|
||||
}
|
32
plugins/simplesaml/lib/vendor/symfony/config/Loader/ParamConfigurator.php
vendored
Normal file
32
plugins/simplesaml/lib/vendor/symfony/config/Loader/ParamConfigurator.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Loader;
|
||||
|
||||
/**
|
||||
* Placeholder for a parameter.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ParamConfigurator
|
||||
{
|
||||
private string $name;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '%'.$this->name.'%';
|
||||
}
|
||||
}
|
15
plugins/simplesaml/lib/vendor/symfony/config/README.md
vendored
Normal file
15
plugins/simplesaml/lib/vendor/symfony/config/README.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
Config Component
|
||||
================
|
||||
|
||||
The Config component helps find, load, combine, autofill and validate
|
||||
configuration values of any kind, whatever their source may be (YAML, XML, INI
|
||||
files, or for instance a database).
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* [Documentation](https://symfony.com/doc/current/components/config.html)
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
227
plugins/simplesaml/lib/vendor/symfony/config/Resource/ClassExistenceResource.php
vendored
Normal file
227
plugins/simplesaml/lib/vendor/symfony/config/Resource/ClassExistenceResource.php
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* ClassExistenceResource represents a class existence.
|
||||
* Freshness is only evaluated against resource existence.
|
||||
*
|
||||
* The resource must be a fully-qualified class name.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
private string $resource;
|
||||
private ?array $exists = null;
|
||||
|
||||
private static int $autoloadLevel = 0;
|
||||
private static ?string $autoloadedClass = null;
|
||||
private static array $existsCache = [];
|
||||
|
||||
/**
|
||||
* @param string $resource The fully-qualified class name
|
||||
* @param bool|null $exists Boolean when the existence check has already been done
|
||||
*/
|
||||
public function __construct(string $resource, ?bool $exists = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
if (null !== $exists) {
|
||||
$this->exists = [$exists, null];
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function getResource(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \ReflectionException when a parent class/interface/trait is not found
|
||||
*/
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
$loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
|
||||
|
||||
if (null !== $exists = &self::$existsCache[$this->resource]) {
|
||||
if ($loaded) {
|
||||
$exists = [true, null];
|
||||
} elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) {
|
||||
throw new \ReflectionException($exists[1]);
|
||||
}
|
||||
} elseif ([false, null] === $exists = [$loaded, null]) {
|
||||
if (!self::$autoloadLevel++) {
|
||||
spl_autoload_register(__CLASS__.'::throwOnRequiredClass');
|
||||
}
|
||||
$autoloadedClass = self::$autoloadedClass;
|
||||
self::$autoloadedClass = ltrim($this->resource, '\\');
|
||||
|
||||
try {
|
||||
$exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
|
||||
} catch (\Exception $e) {
|
||||
$exists[1] = $e->getMessage();
|
||||
|
||||
try {
|
||||
self::throwOnRequiredClass($this->resource, $e);
|
||||
} catch (\ReflectionException $e) {
|
||||
if (0 >= $timestamp) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$exists[1] = $e->getMessage();
|
||||
|
||||
throw $e;
|
||||
} finally {
|
||||
self::$autoloadedClass = $autoloadedClass;
|
||||
if (!--self::$autoloadLevel) {
|
||||
spl_autoload_unregister(__CLASS__.'::throwOnRequiredClass');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->exists ??= $exists;
|
||||
|
||||
return $this->exists[0] xor !$exists[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
if (null === $this->exists) {
|
||||
$this->isFresh(0);
|
||||
}
|
||||
|
||||
return ['resource', 'exists'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup(): void
|
||||
{
|
||||
if (\is_bool($this->exists)) {
|
||||
$this->exists = [$this->exists, null];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws a reflection exception when the passed class does not exist but is required.
|
||||
*
|
||||
* A class is considered "not required" when it's loaded as part of a "class_exists" or similar check.
|
||||
*
|
||||
* This function can be used as an autoload function to throw a reflection
|
||||
* exception if the class was not found by previous autoload functions.
|
||||
*
|
||||
* A previous exception can be passed. In this case, the class is considered as being
|
||||
* required totally, so if it doesn't exist, a reflection exception is always thrown.
|
||||
* If it exists, the previous exception is rethrown.
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function throwOnRequiredClass(string $class, ?\Exception $previous = null): void
|
||||
{
|
||||
// If the passed class is the resource being checked, we shouldn't throw.
|
||||
if (null === $previous && self::$autoloadedClass === $class) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) {
|
||||
if (null !== $previous) {
|
||||
throw $previous;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($previous instanceof \ReflectionException) {
|
||||
throw $previous;
|
||||
}
|
||||
|
||||
$message = sprintf('Class "%s" not found.', $class);
|
||||
|
||||
if ($class !== (self::$autoloadedClass ?? $class)) {
|
||||
$message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
|
||||
}
|
||||
|
||||
if (null !== $previous) {
|
||||
$message = $previous->getMessage();
|
||||
}
|
||||
|
||||
$e = new \ReflectionException($message, 0, $previous);
|
||||
|
||||
if (null !== $previous) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$trace = debug_backtrace();
|
||||
$autoloadFrame = [
|
||||
'function' => 'spl_autoload_call',
|
||||
'args' => [$class],
|
||||
];
|
||||
|
||||
if (isset($trace[1])) {
|
||||
$callerFrame = $trace[1];
|
||||
$i = 2;
|
||||
} elseif (false !== $i = array_search($autoloadFrame, $trace, true)) {
|
||||
$callerFrame = $trace[++$i];
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (isset($callerFrame['function']) && !isset($callerFrame['class'])) {
|
||||
switch ($callerFrame['function']) {
|
||||
case 'get_class_methods':
|
||||
case 'get_class_vars':
|
||||
case 'get_parent_class':
|
||||
case 'is_a':
|
||||
case 'is_subclass_of':
|
||||
case 'class_exists':
|
||||
case 'class_implements':
|
||||
case 'class_parents':
|
||||
case 'trait_exists':
|
||||
case 'defined':
|
||||
case 'interface_exists':
|
||||
case 'method_exists':
|
||||
case 'property_exists':
|
||||
case 'is_callable':
|
||||
return;
|
||||
}
|
||||
|
||||
$props = [
|
||||
'file' => $callerFrame['file'] ?? null,
|
||||
'line' => $callerFrame['line'] ?? null,
|
||||
'trace' => \array_slice($trace, 1 + $i),
|
||||
];
|
||||
|
||||
foreach ($props as $p => $v) {
|
||||
if (null !== $v) {
|
||||
$r = new \ReflectionProperty(\Exception::class, $p);
|
||||
$r->setValue($e, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
64
plugins/simplesaml/lib/vendor/symfony/config/Resource/ComposerResource.php
vendored
Normal file
64
plugins/simplesaml/lib/vendor/symfony/config/Resource/ComposerResource.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* ComposerResource tracks the PHP version and Composer dependencies.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class ComposerResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
private array $vendors;
|
||||
|
||||
private static array $runtimeVendors;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
self::refresh();
|
||||
$this->vendors = self::$runtimeVendors;
|
||||
}
|
||||
|
||||
public function getVendors(): array
|
||||
{
|
||||
return array_keys($this->vendors);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return __CLASS__;
|
||||
}
|
||||
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
self::refresh();
|
||||
|
||||
return array_values(self::$runtimeVendors) === array_values($this->vendors);
|
||||
}
|
||||
|
||||
private static function refresh(): void
|
||||
{
|
||||
self::$runtimeVendors = [];
|
||||
|
||||
foreach (get_declared_classes() as $class) {
|
||||
if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) {
|
||||
$r = new \ReflectionClass($class);
|
||||
$v = \dirname($r->getFileName(), 2);
|
||||
if (is_file($v.'/composer/installed.json')) {
|
||||
self::$runtimeVendors[$v] = @filemtime($v.'/composer/installed.json');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
96
plugins/simplesaml/lib/vendor/symfony/config/Resource/DirectoryResource.php
vendored
Normal file
96
plugins/simplesaml/lib/vendor/symfony/config/Resource/DirectoryResource.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* DirectoryResource represents a resources stored in a subdirectory tree.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class DirectoryResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
private string $resource;
|
||||
private ?string $pattern;
|
||||
|
||||
/**
|
||||
* @param string $resource The file path to the resource
|
||||
* @param string|null $pattern A pattern to restrict monitored files
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $resource, ?string $pattern = null)
|
||||
{
|
||||
$resolvedResource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
|
||||
$this->pattern = $pattern;
|
||||
|
||||
if (false === $resolvedResource || !is_dir($resolvedResource)) {
|
||||
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $resource));
|
||||
}
|
||||
|
||||
$this->resource = $resolvedResource;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return hash('xxh128', serialize([$this->resource, $this->pattern]));
|
||||
}
|
||||
|
||||
public function getResource(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function getPattern(): ?string
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
if (!is_dir($this->resource)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($timestamp < filemtime($this->resource)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
|
||||
// if regex filtering is enabled only check matching files
|
||||
if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// always monitor directories for changes, except the .. entries
|
||||
// (otherwise deleted files wouldn't get detected)
|
||||
if ($file->isDir() && str_ends_with($file, '/..')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// for broken links
|
||||
try {
|
||||
$fileMTime = $file->getMTime();
|
||||
} catch (\RuntimeException) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// early return if a file's mtime exceeds the passed timestamp
|
||||
if ($timestamp < $fileMTime) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
53
plugins/simplesaml/lib/vendor/symfony/config/Resource/FileExistenceResource.php
vendored
Normal file
53
plugins/simplesaml/lib/vendor/symfony/config/Resource/FileExistenceResource.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* FileExistenceResource represents a resource stored on the filesystem.
|
||||
* Freshness is only evaluated against resource creation or deletion.
|
||||
*
|
||||
* The resource can be a file or a directory.
|
||||
*
|
||||
* @author Charles-Henri Bruyand <charleshenri.bruyand@gmail.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class FileExistenceResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
private string $resource;
|
||||
|
||||
private bool $exists;
|
||||
|
||||
/**
|
||||
* @param string $resource The file path to the resource
|
||||
*/
|
||||
public function __construct(string $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->exists = file_exists($resource);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'existence.'.$this->resource;
|
||||
}
|
||||
|
||||
public function getResource(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
return file_exists($this->resource) === $this->exists;
|
||||
}
|
||||
}
|
60
plugins/simplesaml/lib/vendor/symfony/config/Resource/FileResource.php
vendored
Normal file
60
plugins/simplesaml/lib/vendor/symfony/config/Resource/FileResource.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* FileResource represents a resource stored on the filesystem.
|
||||
*
|
||||
* The resource can be a file or a directory.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class FileResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
private string $resource;
|
||||
|
||||
/**
|
||||
* @param string $resource The file path to the resource
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $resource)
|
||||
{
|
||||
$resolvedResource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
|
||||
|
||||
if (false === $resolvedResource) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
|
||||
}
|
||||
|
||||
$this->resource = $resolvedResource;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the canonicalized, absolute path to the resource.
|
||||
*/
|
||||
public function getResource(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
return false !== ($filemtime = @filemtime($this->resource)) && $filemtime <= $timestamp;
|
||||
}
|
||||
}
|
249
plugins/simplesaml/lib/vendor/symfony/config/Resource/GlobResource.php
vendored
Normal file
249
plugins/simplesaml/lib/vendor/symfony/config/Resource/GlobResource.php
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Finder\Glob;
|
||||
|
||||
/**
|
||||
* GlobResource represents a set of resources stored on the filesystem.
|
||||
*
|
||||
* Only existence/removal is tracked (not mtimes.)
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @final
|
||||
*
|
||||
* @implements \IteratorAggregate<string, \SplFileInfo>
|
||||
*/
|
||||
class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
|
||||
{
|
||||
private string $prefix;
|
||||
private string $pattern;
|
||||
private bool $recursive;
|
||||
private string $hash;
|
||||
private bool $forExclusion;
|
||||
private array $excludedPrefixes;
|
||||
private int $globBrace;
|
||||
|
||||
/**
|
||||
* @param string $prefix A directory prefix
|
||||
* @param string $pattern A glob pattern
|
||||
* @param bool $recursive Whether directories should be scanned recursively or not
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $prefix, string $pattern, bool $recursive, bool $forExclusion = false, array $excludedPrefixes = [])
|
||||
{
|
||||
ksort($excludedPrefixes);
|
||||
$resolvedPrefix = realpath($prefix) ?: (file_exists($prefix) ? $prefix : false);
|
||||
$this->pattern = $pattern;
|
||||
$this->recursive = $recursive;
|
||||
$this->forExclusion = $forExclusion;
|
||||
$this->excludedPrefixes = $excludedPrefixes;
|
||||
$this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
|
||||
|
||||
if (false === $resolvedPrefix) {
|
||||
throw new \InvalidArgumentException(sprintf('The path "%s" does not exist.', $prefix));
|
||||
}
|
||||
|
||||
$this->prefix = $resolvedPrefix;
|
||||
}
|
||||
|
||||
public function getPrefix(): string
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'glob.'.$this->prefix.(int) $this->recursive.$this->pattern.(int) $this->forExclusion.implode("\0", $this->excludedPrefixes);
|
||||
}
|
||||
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
$hash = $this->computeHash();
|
||||
$this->hash ??= $hash;
|
||||
|
||||
return $this->hash === $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
$this->hash ??= $this->computeHash();
|
||||
|
||||
return ['prefix', 'pattern', 'recursive', 'hash', 'forExclusion', 'excludedPrefixes'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup(): void
|
||||
{
|
||||
$this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
|
||||
}
|
||||
|
||||
public function getIterator(): \Traversable
|
||||
{
|
||||
if ((!$this->recursive && '' === $this->pattern) || !file_exists($this->prefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_file($prefix = str_replace('\\', '/', $this->prefix))) {
|
||||
$prefix = \dirname($prefix);
|
||||
$pattern = basename($prefix).$this->pattern;
|
||||
} else {
|
||||
$pattern = $this->pattern;
|
||||
}
|
||||
|
||||
if (class_exists(Finder::class)) {
|
||||
$regex = Glob::toRegex($pattern);
|
||||
if ($this->recursive) {
|
||||
$regex = substr_replace($regex, '(/|$)', -2, 1);
|
||||
}
|
||||
} else {
|
||||
$regex = null;
|
||||
}
|
||||
|
||||
$prefixLen = \strlen($prefix);
|
||||
$paths = null;
|
||||
|
||||
if ('' === $this->pattern && is_file($this->prefix)) {
|
||||
$paths = [$this->prefix => null];
|
||||
} elseif (!str_starts_with($this->prefix, 'phar://') && (null !== $regex || !str_contains($this->pattern, '/**/'))) {
|
||||
if (!str_contains($this->pattern, '/**/') && ($this->globBrace || !str_contains($this->pattern, '{'))) {
|
||||
$paths = array_fill_keys(glob($this->prefix.$this->pattern, \GLOB_NOSORT | $this->globBrace), null);
|
||||
} elseif (!str_contains($this->pattern, '\\') || !preg_match('/\\\\[,{}]/', $this->pattern)) {
|
||||
$paths = [];
|
||||
foreach ($this->expandGlob($this->pattern) as $p) {
|
||||
if (false !== $i = strpos($p, '/**/')) {
|
||||
$p = substr_replace($p, '/*', $i);
|
||||
}
|
||||
$paths += array_fill_keys(glob($this->prefix.$p, \GLOB_NOSORT), false !== $i ? $regex : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $paths) {
|
||||
uksort($paths, 'strnatcmp');
|
||||
foreach ($paths as $path => $regex) {
|
||||
if ($this->excludedPrefixes) {
|
||||
$normalizedPath = str_replace('\\', '/', $path);
|
||||
do {
|
||||
if (isset($this->excludedPrefixes[$dirPath = $normalizedPath])) {
|
||||
continue 2;
|
||||
}
|
||||
} while ($prefix !== $dirPath && $dirPath !== $normalizedPath = \dirname($dirPath));
|
||||
}
|
||||
|
||||
if ((null === $regex || preg_match($regex, substr(str_replace('\\', '/', $path), $prefixLen))) && is_file($path)) {
|
||||
yield $path => new \SplFileInfo($path);
|
||||
}
|
||||
if (!is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->forExclusion && (null === $regex || preg_match($regex, substr(str_replace('\\', '/', $path), $prefixLen)))) {
|
||||
yield $path => new \SplFileInfo($path);
|
||||
continue;
|
||||
}
|
||||
if (!($this->recursive || null !== $regex) || isset($this->excludedPrefixes[str_replace('\\', '/', $path)])) {
|
||||
continue;
|
||||
}
|
||||
$files = iterator_to_array(new \RecursiveIteratorIterator(
|
||||
new \RecursiveCallbackFilterIterator(
|
||||
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
|
||||
fn (\SplFileInfo $file, $path) => !isset($this->excludedPrefixes[$path = str_replace('\\', '/', $path)])
|
||||
&& (null === $regex || preg_match($regex, substr($path, $prefixLen)) || $file->isDir())
|
||||
&& '.' !== $file->getBasename()[0]
|
||||
),
|
||||
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||
));
|
||||
uksort($files, 'strnatcmp');
|
||||
|
||||
foreach ($files as $path => $info) {
|
||||
if ($info->isFile()) {
|
||||
yield $path => $info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!class_exists(Finder::class)) {
|
||||
throw new \LogicException('Extended glob patterns cannot be used as the Finder component is not installed. Try running "composer require symfony/finder".');
|
||||
}
|
||||
|
||||
yield from (new Finder())
|
||||
->followLinks()
|
||||
->filter(function (\SplFileInfo $info) use ($regex, $prefixLen, $prefix) {
|
||||
$normalizedPath = str_replace('\\', '/', $info->getPathname());
|
||||
if (!preg_match($regex, substr($normalizedPath, $prefixLen)) || !$info->isFile()) {
|
||||
return false;
|
||||
}
|
||||
if ($this->excludedPrefixes) {
|
||||
do {
|
||||
if (isset($this->excludedPrefixes[$dirPath = $normalizedPath])) {
|
||||
return false;
|
||||
}
|
||||
} while ($prefix !== $dirPath && $dirPath !== $normalizedPath = \dirname($dirPath));
|
||||
}
|
||||
})
|
||||
->sortByName()
|
||||
->in($prefix)
|
||||
;
|
||||
}
|
||||
|
||||
private function computeHash(): string
|
||||
{
|
||||
$hash = hash_init('xxh128');
|
||||
|
||||
foreach ($this->getIterator() as $path => $info) {
|
||||
hash_update($hash, $path."\n");
|
||||
}
|
||||
|
||||
return hash_final($hash);
|
||||
}
|
||||
|
||||
private function expandGlob(string $pattern): array
|
||||
{
|
||||
$segments = preg_split('/\{([^{}]*+)\}/', $pattern, -1, \PREG_SPLIT_DELIM_CAPTURE);
|
||||
$paths = [$segments[0]];
|
||||
$patterns = [];
|
||||
|
||||
for ($i = 1; $i < \count($segments); $i += 2) {
|
||||
$patterns = [];
|
||||
|
||||
foreach (explode(',', $segments[$i]) as $s) {
|
||||
foreach ($paths as $p) {
|
||||
$patterns[] = $p.$s.$segments[1 + $i];
|
||||
}
|
||||
}
|
||||
|
||||
$paths = $patterns;
|
||||
}
|
||||
|
||||
$j = 0;
|
||||
foreach ($patterns as $i => $p) {
|
||||
if (str_contains($p, '{')) {
|
||||
$p = $this->expandGlob($p);
|
||||
array_splice($paths, $i + $j, 1, $p);
|
||||
$j += \count($p) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
}
|
206
plugins/simplesaml/lib/vendor/symfony/config/Resource/ReflectionClassResource.php
vendored
Normal file
206
plugins/simplesaml/lib/vendor/symfony/config/Resource/ReflectionClassResource.php
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
|
||||
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class ReflectionClassResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
private array $files = [];
|
||||
private string $className;
|
||||
private \ReflectionClass $classReflector;
|
||||
private array $excludedVendors = [];
|
||||
private string $hash;
|
||||
|
||||
public function __construct(\ReflectionClass $classReflector, array $excludedVendors = [])
|
||||
{
|
||||
$this->className = $classReflector->name;
|
||||
$this->classReflector = $classReflector;
|
||||
$this->excludedVendors = $excludedVendors;
|
||||
}
|
||||
|
||||
public function isFresh(int $timestamp): bool
|
||||
{
|
||||
if (!isset($this->hash)) {
|
||||
$this->hash = $this->computeHash();
|
||||
$this->loadFiles($this->classReflector);
|
||||
}
|
||||
|
||||
foreach ($this->files as $file => $v) {
|
||||
if (false === $filemtime = @filemtime($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($filemtime > $timestamp) {
|
||||
return $this->hash === $this->computeHash();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'reflection.'.$this->className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
if (!isset($this->hash)) {
|
||||
$this->hash = $this->computeHash();
|
||||
$this->loadFiles($this->classReflector);
|
||||
}
|
||||
|
||||
return ['files', 'className', 'hash'];
|
||||
}
|
||||
|
||||
private function loadFiles(\ReflectionClass $class): void
|
||||
{
|
||||
foreach ($class->getInterfaces() as $v) {
|
||||
$this->loadFiles($v);
|
||||
}
|
||||
do {
|
||||
$file = $class->getFileName();
|
||||
if (false !== $file && is_file($file)) {
|
||||
foreach ($this->excludedVendors as $vendor) {
|
||||
if (str_starts_with($file, $vendor) && false !== strpbrk(substr($file, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) {
|
||||
$file = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($file) {
|
||||
$this->files[$file] = null;
|
||||
}
|
||||
}
|
||||
foreach ($class->getTraits() as $v) {
|
||||
$this->loadFiles($v);
|
||||
}
|
||||
} while ($class = $class->getParentClass());
|
||||
}
|
||||
|
||||
private function computeHash(): string
|
||||
{
|
||||
try {
|
||||
$this->classReflector ??= new \ReflectionClass($this->className);
|
||||
} catch (\ReflectionException) {
|
||||
// the class does not exist anymore
|
||||
return false;
|
||||
}
|
||||
$hash = hash_init('xxh128');
|
||||
|
||||
foreach ($this->generateSignature($this->classReflector) as $info) {
|
||||
hash_update($hash, $info);
|
||||
}
|
||||
|
||||
return hash_final($hash);
|
||||
}
|
||||
|
||||
private function generateSignature(\ReflectionClass $class): iterable
|
||||
{
|
||||
$attributes = [];
|
||||
foreach ($class->getAttributes() as $a) {
|
||||
$attributes[] = [$a->getName(), (string) $a];
|
||||
}
|
||||
yield print_r($attributes, true);
|
||||
$attributes = [];
|
||||
|
||||
yield $class->getDocComment();
|
||||
yield (int) $class->isFinal();
|
||||
yield (int) $class->isAbstract();
|
||||
|
||||
if ($class->isTrait()) {
|
||||
yield print_r(class_uses($class->name), true);
|
||||
} else {
|
||||
yield print_r(class_parents($class->name), true);
|
||||
yield print_r(class_implements($class->name), true);
|
||||
yield print_r($class->getConstants(), true);
|
||||
}
|
||||
|
||||
if (!$class->isInterface()) {
|
||||
$defaults = $class->getDefaultProperties();
|
||||
|
||||
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) {
|
||||
foreach ($p->getAttributes() as $a) {
|
||||
$attributes[] = [$a->getName(), (string) $a];
|
||||
}
|
||||
yield print_r($attributes, true);
|
||||
$attributes = [];
|
||||
|
||||
yield $p->getDocComment();
|
||||
yield $p->isDefault() ? '<default>' : '';
|
||||
yield $p->isPublic() ? 'public' : 'protected';
|
||||
yield $p->isStatic() ? 'static' : '';
|
||||
yield '$'.$p->name;
|
||||
yield print_r(isset($defaults[$p->name]) && !\is_object($defaults[$p->name]) ? $defaults[$p->name] : null, true);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) {
|
||||
foreach ($m->getAttributes() as $a) {
|
||||
$attributes[] = [$a->getName(), (string) $a];
|
||||
}
|
||||
yield print_r($attributes, true);
|
||||
$attributes = [];
|
||||
|
||||
$defaults = [];
|
||||
foreach ($m->getParameters() as $p) {
|
||||
foreach ($p->getAttributes() as $a) {
|
||||
$attributes[] = [$a->getName(), (string) $a];
|
||||
}
|
||||
yield print_r($attributes, true);
|
||||
$attributes = [];
|
||||
|
||||
if (!$p->isDefaultValueAvailable()) {
|
||||
$defaults[$p->name] = null;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$defaults[$p->name] = (string) $p;
|
||||
}
|
||||
|
||||
yield preg_replace('/^ @@.*/m', '', $m);
|
||||
yield print_r($defaults, true);
|
||||
}
|
||||
|
||||
if ($class->isAbstract() || $class->isInterface() || $class->isTrait()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (interface_exists(EventSubscriberInterface::class, false) && $class->isSubclassOf(EventSubscriberInterface::class)) {
|
||||
yield EventSubscriberInterface::class;
|
||||
yield print_r($class->name::getSubscribedEvents(), true);
|
||||
}
|
||||
|
||||
if (interface_exists(MessageSubscriberInterface::class, false) && $class->isSubclassOf(MessageSubscriberInterface::class)) {
|
||||
yield MessageSubscriberInterface::class;
|
||||
foreach ($class->name::getHandledMessages() as $key => $value) {
|
||||
yield $key.print_r($value, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) {
|
||||
yield ServiceSubscriberInterface::class;
|
||||
yield print_r($class->name::getSubscribedServices(), true);
|
||||
}
|
||||
}
|
||||
}
|
31
plugins/simplesaml/lib/vendor/symfony/config/Resource/ResourceInterface.php
vendored
Normal file
31
plugins/simplesaml/lib/vendor/symfony/config/Resource/ResourceInterface.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* ResourceInterface is the interface that must be implemented by all Resource classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface ResourceInterface extends \Stringable
|
||||
{
|
||||
/**
|
||||
* Returns a string representation of the Resource.
|
||||
*
|
||||
* This method is necessary to allow for resource de-duplication, for example by means
|
||||
* of array_unique(). The string returned need not have a particular meaning, but has
|
||||
* to be identical for different ResourceInterface instances referring to the same
|
||||
* resource; and it should be unlikely to collide with that of other, unrelated
|
||||
* resource instances.
|
||||
*/
|
||||
public function __toString(): string;
|
||||
}
|
46
plugins/simplesaml/lib/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php
vendored
Normal file
46
plugins/simplesaml/lib/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
use Symfony\Component\Config\ResourceCheckerInterface;
|
||||
|
||||
/**
|
||||
* Resource checker for instances of SelfCheckingResourceInterface.
|
||||
*
|
||||
* As these resources perform the actual check themselves, we can provide
|
||||
* this class as a standard way of validating them.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
class SelfCheckingResourceChecker implements ResourceCheckerInterface
|
||||
{
|
||||
// Common shared cache, because this checker can be used in different
|
||||
// situations. For example, when using the full stack framework, the router
|
||||
// and the container have their own cache. But they may check the very same
|
||||
// resources
|
||||
private static array $cache = [];
|
||||
|
||||
public function supports(ResourceInterface $metadata): bool
|
||||
{
|
||||
return $metadata instanceof SelfCheckingResourceInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SelfCheckingResourceInterface $resource
|
||||
*/
|
||||
public function isFresh(ResourceInterface $resource, int $timestamp): bool
|
||||
{
|
||||
$key = "$resource:$timestamp";
|
||||
|
||||
return self::$cache[$key] ??= $resource->isFresh($timestamp);
|
||||
}
|
||||
}
|
28
plugins/simplesaml/lib/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php
vendored
Normal file
28
plugins/simplesaml/lib/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
/**
|
||||
* Interface for Resources that can check for freshness autonomously,
|
||||
* without special support from external services.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
interface SelfCheckingResourceInterface extends ResourceInterface
|
||||
{
|
||||
/**
|
||||
* Returns true if the resource has not been updated since the given timestamp.
|
||||
*
|
||||
* @param int $timestamp The last time the resource was loaded
|
||||
*/
|
||||
public function isFresh(int $timestamp): bool;
|
||||
}
|
181
plugins/simplesaml/lib/vendor/symfony/config/ResourceCheckerConfigCache.php
vendored
Normal file
181
plugins/simplesaml/lib/vendor/symfony/config/ResourceCheckerConfigCache.php
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
use Symfony\Component\Filesystem\Exception\IOException;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* ResourceCheckerConfigCache uses instances of ResourceCheckerInterface
|
||||
* to check whether cached data is still fresh.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
class ResourceCheckerConfigCache implements ConfigCacheInterface
|
||||
{
|
||||
private string $file;
|
||||
|
||||
/**
|
||||
* @var iterable<mixed, ResourceCheckerInterface>
|
||||
*/
|
||||
private iterable $resourceCheckers;
|
||||
|
||||
/**
|
||||
* @param string $file The absolute cache path
|
||||
* @param iterable<mixed, ResourceCheckerInterface> $resourceCheckers The ResourceCheckers to use for the freshness check
|
||||
*/
|
||||
public function __construct(string $file, iterable $resourceCheckers = [])
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->resourceCheckers = $resourceCheckers;
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the cache is still fresh.
|
||||
*
|
||||
* This implementation will make a decision solely based on the ResourceCheckers
|
||||
* passed in the constructor.
|
||||
*
|
||||
* The first ResourceChecker that supports a given resource is considered authoritative.
|
||||
* Resources with no matching ResourceChecker will silently be ignored and considered fresh.
|
||||
*/
|
||||
public function isFresh(): bool
|
||||
{
|
||||
if (!is_file($this->file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->resourceCheckers instanceof \Traversable && !$this->resourceCheckers instanceof \Countable) {
|
||||
$this->resourceCheckers = iterator_to_array($this->resourceCheckers);
|
||||
}
|
||||
|
||||
if (!\count($this->resourceCheckers)) {
|
||||
return true; // shortcut - if we don't have any checkers we don't need to bother with the meta file at all
|
||||
}
|
||||
|
||||
$metadata = $this->getMetaFile();
|
||||
|
||||
if (!is_file($metadata)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$meta = $this->safelyUnserialize($metadata);
|
||||
|
||||
if (false === $meta) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$time = filemtime($this->file);
|
||||
|
||||
foreach ($meta as $resource) {
|
||||
foreach ($this->resourceCheckers as $checker) {
|
||||
if (!$checker->supports($resource)) {
|
||||
continue; // next checker
|
||||
}
|
||||
if ($checker->isFresh($resource, $time)) {
|
||||
break; // no need to further check this resource
|
||||
}
|
||||
|
||||
return false; // cache is stale
|
||||
}
|
||||
// no suitable checker found, ignore this resource
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes cache.
|
||||
*
|
||||
* @param string $content The content to write in the cache
|
||||
* @param ResourceInterface[] $metadata An array of metadata
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException When cache file can't be written
|
||||
*/
|
||||
public function write(string $content, ?array $metadata = null)
|
||||
{
|
||||
$mode = 0666;
|
||||
$umask = umask();
|
||||
$filesystem = new Filesystem();
|
||||
$filesystem->dumpFile($this->file, $content);
|
||||
try {
|
||||
$filesystem->chmod($this->file, $mode, $umask);
|
||||
} catch (IOException) {
|
||||
// discard chmod failure (some filesystem may not support it)
|
||||
}
|
||||
|
||||
if (null !== $metadata) {
|
||||
$filesystem->dumpFile($this->getMetaFile(), serialize($metadata));
|
||||
try {
|
||||
$filesystem->chmod($this->getMetaFile(), $mode, $umask);
|
||||
} catch (IOException) {
|
||||
// discard chmod failure (some filesystem may not support it)
|
||||
}
|
||||
}
|
||||
|
||||
if (\function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL)) {
|
||||
@opcache_invalidate($this->file, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the meta file path.
|
||||
*/
|
||||
private function getMetaFile(): string
|
||||
{
|
||||
return $this->file.'.meta';
|
||||
}
|
||||
|
||||
private function safelyUnserialize(string $file): mixed
|
||||
{
|
||||
$meta = false;
|
||||
$content = file_get_contents($file);
|
||||
$signalingException = new \UnexpectedValueException();
|
||||
$prevUnserializeHandler = ini_set('unserialize_callback_func', self::class.'::handleUnserializeCallback');
|
||||
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) {
|
||||
if (__FILE__ === $file && !\in_array($type, [\E_DEPRECATED, \E_USER_DEPRECATED], true)) {
|
||||
throw $signalingException;
|
||||
}
|
||||
|
||||
return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
|
||||
});
|
||||
|
||||
try {
|
||||
$meta = unserialize($content);
|
||||
} catch (\Throwable $e) {
|
||||
if ($e !== $signalingException) {
|
||||
throw $e;
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
ini_set('unserialize_callback_func', $prevUnserializeHandler);
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function handleUnserializeCallback(string $class): void
|
||||
{
|
||||
trigger_error('Class not found: '.$class);
|
||||
}
|
||||
}
|
41
plugins/simplesaml/lib/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php
vendored
Normal file
41
plugins/simplesaml/lib/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
/**
|
||||
* A ConfigCacheFactory implementation that validates the
|
||||
* cache with an arbitrary set of ResourceCheckers.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
*/
|
||||
class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryInterface
|
||||
{
|
||||
private iterable $resourceCheckers = [];
|
||||
|
||||
/**
|
||||
* @param iterable<int, ResourceCheckerInterface> $resourceCheckers
|
||||
*/
|
||||
public function __construct(iterable $resourceCheckers = [])
|
||||
{
|
||||
$this->resourceCheckers = $resourceCheckers;
|
||||
}
|
||||
|
||||
public function cache(string $file, callable $callable): ConfigCacheInterface
|
||||
{
|
||||
$cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers);
|
||||
if (!$cache->isFresh()) {
|
||||
$callable($cache);
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
}
|
45
plugins/simplesaml/lib/vendor/symfony/config/ResourceCheckerInterface.php
vendored
Normal file
45
plugins/simplesaml/lib/vendor/symfony/config/ResourceCheckerInterface.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config;
|
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
|
||||
/**
|
||||
* Interface for ResourceCheckers.
|
||||
*
|
||||
* When a ResourceCheckerConfigCache instance is checked for freshness, all its associated
|
||||
* metadata resources are passed to ResourceCheckers. The ResourceCheckers
|
||||
* can then inspect the resources and decide whether the cache can be considered
|
||||
* fresh or not.
|
||||
*
|
||||
* @author Matthias Pigulla <mp@webfactory.de>
|
||||
* @author Benjamin Klotz <bk@webfactory.de>
|
||||
*/
|
||||
interface ResourceCheckerInterface
|
||||
{
|
||||
/**
|
||||
* Queries the ResourceChecker whether it can validate a given
|
||||
* resource or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(ResourceInterface $metadata);
|
||||
|
||||
/**
|
||||
* Validates the resource.
|
||||
*
|
||||
* @param int $timestamp The timestamp at which the cache associated with this resource was created
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFresh(ResourceInterface $resource, int $timestamp);
|
||||
}
|
22
plugins/simplesaml/lib/vendor/symfony/config/Util/Exception/InvalidXmlException.php
vendored
Normal file
22
plugins/simplesaml/lib/vendor/symfony/config/Util/Exception/InvalidXmlException.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Util\Exception;
|
||||
|
||||
/**
|
||||
* Exception class for when XML parsing with an XSD schema file path or a callable validator produces errors unrelated
|
||||
* to the actual XML parsing.
|
||||
*
|
||||
* @author Ole Rößner <ole@roessner.it>
|
||||
*/
|
||||
class InvalidXmlException extends XmlParsingException
|
||||
{
|
||||
}
|
21
plugins/simplesaml/lib/vendor/symfony/config/Util/Exception/XmlParsingException.php
vendored
Normal file
21
plugins/simplesaml/lib/vendor/symfony/config/Util/Exception/XmlParsingException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Util\Exception;
|
||||
|
||||
/**
|
||||
* Exception class for when XML cannot be parsed properly.
|
||||
*
|
||||
* @author Ole Rößner <ole@roessner.it>
|
||||
*/
|
||||
class XmlParsingException extends \InvalidArgumentException
|
||||
{
|
||||
}
|
272
plugins/simplesaml/lib/vendor/symfony/config/Util/XmlUtils.php
vendored
Normal file
272
plugins/simplesaml/lib/vendor/symfony/config/Util/XmlUtils.php
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Config\Util;
|
||||
|
||||
use Symfony\Component\Config\Util\Exception\InvalidXmlException;
|
||||
use Symfony\Component\Config\Util\Exception\XmlParsingException;
|
||||
|
||||
/**
|
||||
* XMLUtils is a bunch of utility methods to XML operations.
|
||||
*
|
||||
* This class contains static methods only and is not meant to be instantiated.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Martin Hasoň <martin.hason@gmail.com>
|
||||
* @author Ole Rößner <ole@roessner.it>
|
||||
*/
|
||||
class XmlUtils
|
||||
{
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an XML string.
|
||||
*
|
||||
* @param string $content An XML string
|
||||
* @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
|
||||
*
|
||||
* @throws XmlParsingException When parsing of XML file returns error
|
||||
* @throws InvalidXmlException When parsing of XML with schema or callable produces any errors unrelated to the XML parsing itself
|
||||
* @throws \RuntimeException When DOM extension is missing
|
||||
*/
|
||||
public static function parse(string $content, string|callable|null $schemaOrCallable = null): \DOMDocument
|
||||
{
|
||||
if (!\extension_loaded('dom')) {
|
||||
throw new \LogicException('Extension DOM is required.');
|
||||
}
|
||||
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
$dom->validateOnParse = true;
|
||||
if (!$dom->loadXML($content, \LIBXML_NONET | \LIBXML_COMPACT)) {
|
||||
throw new XmlParsingException(implode("\n", static::getXmlErrors($internalErrors)));
|
||||
}
|
||||
|
||||
$dom->normalizeDocument();
|
||||
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
foreach ($dom->childNodes as $child) {
|
||||
if (\XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
|
||||
throw new XmlParsingException('Document types are not allowed.');
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $schemaOrCallable) {
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
|
||||
$e = null;
|
||||
if (\is_callable($schemaOrCallable)) {
|
||||
try {
|
||||
$valid = $schemaOrCallable($dom, $internalErrors);
|
||||
} catch (\Exception $e) {
|
||||
$valid = false;
|
||||
}
|
||||
} elseif (is_file($schemaOrCallable)) {
|
||||
$schemaSource = file_get_contents((string) $schemaOrCallable);
|
||||
$valid = @$dom->schemaValidateSource($schemaSource);
|
||||
} else {
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
throw new XmlParsingException(sprintf('Invalid XSD file: "%s".', $schemaOrCallable));
|
||||
}
|
||||
|
||||
if (!$valid) {
|
||||
$messages = static::getXmlErrors($internalErrors);
|
||||
if (!$messages) {
|
||||
throw new InvalidXmlException('The XML is not valid.', 0, $e);
|
||||
}
|
||||
throw new XmlParsingException(implode("\n", $messages), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
return $dom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an XML file.
|
||||
*
|
||||
* @param string $file An XML file path
|
||||
* @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
|
||||
*
|
||||
* @throws \InvalidArgumentException When loading of XML file returns error
|
||||
* @throws XmlParsingException When XML parsing returns any errors
|
||||
* @throws \RuntimeException When DOM extension is missing
|
||||
*/
|
||||
public static function loadFile(string $file, string|callable|null $schemaOrCallable = null): \DOMDocument
|
||||
{
|
||||
if (!is_file($file)) {
|
||||
throw new \InvalidArgumentException(sprintf('Resource "%s" is not a file.', $file));
|
||||
}
|
||||
|
||||
if (!is_readable($file)) {
|
||||
throw new \InvalidArgumentException(sprintf('File "%s" is not readable.', $file));
|
||||
}
|
||||
|
||||
$content = @file_get_contents($file);
|
||||
|
||||
if ('' === trim($content)) {
|
||||
throw new \InvalidArgumentException(sprintf('File "%s" does not contain valid XML, it is empty.', $file));
|
||||
}
|
||||
|
||||
try {
|
||||
return static::parse($content, $schemaOrCallable);
|
||||
} catch (InvalidXmlException $e) {
|
||||
throw new XmlParsingException(sprintf('The XML file "%s" is not valid.', $file), 0, $e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a \DOMElement object to a PHP array.
|
||||
*
|
||||
* The following rules applies during the conversion:
|
||||
*
|
||||
* * Each tag is converted to a key value or an array
|
||||
* if there is more than one "value"
|
||||
*
|
||||
* * The content of a tag is set under a "value" key (<foo>bar</foo>)
|
||||
* if the tag also has some nested tags
|
||||
*
|
||||
* * The attributes are converted to keys (<foo foo="bar"/>)
|
||||
*
|
||||
* * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
|
||||
*
|
||||
* @param \DOMElement $element A \DOMElement instance
|
||||
* @param bool $checkPrefix Check prefix in an element or an attribute name
|
||||
*/
|
||||
public static function convertDomElementToArray(\DOMElement $element, bool $checkPrefix = true): mixed
|
||||
{
|
||||
$prefix = (string) $element->prefix;
|
||||
$empty = true;
|
||||
$config = [];
|
||||
foreach ($element->attributes as $name => $node) {
|
||||
if ($checkPrefix && !\in_array((string) $node->prefix, ['', $prefix], true)) {
|
||||
continue;
|
||||
}
|
||||
$config[$name] = static::phpize($node->value);
|
||||
$empty = false;
|
||||
}
|
||||
|
||||
$nodeValue = false;
|
||||
foreach ($element->childNodes as $node) {
|
||||
if ($node instanceof \DOMText) {
|
||||
if ('' !== trim($node->nodeValue)) {
|
||||
$nodeValue = trim($node->nodeValue);
|
||||
$empty = false;
|
||||
}
|
||||
} elseif ($checkPrefix && $prefix != (string) $node->prefix) {
|
||||
continue;
|
||||
} elseif (!$node instanceof \DOMComment) {
|
||||
$value = static::convertDomElementToArray($node, $checkPrefix);
|
||||
|
||||
$key = $node->localName;
|
||||
if (isset($config[$key])) {
|
||||
if (!\is_array($config[$key]) || !\is_int(key($config[$key]))) {
|
||||
$config[$key] = [$config[$key]];
|
||||
}
|
||||
$config[$key][] = $value;
|
||||
} else {
|
||||
$config[$key] = $value;
|
||||
}
|
||||
|
||||
$empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (false !== $nodeValue) {
|
||||
$value = static::phpize($nodeValue);
|
||||
if (\count($config)) {
|
||||
$config['value'] = $value;
|
||||
} else {
|
||||
$config = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return !$empty ? $config : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an xml value to a PHP type.
|
||||
*/
|
||||
public static function phpize(string|\Stringable $value): mixed
|
||||
{
|
||||
$value = (string) $value;
|
||||
$lowercaseValue = strtolower($value);
|
||||
|
||||
switch (true) {
|
||||
case 'null' === $lowercaseValue:
|
||||
return null;
|
||||
case ctype_digit($value):
|
||||
case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)):
|
||||
$raw = $value;
|
||||
$cast = (int) $value;
|
||||
|
||||
return self::isOctal($value) ? \intval($value, 8) : (($raw === (string) $cast) ? $cast : $raw);
|
||||
case 'true' === $lowercaseValue:
|
||||
return true;
|
||||
case 'false' === $lowercaseValue:
|
||||
return false;
|
||||
case isset($value[1]) && '0b' == $value[0].$value[1] && preg_match('/^0b[01]*$/', $value):
|
||||
return bindec($value);
|
||||
case is_numeric($value):
|
||||
return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value;
|
||||
case preg_match('/^0x[0-9a-f]++$/i', $value):
|
||||
return hexdec($value);
|
||||
case preg_match('/^[+-]?[0-9]+(\.[0-9]+)?$/', $value):
|
||||
return (float) $value;
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected static function getXmlErrors(bool $internalErrors)
|
||||
{
|
||||
$errors = [];
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
|
||||
\LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
||||
$error->code,
|
||||
trim($error->message),
|
||||
$error->file ?: 'n/a',
|
||||
$error->line,
|
||||
$error->column
|
||||
);
|
||||
}
|
||||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function isOctal(string $str): bool
|
||||
{
|
||||
if ('-' === $str[0]) {
|
||||
$str = substr($str, 1);
|
||||
}
|
||||
|
||||
return $str === '0'.decoct(\intval($str, 8));
|
||||
}
|
||||
}
|
42
plugins/simplesaml/lib/vendor/symfony/config/composer.json
vendored
Normal file
42
plugins/simplesaml/lib/vendor/symfony/config/composer.json
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"type": "library",
|
||||
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||
"keywords": [],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/filesystem": "^5.4|^6.0|^7.0",
|
||||
"symfony/polyfill-ctype": "~1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/event-dispatcher": "^5.4|^6.0|^7.0",
|
||||
"symfony/finder": "^5.4|^6.0|^7.0",
|
||||
"symfony/messenger": "^5.4|^6.0|^7.0",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/yaml": "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/finder": "<5.4",
|
||||
"symfony/service-contracts": "<2.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Config\\": "" },
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
Reference in New Issue
Block a user