package and depencies

This commit is contained in:
RafficMohammed
2023-01-08 02:57:24 +05:30
parent d5332eb421
commit 1d54b8bc7f
4309 changed files with 193331 additions and 172289 deletions

View File

@@ -102,13 +102,9 @@ abstract class AnnotationClassLoader implements LoaderInterface
/**
* Loads from annotations from a class.
*
* @param string $class A class name
*
* @return RouteCollection
*
* @throws \InvalidArgumentException When route can't be parsed
*/
public function load($class, string $type = null)
public function load(mixed $class, string $type = null): RouteCollection
{
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
@@ -154,10 +150,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
return;
}
$name = $annot->getName();
if (null === $name) {
$name = $this->getDefaultRouteName($class, $method);
}
$name = $annot->getName() ?? $this->getDefaultRouteName($class, $method);
$name = $globals['name'].$name;
$requirements = $annot->getRequirements();
@@ -174,11 +167,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
$schemes = array_merge($globals['schemes'], $annot->getSchemes());
$methods = array_merge($globals['methods'], $annot->getMethods());
$host = $annot->getHost();
if (null === $host) {
$host = $globals['host'];
}
$host = $annot->getHost() ?? $globals['host'];
$condition = $annot->getCondition() ?? $globals['condition'];
$priority = $annot->getPriority() ?? $globals['priority'];
@@ -236,25 +225,16 @@ abstract class AnnotationClassLoader implements LoaderInterface
}
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return \is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
return \is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || \in_array($type, ['annotation', 'attribute'], true));
}
/**
* {@inheritdoc}
*/
public function setResolver(LoaderResolverInterface $resolver)
{
}
/**
* {@inheritdoc}
*/
public function getResolver()
public function getResolver(): LoaderResolverInterface
{
}
@@ -280,7 +260,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
$globals = $this->resetGlobals();
$annot = null;
if (\PHP_VERSION_ID >= 80000 && ($attribute = $class->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null)) {
if ($attribute = $class->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
$annot = $attribute->newInstance();
}
if (!$annot && $this->reader) {
@@ -371,21 +351,19 @@ abstract class AnnotationClassLoader implements LoaderInterface
*/
private function getAnnotations(object $reflection): iterable
{
if (\PHP_VERSION_ID >= 80000) {
foreach ($reflection->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
yield $attribute->newInstance();
}
foreach ($reflection->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
yield $attribute->newInstance();
}
if (!$this->reader) {
return;
}
$anntotations = $reflection instanceof \ReflectionClass
$annotations = $reflection instanceof \ReflectionClass
? $this->reader->getClassAnnotations($reflection)
: $this->reader->getMethodAnnotations($reflection);
foreach ($anntotations as $annotation) {
foreach ($annotations as $annotation) {
if ($annotation instanceof $this->routeAnnotationClass) {
yield $annotation;
}

View File

@@ -23,16 +23,9 @@ use Symfony\Component\Routing\RouteCollection;
class AnnotationDirectoryLoader extends AnnotationFileLoader
{
/**
* Loads from annotations from a directory.
*
* @param string $path A directory path
* @param string|null $type The resource type
*
* @return RouteCollection
*
* @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed
*/
public function load($path, string $type = null)
public function load(mixed $path, string $type = null): ?RouteCollection
{
if (!is_dir($dir = $this->locator->locate($path))) {
return parent::supports($path, $type) ? parent::load($path, $type) : new RouteCollection();
@@ -44,7 +37,7 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
new \RecursiveCallbackFilterIterator(
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
function (\SplFileInfo $current) {
return '.' !== substr($current->getBasename(), 0, 1);
return !str_starts_with($current->getBasename(), '.');
}
),
\RecursiveIteratorIterator::LEAVES_ONLY
@@ -71,22 +64,23 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader
return $collection;
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
if ('annotation' === $type) {
if (!\is_string($resource)) {
return false;
}
if (\in_array($type, ['annotation', 'attribute'], true)) {
return true;
}
if ($type || !\is_string($resource)) {
if ($type) {
return false;
}
try {
return is_dir($this->locator->locate($resource));
} catch (\Exception $e) {
} catch (\Exception) {
return false;
}
}

View File

@@ -40,14 +40,9 @@ class AnnotationFileLoader extends FileLoader
/**
* Loads from annotations from a file.
*
* @param string $file A PHP file path
* @param string|null $type The resource type
*
* @return RouteCollection|null
*
* @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
*/
public function load($file, string $type = null)
public function load(mixed $file, string $type = null): ?RouteCollection
{
$path = $this->locator->locate($file);
@@ -67,20 +62,15 @@ class AnnotationFileLoader extends FileLoader
return $collection;
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || \in_array($type, ['annotation', 'attribute'], true));
}
/**
* Returns the full class name for the first class in the file.
*
* @return string|false
*/
protected function findClass(string $file)
protected function findClass(string $file): string|false
{
$class = false;
$namespace = false;

View File

@@ -25,21 +25,13 @@ class ClosureLoader extends Loader
{
/**
* Loads a Closure.
*
* @param \Closure $closure A Closure
* @param string|null $type The resource type
*
* @return RouteCollection
*/
public function load($closure, string $type = null)
public function load(mixed $closure, string $type = null): RouteCollection
{
return $closure($this->env);
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return $resource instanceof \Closure && (!$type || 'closure' === $type);
}

View File

@@ -16,7 +16,7 @@ use Symfony\Component\Routing\Alias;
class AliasConfigurator
{
private $alias;
private Alias $alias;
public function __construct(Alias $alias)
{
@@ -34,7 +34,7 @@ class AliasConfigurator
*
* @throws InvalidArgumentException when the message template is invalid
*/
public function deprecate(string $package, string $version, string $message): self
public function deprecate(string $package, string $version, string $message): static
{
$this->alias->setDeprecated($package, $version, $message);

View File

@@ -23,10 +23,10 @@ class CollectionConfigurator
use Traits\HostTrait;
use Traits\RouteTrait;
private $parent;
private $parentConfigurator;
private $parentPrefixes;
private $host;
private RouteCollection $parent;
private ?CollectionConfigurator $parentConfigurator;
private ?array $parentPrefixes;
private string|array|null $host = null;
public function __construct(RouteCollection $parent, string $name, self $parentConfigurator = null, array $parentPrefixes = null)
{
@@ -38,10 +38,7 @@ class CollectionConfigurator
$this->parentPrefixes = $parentPrefixes;
}
/**
* @return array
*/
public function __sleep()
public function __sleep(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
@@ -78,7 +75,7 @@ class CollectionConfigurator
*
* @return $this
*/
final public function prefix($prefix): self
final public function prefix(string|array $prefix): static
{
if (\is_array($prefix)) {
if (null === $this->parentPrefixes) {
@@ -111,7 +108,7 @@ class CollectionConfigurator
*
* @return $this
*/
final public function host($host): self
final public function host(string|array $host): static
{
$this->host = $host;

View File

@@ -22,7 +22,7 @@ class ImportConfigurator
use Traits\PrefixTrait;
use Traits\RouteTrait;
private $parent;
private RouteCollection $parent;
public function __construct(RouteCollection $parent, RouteCollection $route)
{
@@ -30,10 +30,7 @@ class ImportConfigurator
$this->route = $route;
}
/**
* @return array
*/
public function __sleep()
public function __sleep(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
@@ -55,7 +52,7 @@ class ImportConfigurator
*
* @return $this
*/
final public function prefix($prefix, bool $trailingSlashOnRoot = true): self
final public function prefix(string|array $prefix, bool $trailingSlashOnRoot = true): static
{
$this->addPrefix($this->route, $prefix, $trailingSlashOnRoot);
@@ -67,7 +64,7 @@ class ImportConfigurator
*
* @return $this
*/
final public function namePrefix(string $namePrefix): self
final public function namePrefix(string $namePrefix): static
{
$this->route->addNamePrefix($namePrefix);
@@ -81,7 +78,7 @@ class ImportConfigurator
*
* @return $this
*/
final public function host($host): self
final public function host(string|array $host): static
{
$this->addHost($this->route, $host);

View File

@@ -40,7 +40,7 @@ class RouteConfigurator
*
* @return $this
*/
final public function host($host): self
final public function host(string|array $host): static
{
$this->addHost($this->route, $host);

View File

@@ -21,10 +21,10 @@ class RoutingConfigurator
{
use Traits\AddTrait;
private $loader;
private $path;
private $file;
private $env;
private PhpFileLoader $loader;
private string $path;
private string $file;
private ?string $env;
public function __construct(RouteCollection $collection, PhpFileLoader $loader, string $path, string $file, string $env = null)
{
@@ -38,7 +38,7 @@ class RoutingConfigurator
/**
* @param string|string[]|null $exclude Glob patterns to exclude from the import
*/
final public function import($resource, string $type = null, bool $ignoreErrors = false, $exclude = null): ImportConfigurator
final public function import(string|array $resource, string $type = null, bool $ignoreErrors = false, string|array $exclude = null): ImportConfigurator
{
$this->loader->setCurrentDir(\dirname($this->path));
@@ -68,10 +68,7 @@ class RoutingConfigurator
return $this->env;
}
/**
* @return static
*/
final public function withPath(string $path): self
final public function withPath(string $path): static
{
$clone = clone $this;
$clone->path = $clone->file = $path;

View File

@@ -35,7 +35,7 @@ trait AddTrait
*
* @param string|array $path the path, or the localized paths of the route
*/
public function add(string $name, $path): RouteConfigurator
public function add(string $name, string|array $path): RouteConfigurator
{
$parentConfigurator = $this instanceof CollectionConfigurator ? $this : ($this instanceof RouteConfigurator ? $this->parentConfigurator : null);
$route = $this->createLocalizedRoute($this->collection, $name, $path, $this->name, $this->prefixes);
@@ -53,7 +53,7 @@ trait AddTrait
*
* @param string|array $path the path, or the localized paths of the route
*/
public function __invoke(string $name, $path): RouteConfigurator
public function __invoke(string $name, string|array $path): RouteConfigurator
{
return $this->add($name, $path);
}

View File

@@ -18,7 +18,7 @@ use Symfony\Component\Routing\RouteCollection;
*/
trait HostTrait
{
final protected function addHost(RouteCollection $routes, $hosts)
final protected function addHost(RouteCollection $routes, string|array $hosts)
{
if (!$hosts || !\is_array($hosts)) {
$routes->setHost($hosts ?: '');

View File

@@ -27,7 +27,7 @@ trait LocalizedRouteTrait
*
* @param string|array $path the path, or the localized paths of the route
*/
final protected function createLocalizedRoute(RouteCollection $collection, string $name, $path, string $namePrefix = '', array $prefixes = null): RouteCollection
final protected function createLocalizedRoute(RouteCollection $collection, string $name, string|array $path, string $namePrefix = '', array $prefixes = null): RouteCollection
{
$paths = [];

View File

@@ -21,7 +21,7 @@ use Symfony\Component\Routing\RouteCollection;
*/
trait PrefixTrait
{
final protected function addPrefix(RouteCollection $routes, $prefix, bool $trailingSlashOnRoot)
final protected function addPrefix(RouteCollection $routes, string|array $prefix, bool $trailingSlashOnRoot)
{
if (\is_array($prefix)) {
foreach ($prefix as $locale => $localePrefix) {

View File

@@ -26,7 +26,7 @@ trait RouteTrait
*
* @return $this
*/
final public function defaults(array $defaults): self
final public function defaults(array $defaults): static
{
$this->route->addDefaults($defaults);
@@ -38,7 +38,7 @@ trait RouteTrait
*
* @return $this
*/
final public function requirements(array $requirements): self
final public function requirements(array $requirements): static
{
$this->route->addRequirements($requirements);
@@ -50,7 +50,7 @@ trait RouteTrait
*
* @return $this
*/
final public function options(array $options): self
final public function options(array $options): static
{
$this->route->addOptions($options);
@@ -62,7 +62,7 @@ trait RouteTrait
*
* @return $this
*/
final public function utf8(bool $utf8 = true): self
final public function utf8(bool $utf8 = true): static
{
$this->route->addOptions(['utf8' => $utf8]);
@@ -74,7 +74,7 @@ trait RouteTrait
*
* @return $this
*/
final public function condition(string $condition): self
final public function condition(string $condition): static
{
$this->route->setCondition($condition);
@@ -86,7 +86,7 @@ trait RouteTrait
*
* @return $this
*/
final public function host(string $pattern): self
final public function host(string $pattern): static
{
$this->route->setHost($pattern);
@@ -101,7 +101,7 @@ trait RouteTrait
*
* @return $this
*/
final public function schemes(array $schemes): self
final public function schemes(array $schemes): static
{
$this->route->setSchemes($schemes);
@@ -116,7 +116,7 @@ trait RouteTrait
*
* @return $this
*/
final public function methods(array $methods): self
final public function methods(array $methods): static
{
$this->route->setMethods($methods);
@@ -130,7 +130,7 @@ trait RouteTrait
*
* @return $this
*/
final public function controller($controller): self
final public function controller(callable|string|array $controller): static
{
$this->route->addDefaults(['_controller' => $controller]);
@@ -142,7 +142,7 @@ trait RouteTrait
*
* @return $this
*/
final public function locale(string $locale): self
final public function locale(string $locale): static
{
$this->route->addDefaults(['_locale' => $locale]);
@@ -154,7 +154,7 @@ trait RouteTrait
*
* @return $this
*/
final public function format(string $format): self
final public function format(string $format): static
{
$this->route->addDefaults(['_format' => $format]);
@@ -166,7 +166,7 @@ trait RouteTrait
*
* @return $this
*/
final public function stateless(bool $stateless = true): self
final public function stateless(bool $stateless = true): static
{
$this->route->addDefaults(['_stateless' => $stateless]);

View File

@@ -20,7 +20,7 @@ use Psr\Container\ContainerInterface;
*/
class ContainerLoader extends ObjectLoader
{
private $container;
private ContainerInterface $container;
public function __construct(ContainerInterface $container, string $env = null)
{
@@ -28,18 +28,12 @@ class ContainerLoader extends ObjectLoader
parent::__construct($env);
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return 'service' === $type && \is_string($resource);
}
/**
* {@inheritdoc}
*/
protected function getObject(string $id)
protected function getObject(string $id): object
{
return $this->container->get($id);
}

View File

@@ -17,10 +17,7 @@ use Symfony\Component\Routing\RouteCollection;
class DirectoryLoader extends FileLoader
{
/**
* {@inheritdoc}
*/
public function load($file, string $type = null)
public function load(mixed $file, string $type = null): mixed
{
$path = $this->locator->locate($file);
@@ -46,10 +43,7 @@ class DirectoryLoader extends FileLoader
return $collection;
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
// only when type is forced to directory, not to conflict with AnnotationLoader

View File

@@ -21,10 +21,7 @@ use Symfony\Component\Routing\RouteCollection;
*/
class GlobFileLoader extends FileLoader
{
/**
* {@inheritdoc}
*/
public function load($resource, string $type = null)
public function load(mixed $resource, string $type = null): mixed
{
$collection = new RouteCollection();
@@ -37,10 +34,7 @@ class GlobFileLoader extends FileLoader
return $collection;
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return 'glob' === $type;
}

View File

@@ -27,20 +27,13 @@ abstract class ObjectLoader extends Loader
*
* For example, if your application uses a service container,
* the $id may be a service id.
*
* @return object
*/
abstract protected function getObject(string $id);
abstract protected function getObject(string $id): object;
/**
* Calls the object method that will load the routes.
*
* @param string $resource object_id::method
* @param string|null $type The resource type
*
* @return RouteCollection
*/
public function load($resource, string $type = null)
public function load(mixed $resource, string $type = null): RouteCollection
{
if (!preg_match('/^[^\:]+(?:::(?:[^\:]+))?$/', $resource)) {
throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the %s route loader: use the format "object_id::method" or "object_id" if your object class has an "__invoke" method.', $resource, \is_string($type) ? '"'.$type.'"' : 'object'));

View File

@@ -29,13 +29,8 @@ class PhpFileLoader extends FileLoader
{
/**
* Loads a PHP file.
*
* @param string $file A PHP file path
* @param string|null $type The resource type
*
* @return RouteCollection
*/
public function load($file, string $type = null)
public function load(mixed $file, string $type = null): RouteCollection
{
$path = $this->locator->locate($file);
$this->setCurrentDir(\dirname($path));
@@ -59,10 +54,7 @@ class PhpFileLoader extends FileLoader
return $collection;
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'php' === $type);
}

View File

@@ -0,0 +1,95 @@
<?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\Routing\Loader;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Config\Loader\DirectoryAwareLoaderInterface;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Routing\RouteCollection;
/**
* A loader that discovers controller classes in a directory that follows PSR-4.
*
* @author Alexander M. Turek <me@derrabus.de>
*/
final class Psr4DirectoryLoader extends Loader implements DirectoryAwareLoaderInterface
{
private ?string $currentDirectory = null;
public function __construct(
private readonly FileLocatorInterface $locator,
) {
// PSR-4 directory loader has no env-aware logic, so we drop the $env constructor parameter.
parent::__construct();
}
/**
* @param array{path: string, namespace: string} $resource
*/
public function load(mixed $resource, string $type = null): ?RouteCollection
{
$path = $this->locator->locate($resource['path'], $this->currentDirectory);
if (!is_dir($path)) {
return new RouteCollection();
}
return $this->loadFromDirectory($path, trim($resource['namespace'], '\\'));
}
public function supports(mixed $resource, string $type = null): bool
{
return ('attribute' === $type || 'annotation' === $type) && \is_array($resource) && isset($resource['path'], $resource['namespace']);
}
public function forDirectory(string $currentDirectory): static
{
$loader = clone $this;
$loader->currentDirectory = $currentDirectory;
return $loader;
}
private function loadFromDirectory(string $directory, string $psr4Prefix): RouteCollection
{
$collection = new RouteCollection();
$collection->addResource(new DirectoryResource($directory, '/\.php$/'));
$files = iterator_to_array(new \RecursiveIteratorIterator(
new \RecursiveCallbackFilterIterator(
new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
function (\SplFileInfo $current) {
return !str_starts_with($current->getBasename(), '.');
}
),
\RecursiveIteratorIterator::SELF_FIRST
));
usort($files, function (\SplFileInfo $a, \SplFileInfo $b) {
return (string) $a > (string) $b ? 1 : -1;
});
/** @var \SplFileInfo $file */
foreach ($files as $file) {
if ($file->isDir()) {
$collection->addCollection($this->loadFromDirectory($file->getPathname(), $psr4Prefix.'\\'.$file->getFilename()));
continue;
}
if ('php' !== $file->getExtension() || !class_exists($className = $psr4Prefix.'\\'.$file->getBasename('.php')) || (new \ReflectionClass($className))->isAbstract()) {
continue;
}
$collection->addCollection($this->import($className, 'attribute'));
}
return $collection;
}
}

View File

@@ -35,17 +35,10 @@ class XmlFileLoader extends FileLoader
public const SCHEME_PATH = '/schema/routing/routing-1.0.xsd';
/**
* Loads an XML file.
*
* @param string $file An XML file path
* @param string|null $type The resource type
*
* @return RouteCollection
*
* @throws \InvalidArgumentException when the file cannot be loaded or when the XML cannot be
* parsed because it does not validate against the scheme
*/
public function load($file, string $type = null)
public function load(mixed $file, string $type = null): RouteCollection
{
$path = $this->locator->locate($file);
@@ -99,10 +92,7 @@ class XmlFileLoader extends FileLoader
}
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return \is_string($resource) && 'xml' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'xml' === $type);
}
@@ -161,8 +151,17 @@ class XmlFileLoader extends FileLoader
*/
protected function parseImport(RouteCollection $collection, \DOMElement $node, string $path, string $file)
{
if ('' === $resource = $node->getAttribute('resource')) {
throw new \InvalidArgumentException(sprintf('The <import> element in file "%s" must have a "resource" attribute.', $path));
/** @var \DOMElement $resourceElement */
if (!($resource = $node->getAttribute('resource') ?: null) && $resourceElement = $node->getElementsByTagName('resource')[0] ?? null) {
$resource = [];
/** @var \DOMAttr $attribute */
foreach ($resourceElement->attributes as $attribute) {
$resource[$attribute->name] = $attribute->value;
}
}
if (!$resource) {
throw new \InvalidArgumentException(sprintf('The <import> element in file "%s" must have a "resource" attribute or element.', $path));
}
$type = $node->getAttribute('type');
@@ -229,13 +228,11 @@ class XmlFileLoader extends FileLoader
}
/**
* @return \DOMDocument
*
* @throws \InvalidArgumentException When loading of XML file fails because of syntax errors
* or when the XML structure is not as expected by the scheme -
* see validate()
*/
protected function loadFile(string $file)
protected function loadFile(string $file): \DOMDocument
{
return XmlUtils::loadFile($file, __DIR__.static::SCHEME_PATH);
}
@@ -288,6 +285,8 @@ class XmlFileLoader extends FileLoader
case 'condition':
$condition = trim($n->textContent);
break;
case 'resource':
break;
default:
throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement", "option" or "condition".', $n->localName, $path));
}
@@ -330,10 +329,8 @@ class XmlFileLoader extends FileLoader
/**
* Parses the "default" elements.
*
* @return array|bool|float|int|string|null
*/
private function parseDefaultsConfig(\DOMElement $element, string $path)
private function parseDefaultsConfig(\DOMElement $element, string $path): array|bool|float|int|string|null
{
if ($this->isElementValueNull($element)) {
return null;
@@ -363,11 +360,9 @@ class XmlFileLoader extends FileLoader
/**
* Recursively parses the value of a "default" element.
*
* @return array|bool|float|int|string|null
*
* @throws \InvalidArgumentException when the XML is invalid
*/
private function parseDefaultNode(\DOMElement $node, string $path)
private function parseDefaultNode(\DOMElement $node, string $path): array|bool|float|int|string|null
{
if ($this->isElementValueNull($node)) {
return null;

View File

@@ -36,19 +36,12 @@ class YamlFileLoader extends FileLoader
private const AVAILABLE_KEYS = [
'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller', 'name_prefix', 'trailing_slash_on_root', 'locale', 'format', 'utf8', 'exclude', 'stateless',
];
private $yamlParser;
private YamlParser $yamlParser;
/**
* Loads a Yaml file.
*
* @param string $file A Yaml file path
* @param string|null $type The resource type
*
* @return RouteCollection
*
* @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
*/
public function load($file, string $type = null)
public function load(mixed $file, string $type = null): RouteCollection
{
$path = $this->locator->locate($file);
@@ -60,9 +53,7 @@ class YamlFileLoader extends FileLoader
throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path));
}
if (null === $this->yamlParser) {
$this->yamlParser = new YamlParser();
}
$this->yamlParser ??= new YamlParser();
try {
$parsedConfig = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT);
@@ -84,7 +75,7 @@ class YamlFileLoader extends FileLoader
}
foreach ($parsedConfig as $name => $config) {
if (0 === strpos($name, 'when@')) {
if (str_starts_with($name, 'when@')) {
if (!$this->env || 'when@'.$this->env !== $name) {
continue;
}
@@ -114,10 +105,7 @@ class YamlFileLoader extends FileLoader
return $collection;
}
/**
* {@inheritdoc}
*/
public function supports($resource, string $type = null)
public function supports(mixed $resource, string $type = null): bool
{
return \is_string($resource) && \in_array(pathinfo($resource, \PATHINFO_EXTENSION), ['yml', 'yaml'], true) && (!$type || 'yaml' === $type);
}
@@ -250,16 +238,10 @@ class YamlFileLoader extends FileLoader
}
/**
* Validates the route configuration.
*
* @param array $config A resource config
* @param string $name The config key
* @param string $path The loaded file path
*
* @throws \InvalidArgumentException If one of the provided config keys is not supported,
* something is missing or the combination is nonsense
*/
protected function validate($config, string $name, string $path)
protected function validate(mixed $config, string $name, string $path)
{
if (!\is_array($config)) {
throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));

View File

@@ -76,8 +76,9 @@
<xsd:element name="prefix" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="exclude" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="host" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="resource" type="resource" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="resource" type="xsd:string" use="required" />
<xsd:attribute name="resource" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="exclude" type="xsd:string" />
<xsd:attribute name="prefix" type="xsd:string" />
@@ -93,6 +94,12 @@
<xsd:attribute name="stateless" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="resource">
<xsd:attribute name="path" type="xsd:string" />
<xsd:attribute name="namespace" type="xsd:string" />
<xsd:anyAttribute />
</xsd:complexType>
<xsd:complexType name="default" mixed="true">
<xsd:choice minOccurs="0" maxOccurs="1">
<xsd:element name="bool" type="xsd:boolean" />