mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-18 23:08:46 +02:00
N°8834 - Add compatibility with PHP 8.4 (#819)
* N°8834 - Add compatibility with PHP 8.4 * Rollback of scssphp/scssphp version upgrade due to compilation error
This commit is contained in:
@@ -63,11 +63,11 @@ class ClassBuilder
|
||||
}
|
||||
unset($path[$key]);
|
||||
}
|
||||
$require .= sprintf('require_once __DIR__.\DIRECTORY_SEPARATOR.\'%s\';', implode('\'.\DIRECTORY_SEPARATOR.\'', $path))."\n";
|
||||
$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";
|
||||
$use .= \sprintf('use %s;', $statement)."\n";
|
||||
}
|
||||
|
||||
$implements = [] === $this->implements ? '' : 'implements '.implode(', ', $this->implements);
|
||||
@@ -119,15 +119,15 @@ BODY
|
||||
$this->methods[] = new Method(strtr($body, ['NAME' => $this->camelCase($name)] + $params));
|
||||
}
|
||||
|
||||
public function addProperty(string $name, string $classType = null, string $defaultValue = null): Property
|
||||
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));
|
||||
$defaultValue = null !== $defaultValue ? \sprintf(' = %s', $defaultValue) : '';
|
||||
$property->setContent(\sprintf('private $%s%s;', $property->getName(), $defaultValue));
|
||||
|
||||
return $property;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ public function NAME(): string
|
||||
$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)),
|
||||
default => throw new \RuntimeException(\sprintf('Unknown node "%s".', $child::class)),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -127,12 +127,15 @@ public function NAME(): string
|
||||
$class->addRequire($childClass);
|
||||
$this->classes[] = $childClass;
|
||||
|
||||
$nodeTypes = $this->getParameterTypes($node);
|
||||
$paramType = $this->getParamType($nodeTypes);
|
||||
|
||||
$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 ($hasNormalizationClosures && 'array' !== $paramType) {
|
||||
$comment = \sprintf(" * @template TValue of %s\n * @param TValue \$value\n%s", $paramType, $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";
|
||||
@@ -142,8 +145,7 @@ public function NAME(): string
|
||||
$node->getName(),
|
||||
$this->getType($childClass->getFqcn(), $hasNormalizationClosures)
|
||||
);
|
||||
$nodeTypes = $this->getParameterTypes($node);
|
||||
$body = $hasNormalizationClosures ? '
|
||||
$body = $hasNormalizationClosures && 'array' !== $paramType ? '
|
||||
COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
|
||||
{
|
||||
if (!\is_array($value)) {
|
||||
@@ -178,7 +180,7 @@ COMMENTpublic function NAME(array $value = []): CLASS
|
||||
'COMMENT' => $comment,
|
||||
'PROPERTY' => $property->getName(),
|
||||
'CLASS' => $childClass->getFqcn(),
|
||||
'PARAM_TYPE' => \in_array('mixed', $nodeTypes, true) ? 'mixed' : implode('|', $nodeTypes),
|
||||
'PARAM_TYPE' => $paramType,
|
||||
]);
|
||||
|
||||
$this->buildNode($node, $childClass, $this->getSubNamespace($childClass));
|
||||
@@ -218,10 +220,11 @@ public function NAME(mixed $valueDEFAULT): static
|
||||
|
||||
$nodeParameterTypes = $this->getParameterTypes($node);
|
||||
$prototypeParameterTypes = $this->getParameterTypes($prototype);
|
||||
$noKey = null === $key = $node->getKeyAttribute();
|
||||
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()) {
|
||||
if ($noKey) {
|
||||
// This is an array of values; don't use singular name
|
||||
$nodeTypesWithoutArray = array_filter($nodeParameterTypes, static fn ($type) => 'array' !== $type);
|
||||
$body = '
|
||||
@@ -242,7 +245,7 @@ public function NAME(PARAM_TYPE $value): static
|
||||
'PROPERTY' => $property->getName(),
|
||||
'PROTOTYPE_TYPE' => implode('|', $prototypeParameterTypes),
|
||||
'EXTRA_TYPE' => $nodeTypesWithoutArray ? '|'.implode('|', $nodeTypesWithoutArray) : '',
|
||||
'PARAM_TYPE' => \in_array('mixed', $nodeParameterTypes, true) ? 'mixed' : 'ParamConfigurator|'.implode('|', $nodeParameterTypes),
|
||||
'PARAM_TYPE' => $this->getParamType($nodeParameterTypes, true),
|
||||
]);
|
||||
} else {
|
||||
$body = '
|
||||
@@ -259,7 +262,7 @@ public function NAME(string $VAR, TYPE $VALUE): static
|
||||
|
||||
$class->addMethod($methodName, $body, [
|
||||
'PROPERTY' => $property->getName(),
|
||||
'TYPE' => \in_array('mixed', $prototypeParameterTypes, true) ? 'mixed' : 'ParamConfigurator|'.implode('|', $prototypeParameterTypes),
|
||||
'TYPE' => $this->getParamType($prototypeParameterTypes, true),
|
||||
'VAR' => '' === $key ? 'key' : $key,
|
||||
'VALUE' => 'value' === $key ? 'data' : 'value',
|
||||
]);
|
||||
@@ -280,18 +283,20 @@ public function NAME(string $VAR, TYPE $VALUE): static
|
||||
$this->getType($childClass->getFqcn().'[]', $hasNormalizationClosures)
|
||||
);
|
||||
|
||||
$paramType = $this->getParamType($noKey ? $nodeParameterTypes : $prototypeParameterTypes);
|
||||
|
||||
$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 ($hasNormalizationClosures && 'array' !== $paramType) {
|
||||
$comment = \sprintf(" * @template TValue of %s\n * @param TValue \$value\n%s", $paramType, $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 ? '
|
||||
if ($noKey) {
|
||||
$body = $hasNormalizationClosures && 'array' !== $paramType ? '
|
||||
COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
|
||||
{
|
||||
$this->_usedProperties[\'PROPERTY\'] = true;
|
||||
@@ -313,10 +318,10 @@ COMMENTpublic function NAME(array $value = []): CLASS
|
||||
'COMMENT' => $comment,
|
||||
'PROPERTY' => $property->getName(),
|
||||
'CLASS' => $childClass->getFqcn(),
|
||||
'PARAM_TYPE' => \in_array('mixed', $nodeParameterTypes, true) ? 'mixed' : implode('|', $nodeParameterTypes),
|
||||
'PARAM_TYPE' => $paramType,
|
||||
]);
|
||||
} else {
|
||||
$body = $hasNormalizationClosures ? '
|
||||
$body = $hasNormalizationClosures && 'array' !== $paramType ? '
|
||||
COMMENTpublic function NAME(string $VAR, PARAM_TYPE $VALUE = []): CLASS|static
|
||||
{
|
||||
if (!\is_array($VALUE)) {
|
||||
@@ -352,7 +357,7 @@ COMMENTpublic function NAME(string $VAR, array $VALUE = []): CLASS
|
||||
'CLASS' => $childClass->getFqcn(),
|
||||
'VAR' => '' === $key ? 'key' : $key,
|
||||
'VALUE' => 'value' === $key ? 'data' : 'value',
|
||||
'PARAM_TYPE' => \in_array('mixed', $prototypeParameterTypes, true) ? 'mixed' : implode('|', $prototypeParameterTypes),
|
||||
'PARAM_TYPE' => $paramType,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -413,39 +418,39 @@ public function NAME($value): static
|
||||
{
|
||||
$comment = '';
|
||||
if ('' !== $info = (string) $node->getInfo()) {
|
||||
$comment .= ' * '.$info."\n";
|
||||
$comment .= $info."\n";
|
||||
}
|
||||
|
||||
if (!$node instanceof ArrayNode) {
|
||||
foreach ((array) ($node->getExample() ?? []) as $example) {
|
||||
$comment .= ' * @example '.$example."\n";
|
||||
$comment .= '@example '.$example."\n";
|
||||
}
|
||||
|
||||
if ('' !== $default = $node->getDefaultValue()) {
|
||||
$comment .= ' * @default '.(null === $default ? 'null' : var_export($default, true))."\n";
|
||||
$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";
|
||||
$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";
|
||||
$comment .= '@param ParamConfigurator|'.implode('|', $parameterTypes).' $value'."\n";
|
||||
}
|
||||
} else {
|
||||
foreach ((array) ($node->getExample() ?? []) as $example) {
|
||||
$comment .= ' * @example '.json_encode($example)."\n";
|
||||
$comment .= '@example '.json_encode($example)."\n";
|
||||
}
|
||||
|
||||
if ($node->hasDefaultValue() && [] != $default = $node->getDefaultValue()) {
|
||||
$comment .= ' * @default '.json_encode($default)."\n";
|
||||
$comment .= '@default '.json_encode($default)."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($node->isDeprecated()) {
|
||||
$comment .= ' * @deprecated '.$node->getDeprecation($node->getName(), $node->getParent()->getName())['message']."\n";
|
||||
$comment .= '@deprecated '.$node->getDeprecation($node->getName(), $node->getParent()->getName())['message']."\n";
|
||||
}
|
||||
|
||||
return $comment;
|
||||
return $comment ? ' * '.str_replace("\n", "\n * ", rtrim($comment, "\n"))."\n" : '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -579,7 +584,7 @@ public function NAME(string $key, mixed $value): static
|
||||
|
||||
private function getSubNamespace(ClassBuilder $rootClass): string
|
||||
{
|
||||
return sprintf('%s\\%s', $rootClass->getNamespace(), substr($rootClass->getName(), 0, -6));
|
||||
return \sprintf('%s\\%s', $rootClass->getNamespace(), substr($rootClass->getName(), 0, -6));
|
||||
}
|
||||
|
||||
private function hasNormalizationClosures(NodeInterface $node): bool
|
||||
@@ -597,4 +602,9 @@ public function NAME(string $key, mixed $value): static
|
||||
{
|
||||
return $classType.($hasNormalizationClosures ? '|scalar' : '');
|
||||
}
|
||||
|
||||
private function getParamType(array $types, bool $withParamConfigurator = false): string
|
||||
{
|
||||
return \in_array('mixed', $types, true) ? 'mixed' : ($withParamConfigurator ? 'ParamConfigurator|' : '').implode('|', $types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,5 +43,5 @@ interface ConfigCacheInterface
|
||||
*
|
||||
* @throws \RuntimeException When the cache file cannot be written
|
||||
*/
|
||||
public function write(string $content, array $metadata = null);
|
||||
public function write(string $content, ?array $metadata = null);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
public function getDefaultValue(): mixed
|
||||
{
|
||||
if (!$this->hasDefaultValue()) {
|
||||
throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
|
||||
throw new \RuntimeException(\sprintf('The node at path "%s" has no default value.', $this->getPath()));
|
||||
}
|
||||
|
||||
$defaults = [];
|
||||
@@ -205,7 +205,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
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));
|
||||
throw new \InvalidArgumentException(\sprintf('A child node named "%s" already exists.', $name));
|
||||
}
|
||||
|
||||
$this->children[$name] = $node;
|
||||
@@ -218,15 +218,15 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
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)));
|
||||
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());
|
||||
$message = \sprintf('The child config "%s" under "%s" must be configured', $name, $this->getPath());
|
||||
if ($child->getInfo()) {
|
||||
$message .= sprintf(': %s', $child->getInfo());
|
||||
$message .= \sprintf(': %s', $child->getInfo());
|
||||
} else {
|
||||
$message .= '.';
|
||||
}
|
||||
@@ -264,7 +264,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
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)));
|
||||
$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);
|
||||
}
|
||||
@@ -315,13 +315,13 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
}
|
||||
}
|
||||
|
||||
$msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === \count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());
|
||||
$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)));
|
||||
$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));
|
||||
$msg .= \sprintf('. Available option%s %s "%s".', 1 === \count($proposals) ? '' : 's', 1 === \count($proposals) ? 'is' : 'are', implode('", "', $proposals));
|
||||
}
|
||||
|
||||
$ex = new InvalidConfigurationException($msg);
|
||||
@@ -370,7 +370,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||
// 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 = 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;
|
||||
|
||||
@@ -46,7 +46,7 @@ abstract class BaseNode implements NodeInterface
|
||||
/**
|
||||
* @throws \InvalidArgumentException if the name contains a period
|
||||
*/
|
||||
public function __construct(?string $name, NodeInterface $parent = null, string $pathSeparator = self::DEFAULT_PATH_SEPARATOR)
|
||||
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.'".');
|
||||
@@ -313,7 +313,7 @@ abstract class BaseNode implements NodeInterface
|
||||
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()));
|
||||
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)) {
|
||||
@@ -432,7 +432,7 @@ abstract class BaseNode implements NodeInterface
|
||||
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": ', $this->getPath()).$e->getMessage(), $e->getCode(), $e);
|
||||
throw new InvalidConfigurationException(\sprintf('Invalid configuration for path "%s": ', $this->getPath()).$e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ abstract class BaseNode implements NodeInterface
|
||||
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 = 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;
|
||||
@@ -523,7 +523,7 @@ abstract class BaseNode implements NodeInterface
|
||||
$validTypes = $this->getValidPlaceholderTypes();
|
||||
|
||||
if ($validTypes && array_diff($knownTypes, $validTypes)) {
|
||||
$e = new InvalidTypeException(sprintf(
|
||||
$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).'"',
|
||||
|
||||
@@ -26,7 +26,7 @@ class BooleanNode extends ScalarNode
|
||||
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)));
|
||||
$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);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
protected $nodeBuilder;
|
||||
protected $normalizeKeys = true;
|
||||
|
||||
public function __construct(?string $name, NodeParentInterface $parent = null)
|
||||
public function __construct(?string $name, ?NodeParentInterface $parent = null)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
@@ -126,7 +126,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDefaultChildrenIfNoneSet(int|string|array $children = null): static
|
||||
public function addDefaultChildrenIfNoneSet(int|string|array|null $children = null): static
|
||||
{
|
||||
$this->addDefaultChildren = $children;
|
||||
|
||||
@@ -169,7 +169,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fixXmlConfig(string $singular, string $plural = null): static
|
||||
public function fixXmlConfig(string $singular, ?string $plural = null): static
|
||||
{
|
||||
$this->normalization()->remap($singular, $plural);
|
||||
|
||||
@@ -331,7 +331,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
|
||||
public function append(NodeDefinition $node): static
|
||||
{
|
||||
$this->children[$node->name] = $node->setParent($this);
|
||||
$this->children[$node->name ?? ''] = $node->setParent($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -374,7 +374,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
|
||||
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()));
|
||||
throw new \InvalidArgumentException(\sprintf('%s: the default value of an array node has to be an array.', $node->getPath()));
|
||||
}
|
||||
|
||||
$node->setDefaultValue($this->defaultValue);
|
||||
@@ -434,23 +434,23 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
$path = $node->getPath();
|
||||
|
||||
if (null !== $this->key) {
|
||||
throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s".', $path));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
throw new InvalidDefinitionException(\sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s".', $path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,20 +466,20 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
$path = $node->getPath();
|
||||
|
||||
if ($this->addDefaults) {
|
||||
throw new InvalidDefinitionException(sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s".', $path));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
throw new InvalidDefinitionException(\sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s".', $path));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,7 +504,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||
: 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));
|
||||
throw new \RuntimeException(\sprintf('Node with name "%s" does not exist in the current node "%s".', $firstPathSegment, $this->name));
|
||||
}
|
||||
|
||||
if (false === $pathSeparatorPos) {
|
||||
|
||||
@@ -21,7 +21,7 @@ use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||
*/
|
||||
class BooleanNodeDefinition extends ScalarNodeDefinition
|
||||
{
|
||||
public function __construct(?string $name, NodeParentInterface $parent = null)
|
||||
public function __construct(?string $name, ?NodeParentInterface $parent = null)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class ExprBuilder
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function always(\Closure $then = null): static
|
||||
public function always(?\Closure $then = null): static
|
||||
{
|
||||
$this->ifPart = static fn () => true;
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
@@ -61,7 +61,7 @@ class ExprBuilder
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ifTrue(\Closure $closure = null): static
|
||||
public function ifTrue(?\Closure $closure = null): static
|
||||
{
|
||||
$this->ifPart = $closure ?? static fn ($v) => true === $v;
|
||||
$this->allowedTypes = self::TYPE_ANY;
|
||||
@@ -196,7 +196,7 @@ class ExprBuilder
|
||||
*/
|
||||
public function thenInvalid(string $message): static
|
||||
{
|
||||
$this->thenPart = static fn ($v) => throw new \InvalidArgumentException(sprintf($message, json_encode($v)));
|
||||
$this->thenPart = static fn ($v) => throw new \InvalidArgumentException(\sprintf($message, json_encode($v)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class NodeBuilder implements NodeParentInterface
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent(ParentNodeDefinitionInterface $parent = null): static
|
||||
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__);
|
||||
@@ -190,13 +190,13 @@ class NodeBuilder implements NodeParentInterface
|
||||
$type = strtolower($type);
|
||||
|
||||
if (!isset($this->nodeMapping[$type])) {
|
||||
throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $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));
|
||||
throw new \RuntimeException(\sprintf('The node class "%s" does not exist.', $class));
|
||||
}
|
||||
|
||||
return $class;
|
||||
|
||||
@@ -38,7 +38,7 @@ abstract class NodeDefinition implements NodeParentInterface
|
||||
protected $parent;
|
||||
protected $attributes = [];
|
||||
|
||||
public function __construct(?string $name, NodeParentInterface $parent = null)
|
||||
public function __construct(?string $name, ?NodeParentInterface $parent = null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->name = $name;
|
||||
|
||||
@@ -36,7 +36,7 @@ class NormalizationBuilder
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function remap(string $key, string $plural = null): static
|
||||
public function remap(string $key, ?string $plural = null): static
|
||||
{
|
||||
$this->remappings[] = [$key, null === $plural ? $key.'s' : $plural];
|
||||
|
||||
@@ -48,7 +48,7 @@ class NormalizationBuilder
|
||||
*
|
||||
* @return ExprBuilder|$this
|
||||
*/
|
||||
public function before(\Closure $closure = null): ExprBuilder|static
|
||||
public function before(?\Closure $closure = null): ExprBuilder|static
|
||||
{
|
||||
if (null !== $closure) {
|
||||
$this->before[] = $closure;
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class NumericNodeDefinition extends ScalarNodeDefinition
|
||||
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));
|
||||
throw new \InvalidArgumentException(\sprintf('You cannot define a max(%s) as you already have a min(%s).', $max, $this->min));
|
||||
}
|
||||
$this->max = $max;
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class NumericNodeDefinition extends ScalarNodeDefinition
|
||||
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));
|
||||
throw new \InvalidArgumentException(\sprintf('You cannot define a min(%s) as you already have a max(%s).', $min, $this->max));
|
||||
}
|
||||
$this->min = $min;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class TreeBuilder implements NodeParentInterface
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
public function __construct(string $name, string $type = 'array', NodeBuilder $builder = null)
|
||||
public function __construct(string $name, string $type = 'array', ?NodeBuilder $builder = null)
|
||||
{
|
||||
$builder ??= new NodeBuilder();
|
||||
$this->root = $builder->node($name, $type)->setParent($this);
|
||||
|
||||
@@ -31,7 +31,7 @@ class ValidationBuilder
|
||||
*
|
||||
* @return ExprBuilder|$this
|
||||
*/
|
||||
public function rule(\Closure $closure = null): ExprBuilder|static
|
||||
public function rule(?\Closure $closure = null): ExprBuilder|static
|
||||
{
|
||||
if (null !== $closure) {
|
||||
$this->rules[] = $closure;
|
||||
|
||||
@@ -29,7 +29,7 @@ class DefinitionConfigurator
|
||||
) {
|
||||
}
|
||||
|
||||
public function import(string $resource, string $type = null, bool $ignoreErrors = false): void
|
||||
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);
|
||||
|
||||
@@ -34,7 +34,7 @@ class XmlReferenceDumper
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dump(ConfigurationInterface $configuration, string $namespace = null)
|
||||
public function dump(ConfigurationInterface $configuration, ?string $namespace = null)
|
||||
{
|
||||
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class XmlReferenceDumper
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function dumpNode(NodeInterface $node, string $namespace = null)
|
||||
public function dumpNode(NodeInterface $node, ?string $namespace = null)
|
||||
{
|
||||
$this->reference = '';
|
||||
$this->writeNode($node, 0, true, $namespace);
|
||||
@@ -52,7 +52,7 @@ class XmlReferenceDumper
|
||||
return $ref;
|
||||
}
|
||||
|
||||
private function writeNode(NodeInterface $node, int $depth = 0, bool $root = false, string $namespace = null): void
|
||||
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));
|
||||
@@ -151,7 +151,7 @@ class XmlReferenceDumper
|
||||
|
||||
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']);
|
||||
$comments[] = \sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
|
||||
}
|
||||
|
||||
if ($child instanceof EnumNode) {
|
||||
@@ -205,7 +205,7 @@ class XmlReferenceDumper
|
||||
$rootOpenTag = '<'.$rootName;
|
||||
if (1 >= ($attributesCount = \count($rootAttributes))) {
|
||||
if (1 === $attributesCount) {
|
||||
$rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
|
||||
$rootOpenTag .= \sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
|
||||
}
|
||||
|
||||
$rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';
|
||||
@@ -221,7 +221,7 @@ class XmlReferenceDumper
|
||||
$i = 1;
|
||||
|
||||
foreach ($rootAttributes as $attrName => $attrValue) {
|
||||
$attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));
|
||||
$attr = \sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));
|
||||
|
||||
$this->writeLine($attr, $depth + 4);
|
||||
|
||||
@@ -258,7 +258,7 @@ class XmlReferenceDumper
|
||||
$indent = \strlen($text) + $indent;
|
||||
$format = '%'.$indent.'s';
|
||||
|
||||
$this->reference .= sprintf($format, $text).\PHP_EOL;
|
||||
$this->reference .= \sprintf($format, $text).\PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,6 @@ 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\Config\Definition\VariableNode;
|
||||
use Symfony\Component\Yaml\Inline;
|
||||
|
||||
/**
|
||||
@@ -47,7 +46,7 @@ class YamlReferenceDumper
|
||||
|
||||
foreach (explode('.', $path) as $step) {
|
||||
if (!$node instanceof ArrayNode) {
|
||||
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
|
||||
throw new \UnexpectedValueException(\sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
|
||||
}
|
||||
|
||||
/** @var NodeInterface[] $children */
|
||||
@@ -61,7 +60,7 @@ class YamlReferenceDumper
|
||||
}
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
|
||||
throw new \UnexpectedValueException(\sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path));
|
||||
}
|
||||
|
||||
return $this->dumpNode($node);
|
||||
@@ -80,7 +79,7 @@ class YamlReferenceDumper
|
||||
return $ref;
|
||||
}
|
||||
|
||||
private function writeNode(NodeInterface $node, NodeInterface $parentNode = null, int $depth = 0, bool $prototypedArray = false): void
|
||||
private function writeNode(NodeInterface $node, ?NodeInterface $parentNode = null, int $depth = 0, bool $prototypedArray = false): void
|
||||
{
|
||||
$comments = [];
|
||||
$default = '';
|
||||
@@ -99,19 +98,12 @@ class YamlReferenceDumper
|
||||
$children = $this->getPrototypeChildren($node);
|
||||
}
|
||||
|
||||
if (!$children) {
|
||||
if ($node->hasDefaultValue() && \count($defaultArray = $node->getDefaultValue())) {
|
||||
$default = '';
|
||||
} elseif (!\is_array($example)) {
|
||||
$default = '[]';
|
||||
}
|
||||
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()) : '~';
|
||||
} elseif (VariableNode::class === $node::class && \is_array($example)) {
|
||||
// If there is an array example, we are sure we dont need to print a default value
|
||||
$default = '';
|
||||
} else {
|
||||
$default = '~';
|
||||
|
||||
@@ -138,7 +130,7 @@ class YamlReferenceDumper
|
||||
// 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']);
|
||||
$comments[] = \sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
|
||||
}
|
||||
|
||||
// example
|
||||
@@ -150,12 +142,12 @@ class YamlReferenceDumper
|
||||
$comments = \count($comments) ? '# '.implode(', ', $comments) : '';
|
||||
|
||||
$key = $prototypedArray ? '-' : $node->getName().':';
|
||||
$text = rtrim(sprintf('%-21s%s %s', $key, $default, $comments), ' ');
|
||||
$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);
|
||||
$info = str_replace("\n", \sprintf("\n%".($depth * 4).'s# ', ' '), $info);
|
||||
$this->writeLine('# '.$info, $depth * 4);
|
||||
}
|
||||
|
||||
@@ -179,7 +171,7 @@ class YamlReferenceDumper
|
||||
|
||||
$this->writeLine('# '.$message.':', $depth * 4 + 4);
|
||||
|
||||
$this->writeArray(array_map(Inline::dump(...), $example), $depth + 1);
|
||||
$this->writeArray(array_map(Inline::dump(...), $example), $depth + 1, true);
|
||||
}
|
||||
|
||||
if ($children) {
|
||||
@@ -197,10 +189,10 @@ class YamlReferenceDumper
|
||||
$indent = \strlen($text) + $indent;
|
||||
$format = '%'.$indent.'s';
|
||||
|
||||
$this->reference .= sprintf($format, $text)."\n";
|
||||
$this->reference .= \sprintf($format, $text)."\n";
|
||||
}
|
||||
|
||||
private function writeArray(array $array, int $depth): void
|
||||
private function writeArray(array $array, int $depth, bool $asComment = false): void
|
||||
{
|
||||
$isIndexed = array_is_list($array);
|
||||
|
||||
@@ -211,14 +203,16 @@ class YamlReferenceDumper
|
||||
$val = $value;
|
||||
}
|
||||
|
||||
$prefix = $asComment ? '# ' : '';
|
||||
|
||||
if ($isIndexed) {
|
||||
$this->writeLine('- '.$val, $depth * 4);
|
||||
$this->writeLine($prefix.'- '.$val, $depth * 4);
|
||||
} else {
|
||||
$this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4);
|
||||
$this->writeLine(\sprintf('%s%-20s %s', $prefix, $key.':', $val), $depth * 4);
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
$this->writeArray($value, $depth + 1);
|
||||
$this->writeArray($value, $depth + 1, $asComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,6 +249,6 @@ class YamlReferenceDumper
|
||||
}
|
||||
$keyNode->setInfo($info);
|
||||
|
||||
return [$key => $keyNode];
|
||||
return [$key ?? '' => $keyNode];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class EnumNode extends ScalarNode
|
||||
{
|
||||
private array $values;
|
||||
|
||||
public function __construct(?string $name, NodeInterface $parent = null, array $values = [], string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
|
||||
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.');
|
||||
@@ -34,11 +34,11 @@ class EnumNode extends ScalarNode
|
||||
}
|
||||
|
||||
if (!$value instanceof \UnitEnum) {
|
||||
throw new \InvalidArgumentException(sprintf('"%s" only supports scalar, enum, or null values, "%s" given.', __CLASS__, get_debug_type($value)));
|
||||
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));
|
||||
throw new \InvalidArgumentException(\sprintf('"%s" only supports one type of enum, "%s" and "%s" passed.', __CLASS__, $enumClass, $value::class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class EnumNode extends ScalarNode
|
||||
$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 = 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;
|
||||
|
||||
@@ -31,7 +31,7 @@ class FloatNode extends NumericNode
|
||||
}
|
||||
|
||||
if (!\is_float($value)) {
|
||||
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected "float", but got "%s".', $this->getPath(), get_debug_type($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);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class IntegerNode extends NumericNode
|
||||
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)));
|
||||
$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);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class DefinitionFileLoader extends FileLoader
|
||||
parent::__construct($locator);
|
||||
}
|
||||
|
||||
public function load(mixed $resource, string $type = null): mixed
|
||||
public function load(mixed $resource, ?string $type = null): mixed
|
||||
{
|
||||
// the loader variable is exposed to the included file below
|
||||
$loader = $this;
|
||||
@@ -57,7 +57,7 @@ class DefinitionFileLoader extends FileLoader
|
||||
return null;
|
||||
}
|
||||
|
||||
public function supports(mixed $resource, string $type = null): bool
|
||||
public function supports(mixed $resource, ?string $type = null): bool
|
||||
{
|
||||
if (!\is_string($resource)) {
|
||||
return false;
|
||||
@@ -81,7 +81,7 @@ class DefinitionFileLoader extends FileLoader
|
||||
$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));
|
||||
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()) {
|
||||
|
||||
@@ -23,7 +23,7 @@ class NumericNode extends ScalarNode
|
||||
protected $min;
|
||||
protected $max;
|
||||
|
||||
public function __construct(?string $name, NodeInterface $parent = null, int|float $min = null, int|float $max = null, string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
|
||||
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;
|
||||
@@ -36,10 +36,10 @@ class NumericNode extends ScalarNode
|
||||
|
||||
$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);
|
||||
$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);
|
||||
$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);
|
||||
|
||||
@@ -67,7 +67,7 @@ class Processor
|
||||
* @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
|
||||
public static function normalizeConfig(array $config, string $key, ?string $plural = null): array
|
||||
{
|
||||
$plural ??= $key.'s';
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ class PrototypedArrayNode extends ArrayNode
|
||||
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)));
|
||||
throw new UnsetKeyException(\sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), json_encode($value)));
|
||||
}
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
@@ -181,7 +181,7 @@ class PrototypedArrayNode extends ArrayNode
|
||||
}
|
||||
|
||||
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 = new InvalidConfigurationException(\sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
@@ -206,7 +206,7 @@ class PrototypedArrayNode extends ArrayNode
|
||||
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 = new InvalidConfigurationException(\sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath()));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
@@ -239,7 +239,7 @@ class PrototypedArrayNode extends ArrayNode
|
||||
}
|
||||
|
||||
if (\array_key_exists($k, $normalized)) {
|
||||
$ex = new DuplicateKeyException(sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath()));
|
||||
$ex = new DuplicateKeyException(\sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath()));
|
||||
$ex->setPath($this->getPath());
|
||||
|
||||
throw $ex;
|
||||
@@ -280,7 +280,7 @@ class PrototypedArrayNode extends ArrayNode
|
||||
// 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 = 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;
|
||||
|
||||
@@ -33,7 +33,7 @@ class ScalarNode extends VariableNode
|
||||
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)));
|
||||
$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);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class VariableNode extends BaseNode implements PrototypeNodeInterface
|
||||
// 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()));
|
||||
$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);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ class VariableNode extends BaseNode implements PrototypeNodeInterface
|
||||
}
|
||||
|
||||
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)));
|
||||
$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);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace Symfony\Component\Config\Exception;
|
||||
*/
|
||||
class FileLoaderImportCircularReferenceException extends LoaderLoadException
|
||||
{
|
||||
public function __construct(array $resources, int $code = 0, \Throwable $previous = null)
|
||||
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]);
|
||||
$message = \sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);
|
||||
|
||||
\Exception::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class FileLocatorFileNotFoundException extends \InvalidArgumentException
|
||||
{
|
||||
private array $paths;
|
||||
|
||||
public function __construct(string $message = '', int $code = 0, \Throwable $previous = null, array $paths = [])
|
||||
public function __construct(string $message = '', int $code = 0, ?\Throwable $previous = null, array $paths = [])
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ class LoaderLoadException extends \Exception
|
||||
* @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)
|
||||
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));
|
||||
$resource = \sprintf('resource of type "%s"', get_debug_type($resource));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,35 +42,35 @@ class LoaderLoadException extends \Exception
|
||||
// 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 ';
|
||||
$message .= \sprintf('%s', $trimmedMessage).' in ';
|
||||
} else {
|
||||
$message .= sprintf('%s', $previous->getMessage()).' in ';
|
||||
$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);
|
||||
$message .= \sprintf('(which is loaded in resource "%s")', $resource);
|
||||
} else {
|
||||
$message .= sprintf('(which is being imported from "%s")', $sourceResource);
|
||||
$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);
|
||||
$message .= \sprintf('Cannot load resource "%s".', $resource);
|
||||
} else {
|
||||
$message .= sprintf('Cannot import resource "%s" from "%s".', $resource, $sourceResource);
|
||||
$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);
|
||||
$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);
|
||||
$message .= \sprintf(' Make sure there is a loader supporting the "%s" type.', $type);
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
@@ -82,20 +82,20 @@ class LoaderLoadException extends \Exception
|
||||
protected function varToString(mixed $var)
|
||||
{
|
||||
if (\is_object($var)) {
|
||||
return sprintf('Object(%s)', $var::class);
|
||||
return \sprintf('Object(%s)', $var::class);
|
||||
}
|
||||
|
||||
if (\is_array($var)) {
|
||||
$a = [];
|
||||
foreach ($var as $k => $v) {
|
||||
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
||||
$a[] = \sprintf('%s => %s', $k, $this->varToString($v));
|
||||
}
|
||||
|
||||
return sprintf('Array(%s)', implode(', ', $a));
|
||||
return \sprintf('Array(%s)', implode(', ', $a));
|
||||
}
|
||||
|
||||
if (\is_resource($var)) {
|
||||
return sprintf('Resource(%s)', get_resource_type($var));
|
||||
return \sprintf('Resource(%s)', get_resource_type($var));
|
||||
}
|
||||
|
||||
if (null === $var) {
|
||||
|
||||
@@ -31,9 +31,11 @@ class FileLocator implements FileLocatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|array
|
||||
* @return string|string[]
|
||||
*
|
||||
* @psalm-return ($first is true ? string : string[])
|
||||
*/
|
||||
public function locate(string $name, string $currentPath = null, bool $first = true)
|
||||
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.');
|
||||
@@ -41,7 +43,7 @@ class FileLocator implements FileLocatorInterface
|
||||
|
||||
if ($this->isAbsolutePath($name)) {
|
||||
if (!file_exists($name)) {
|
||||
throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist.', $name), 0, null, [$name]);
|
||||
throw new FileLocatorFileNotFoundException(\sprintf('The file "%s" does not exist.', $name), 0, null, [$name]);
|
||||
}
|
||||
|
||||
return $name;
|
||||
@@ -68,7 +70,7 @@ class FileLocator implements FileLocatorInterface
|
||||
}
|
||||
|
||||
if (!$filepaths) {
|
||||
throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist (in: "%s").', $name, implode('", "', $paths)), 0, null, $notfound);
|
||||
throw new FileLocatorFileNotFoundException(\sprintf('The file "%s" does not exist (in: "%s").', $name, implode('", "', $paths)), 0, null, $notfound);
|
||||
}
|
||||
|
||||
return $filepaths;
|
||||
@@ -84,7 +86,8 @@ class FileLocator implements FileLocatorInterface
|
||||
&& ':' === $file[1]
|
||||
&& ('\\' === $file[2] || '/' === $file[2])
|
||||
)
|
||||
|| null !== parse_url($file, \PHP_URL_SCHEME)
|
||||
|| parse_url($file, \PHP_URL_SCHEME)
|
||||
|| str_starts_with($file, 'phar:///') // "parse_url()" doesn't handle absolute phar path, despite being valid
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ interface FileLocatorInterface
|
||||
* @param string|null $currentPath The current path
|
||||
* @param bool $first Whether to return the first occurrence or an array of filenames
|
||||
*
|
||||
* @return string|array The full path to the file or an array of file paths
|
||||
* @return string|string[] The full path to the file or an array of file paths
|
||||
*
|
||||
* @psalm-return ($first is true ? string : string[])
|
||||
*
|
||||
* @throws \InvalidArgumentException If $name is empty
|
||||
* @throws FileLocatorFileNotFoundException If a file is not found
|
||||
*/
|
||||
public function locate(string $name, string $currentPath = null, bool $first = true);
|
||||
public function locate(string $name, ?string $currentPath = null, bool $first = true);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class DelegatingLoader extends Loader
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
public function load(mixed $resource, string $type = null): mixed
|
||||
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);
|
||||
@@ -37,7 +37,7 @@ class DelegatingLoader extends Loader
|
||||
return $loader->load($resource, $type);
|
||||
}
|
||||
|
||||
public function supports(mixed $resource, string $type = null): bool
|
||||
public function supports(mixed $resource, ?string $type = null): bool
|
||||
{
|
||||
return false !== $this->resolver->resolve($resource, $type);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ abstract class FileLoader extends Loader
|
||||
|
||||
private ?string $currentDir = null;
|
||||
|
||||
public function __construct(FileLocatorInterface $locator, string $env = null)
|
||||
public function __construct(FileLocatorInterface $locator, ?string $env = null)
|
||||
{
|
||||
$this->locator = $locator;
|
||||
parent::__construct($env);
|
||||
@@ -70,7 +70,7 @@ abstract class FileLoader extends Loader
|
||||
* @throws FileLoaderImportCircularReferenceException
|
||||
* @throws FileLocatorFileNotFoundException
|
||||
*/
|
||||
public function import(mixed $resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null, string|array $exclude = null)
|
||||
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 = [];
|
||||
@@ -101,7 +101,7 @@ abstract class FileLoader extends Loader
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected function glob(string $pattern, bool $recursive, array|GlobResource &$resource = null, bool $ignoreErrors = false, bool $forExclusion = false, array $excluded = []): iterable
|
||||
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;
|
||||
@@ -133,7 +133,7 @@ abstract class FileLoader extends Loader
|
||||
yield from $resource;
|
||||
}
|
||||
|
||||
private function doImport(mixed $resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null): mixed
|
||||
private function doImport(mixed $resource, ?string $type = null, bool $ignoreErrors = false, ?string $sourceResource = null): mixed
|
||||
{
|
||||
try {
|
||||
$loader = $this->resolve($resource, $type);
|
||||
|
||||
@@ -18,12 +18,12 @@ namespace Symfony\Component\Config\Loader;
|
||||
*/
|
||||
class GlobFileLoader extends FileLoader
|
||||
{
|
||||
public function load(mixed $resource, string $type = null): mixed
|
||||
public function load(mixed $resource, ?string $type = null): mixed
|
||||
{
|
||||
return $this->import($resource);
|
||||
}
|
||||
|
||||
public function supports(mixed $resource, string $type = null): bool
|
||||
public function supports(mixed $resource, ?string $type = null): bool
|
||||
{
|
||||
return 'glob' === $type;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ abstract class Loader implements LoaderInterface
|
||||
protected $resolver;
|
||||
protected $env;
|
||||
|
||||
public function __construct(string $env = null)
|
||||
public function __construct(?string $env = null)
|
||||
{
|
||||
$this->env = $env;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ abstract class Loader implements LoaderInterface
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function import(mixed $resource, string $type = null)
|
||||
public function import(mixed $resource, ?string $type = null)
|
||||
{
|
||||
return $this->resolve($resource, $type)->load($resource, $type);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ abstract class Loader implements LoaderInterface
|
||||
*
|
||||
* @throws LoaderLoadException If no loader is found
|
||||
*/
|
||||
public function resolve(mixed $resource, string $type = null): LoaderInterface
|
||||
public function resolve(mixed $resource, ?string $type = null): LoaderInterface
|
||||
{
|
||||
if ($this->supports($resource, $type)) {
|
||||
return $this;
|
||||
|
||||
@@ -25,7 +25,7 @@ interface LoaderInterface
|
||||
*
|
||||
* @throws \Exception If something went wrong
|
||||
*/
|
||||
public function load(mixed $resource, string $type = null);
|
||||
public function load(mixed $resource, ?string $type = null);
|
||||
|
||||
/**
|
||||
* Returns whether this class supports the given resource.
|
||||
@@ -34,7 +34,7 @@ interface LoaderInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(mixed $resource, string $type = null);
|
||||
public function supports(mixed $resource, ?string $type = null);
|
||||
|
||||
/**
|
||||
* Gets the loader resolver.
|
||||
|
||||
@@ -36,7 +36,7 @@ class LoaderResolver implements LoaderResolverInterface
|
||||
}
|
||||
}
|
||||
|
||||
public function resolve(mixed $resource, string $type = null): LoaderInterface|false
|
||||
public function resolve(mixed $resource, ?string $type = null): LoaderInterface|false
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
if ($loader->supports($resource, $type)) {
|
||||
|
||||
@@ -23,5 +23,5 @@ interface LoaderResolverInterface
|
||||
*
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*/
|
||||
public function resolve(mixed $resource, string $type = null): LoaderInterface|false;
|
||||
public function resolve(mixed $resource, ?string $type = null): LoaderInterface|false;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
* @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)
|
||||
public function __construct(string $resource, ?bool $exists = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
if (null !== $exists) {
|
||||
@@ -101,23 +101,23 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
return $this->exists[0] xor !$exists[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
public function __serialize(): array
|
||||
{
|
||||
if (null === $this->exists) {
|
||||
$this->isFresh(0);
|
||||
}
|
||||
|
||||
return ['resource', 'exists'];
|
||||
return [
|
||||
'resource' => $this->resource,
|
||||
'exists' => $this->exists,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup(): void
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
$this->resource = array_shift($data);
|
||||
$this->exists = array_shift($data);
|
||||
|
||||
if (\is_bool($this->exists)) {
|
||||
$this->exists = [$this->exists, null];
|
||||
}
|
||||
@@ -139,7 +139,7 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function throwOnRequiredClass(string $class, \Exception $previous = null): void
|
||||
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) {
|
||||
@@ -158,10 +158,10 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
throw $previous;
|
||||
}
|
||||
|
||||
$message = sprintf('Class "%s" not found.', $class);
|
||||
$message = \sprintf('Class "%s" not found.', $class);
|
||||
|
||||
if ($class !== (self::$autoloadedClass ?? $class)) {
|
||||
$message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
|
||||
$message = substr_replace($message, \sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
|
||||
}
|
||||
|
||||
if (null !== $previous) {
|
||||
|
||||
@@ -29,13 +29,13 @@ class DirectoryResource implements SelfCheckingResourceInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $resource, string $pattern = null)
|
||||
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));
|
||||
throw new \InvalidArgumentException(\sprintf('The directory "%s" does not exist.', $resource));
|
||||
}
|
||||
|
||||
$this->resource = $resolvedResource;
|
||||
|
||||
@@ -34,7 +34,7 @@ class FileResource implements SelfCheckingResourceInterface
|
||||
$resolvedResource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
|
||||
|
||||
if (false === $resolvedResource) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
|
||||
throw new \InvalidArgumentException(\sprintf('The file "%s" does not exist.', $resource));
|
||||
}
|
||||
|
||||
$this->resource = $resolvedResource;
|
||||
|
||||
@@ -53,7 +53,7 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
|
||||
$this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
|
||||
|
||||
if (false === $resolvedPrefix) {
|
||||
throw new \InvalidArgumentException(sprintf('The path "%s" does not exist.', $prefix));
|
||||
throw new \InvalidArgumentException(\sprintf('The path "%s" does not exist.', $prefix));
|
||||
}
|
||||
|
||||
$this->prefix = $resolvedPrefix;
|
||||
@@ -77,21 +77,28 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
|
||||
return $this->hash === $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
public function __serialize(): array
|
||||
{
|
||||
$this->hash ??= $this->computeHash();
|
||||
|
||||
return ['prefix', 'pattern', 'recursive', 'hash', 'forExclusion', 'excludedPrefixes'];
|
||||
return [
|
||||
'prefix' => $this->prefix,
|
||||
'pattern' => $this->pattern,
|
||||
'recursive' => $this->recursive,
|
||||
'hash' => $this->hash,
|
||||
'forExclusion' => $this->forExclusion,
|
||||
'excludedPrefixes' => $this->excludedPrefixes,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup(): void
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
$this->prefix = array_shift($data);
|
||||
$this->pattern = array_shift($data);
|
||||
$this->recursive = array_shift($data);
|
||||
$this->hash = array_shift($data);
|
||||
$this->forExclusion = array_shift($data);
|
||||
$this->excludedPrefixes = array_shift($data);
|
||||
$this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
|
||||
}
|
||||
|
||||
@@ -111,7 +118,7 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
|
||||
if (class_exists(Finder::class)) {
|
||||
$regex = Glob::toRegex($pattern);
|
||||
if ($this->recursive) {
|
||||
$regex = substr_replace($regex, '(/|$)', -2, 1);
|
||||
$regex = substr_replace($regex, str_ends_with($pattern, '/') ? '' : '(/|$)', -2, 1);
|
||||
}
|
||||
} else {
|
||||
$regex = null;
|
||||
|
||||
@@ -60,17 +60,19 @@ class ReflectionClassResource implements SelfCheckingResourceInterface
|
||||
return 'reflection.'.$this->className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
public function __serialize(): array
|
||||
{
|
||||
if (!isset($this->hash)) {
|
||||
$this->hash = $this->computeHash();
|
||||
$this->loadFiles($this->classReflector);
|
||||
}
|
||||
|
||||
return ['files', 'className', 'hash'];
|
||||
return [
|
||||
'files' => $this->files,
|
||||
'className' => $this->className,
|
||||
'excludedVendors' => $this->excludedVendors,
|
||||
'hash' => $this->hash,
|
||||
];
|
||||
}
|
||||
|
||||
private function loadFiles(\ReflectionClass $class): void
|
||||
@@ -123,7 +125,7 @@ class ReflectionClassResource implements SelfCheckingResourceInterface
|
||||
yield print_r($attributes, true);
|
||||
$attributes = [];
|
||||
|
||||
yield $class->getDocComment();
|
||||
yield $class->getDocComment() ?: '';
|
||||
yield (int) $class->isFinal();
|
||||
yield (int) $class->isAbstract();
|
||||
|
||||
@@ -135,6 +137,14 @@ class ReflectionClassResource implements SelfCheckingResourceInterface
|
||||
yield print_r($class->getConstants(), true);
|
||||
}
|
||||
|
||||
foreach ($class->getReflectionConstants() as $constant) {
|
||||
foreach ($constant->getAttributes() as $a) {
|
||||
$attributes[] = [$a->getName(), (string) $a];
|
||||
}
|
||||
yield $constant->name.print_r($attributes, true);
|
||||
$attributes = [];
|
||||
}
|
||||
|
||||
if (!$class->isInterface()) {
|
||||
$defaults = $class->getDefaultProperties();
|
||||
|
||||
@@ -145,7 +155,7 @@ class ReflectionClassResource implements SelfCheckingResourceInterface
|
||||
yield print_r($attributes, true);
|
||||
$attributes = [];
|
||||
|
||||
yield $p->getDocComment();
|
||||
yield $p->getDocComment() ?: '';
|
||||
yield $p->isDefault() ? '<default>' : '';
|
||||
yield $p->isPublic() ? 'public' : 'protected';
|
||||
yield $p->isStatic() ? 'static' : '';
|
||||
|
||||
@@ -109,7 +109,7 @@ class ResourceCheckerConfigCache implements ConfigCacheInterface
|
||||
*
|
||||
* @throws \RuntimeException When cache file can't be written
|
||||
*/
|
||||
public function write(string $content, array $metadata = null)
|
||||
public function write(string $content, ?array $metadata = null)
|
||||
{
|
||||
$mode = 0666;
|
||||
$umask = umask();
|
||||
@@ -150,7 +150,7 @@ class ResourceCheckerConfigCache implements ConfigCacheInterface
|
||||
$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) {
|
||||
if (__FILE__ === $file && !\in_array($type, [\E_DEPRECATED, \E_USER_DEPRECATED], true)) {
|
||||
throw $signalingException;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class XmlUtils
|
||||
* @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 $schemaOrCallable = null): \DOMDocument
|
||||
public static function parse(string $content, string|callable|null $schemaOrCallable = null): \DOMDocument
|
||||
{
|
||||
if (!\extension_loaded('dom')) {
|
||||
throw new \LogicException('Extension DOM is required.');
|
||||
@@ -84,7 +84,7 @@ class XmlUtils
|
||||
} else {
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
throw new XmlParsingException(sprintf('Invalid XSD file: "%s".', $schemaOrCallable));
|
||||
throw new XmlParsingException(\sprintf('Invalid XSD file: "%s".', $schemaOrCallable));
|
||||
}
|
||||
|
||||
if (!$valid) {
|
||||
@@ -112,26 +112,26 @@ class XmlUtils
|
||||
* @throws XmlParsingException When XML parsing returns any errors
|
||||
* @throws \RuntimeException When DOM extension is missing
|
||||
*/
|
||||
public static function loadFile(string $file, string|callable $schemaOrCallable = null): \DOMDocument
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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());
|
||||
throw new XmlParsingException(\sprintf('The XML file "%s" is not valid.', $file), 0, $e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ class XmlUtils
|
||||
{
|
||||
$errors = [];
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
|
||||
$errors[] = \sprintf('[%s %s] %s (in %s - line %d, column %d)',
|
||||
\LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
||||
$error->code,
|
||||
trim($error->message),
|
||||
|
||||
Reference in New Issue
Block a user