Showing preview only (975K chars total). Download the full file or copy to clipboard to get everything.
Repository: symfony/routing
Branch: 8.1
Commit: 6d8b12dd9ddd
Files: 315
Total size: 892.0 KB
Directory structure:
gitextract_lyoz_2vn/
├── .gitattributes
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ └── close-pull-request.yml
├── .gitignore
├── Alias.php
├── Attribute/
│ ├── DeprecatedAlias.php
│ └── Route.php
├── CHANGELOG.md
├── CompiledRoute.php
├── DependencyInjection/
│ ├── AddExpressionLanguageProvidersPass.php
│ ├── RoutingControllerPass.php
│ └── RoutingResolverPass.php
├── Exception/
│ ├── ExceptionInterface.php
│ ├── InvalidArgumentException.php
│ ├── InvalidParameterException.php
│ ├── LogicException.php
│ ├── MethodNotAllowedException.php
│ ├── MissingMandatoryParametersException.php
│ ├── NoConfigurationException.php
│ ├── ResourceNotFoundException.php
│ ├── RouteCircularReferenceException.php
│ ├── RouteNotFoundException.php
│ └── RuntimeException.php
├── Generator/
│ ├── CompiledUrlGenerator.php
│ ├── ConfigurableRequirementsInterface.php
│ ├── Dumper/
│ │ ├── CompiledUrlGeneratorDumper.php
│ │ ├── GeneratorDumper.php
│ │ └── GeneratorDumperInterface.php
│ ├── UrlGenerator.php
│ └── UrlGeneratorInterface.php
├── LICENSE
├── Loader/
│ ├── AttributeClassLoader.php
│ ├── AttributeDirectoryLoader.php
│ ├── AttributeFileLoader.php
│ ├── AttributeServicesLoader.php
│ ├── ClosureLoader.php
│ ├── Configurator/
│ │ ├── AliasConfigurator.php
│ │ ├── CollectionConfigurator.php
│ │ ├── ImportConfigurator.php
│ │ ├── RouteConfigurator.php
│ │ ├── RoutesReference.php
│ │ ├── RoutingConfigurator.php
│ │ └── Traits/
│ │ ├── AddTrait.php
│ │ ├── HostTrait.php
│ │ ├── LocalizedRouteTrait.php
│ │ ├── PrefixTrait.php
│ │ └── RouteTrait.php
│ ├── ContainerLoader.php
│ ├── ContentLoaderTrait.php
│ ├── DirectoryLoader.php
│ ├── GlobFileLoader.php
│ ├── ObjectLoader.php
│ ├── PhpFileLoader.php
│ ├── Psr4DirectoryLoader.php
│ ├── YamlFileLoader.php
│ └── schema/
│ ├── routing/
│ │ └── routing-1.0.xsd
│ └── routing.schema.json
├── Matcher/
│ ├── CompiledUrlMatcher.php
│ ├── Dumper/
│ │ ├── CompiledUrlMatcherDumper.php
│ │ ├── CompiledUrlMatcherTrait.php
│ │ ├── MatcherDumper.php
│ │ ├── MatcherDumperInterface.php
│ │ └── StaticPrefixCollection.php
│ ├── ExpressionLanguageProvider.php
│ ├── RedirectableUrlMatcher.php
│ ├── RedirectableUrlMatcherInterface.php
│ ├── RequestMatcherInterface.php
│ ├── TraceableUrlMatcher.php
│ ├── UrlMatcher.php
│ └── UrlMatcherInterface.php
├── README.md
├── RequestContext.php
├── RequestContextAwareInterface.php
├── Requirement/
│ ├── EnumRequirement.php
│ └── Requirement.php
├── Route.php
├── RouteCollection.php
├── RouteCompiler.php
├── RouteCompilerInterface.php
├── Router.php
├── RouterInterface.php
├── Tests/
│ ├── Attribute/
│ │ └── RouteTest.php
│ ├── CompiledRouteTest.php
│ ├── DependencyInjection/
│ │ ├── AddExpressionLanguageProvidersPassTest.php
│ │ ├── RoutingControllerPassTest.php
│ │ └── RoutingResolverPassTest.php
│ ├── Fixtures/
│ │ ├── AttributeFixtures/
│ │ │ ├── AbstractClassController.php
│ │ │ ├── ActionPathController.php
│ │ │ ├── AliasClassController.php
│ │ │ ├── AliasInvokableController.php
│ │ │ ├── AliasLocalizedRouteController.php
│ │ │ ├── AliasRouteController.php
│ │ │ ├── BazClass.php
│ │ │ ├── DefaultValueController.php
│ │ │ ├── DeprecatedAliasCustomMessageRouteController.php
│ │ │ ├── DeprecatedAliasRouteController.php
│ │ │ ├── EncodingClass.php
│ │ │ ├── ExplicitLocalizedActionPathController.php
│ │ │ ├── ExtendedRoute.php
│ │ │ ├── ExtendedRouteOnClassController.php
│ │ │ ├── ExtendedRouteOnMethodController.php
│ │ │ ├── FooController.php
│ │ │ ├── GlobalDefaultsClass.php
│ │ │ ├── InvokableController.php
│ │ │ ├── InvokableFQCNAliasConflictController.php
│ │ │ ├── InvokableLocalizedController.php
│ │ │ ├── InvokableMethodController.php
│ │ │ ├── LocalizedActionPathController.php
│ │ │ ├── LocalizedMethodActionControllers.php
│ │ │ ├── LocalizedPrefixLocalizedActionController.php
│ │ │ ├── LocalizedPrefixMissingLocaleActionController.php
│ │ │ ├── LocalizedPrefixMissingRouteLocaleActionController.php
│ │ │ ├── LocalizedPrefixWithRouteWithoutLocale.php
│ │ │ ├── MethodActionControllers.php
│ │ │ ├── MethodsAndSchemes.php
│ │ │ ├── MissingRouteNameController.php
│ │ │ ├── MultipleDeprecatedAliasRouteController.php
│ │ │ ├── NothingButNameController.php
│ │ │ ├── PrefixedActionLocalizedRouteController.php
│ │ │ ├── PrefixedActionPathController.php
│ │ │ ├── RequirementsWithoutPlaceholderNameController.php
│ │ │ ├── RouteWithEnv.php
│ │ │ ├── RouteWithPrefixController.php
│ │ │ ├── RouteWithPriorityController.php
│ │ │ └── Utf8ActionControllers.php
│ │ ├── AttributedClasses/
│ │ │ ├── AbstractClass.php
│ │ │ ├── BarClass.php
│ │ │ ├── BazClass.php
│ │ │ ├── EncodingClass.php
│ │ │ ├── FooClass.php
│ │ │ └── FooTrait.php
│ │ ├── Attributes/
│ │ │ └── FooAttributes.php
│ │ ├── AttributesFixtures/
│ │ │ ├── AttributesClassParamAfterCommaController.php
│ │ │ ├── AttributesClassParamAfterParenthesisController.php
│ │ │ ├── AttributesClassParamInlineAfterCommaController.php
│ │ │ ├── AttributesClassParamInlineAfterParenthesisController.php
│ │ │ ├── AttributesClassParamInlineQuotedAfterCommaController.php
│ │ │ ├── AttributesClassParamInlineQuotedAfterParenthesisController.php
│ │ │ ├── AttributesClassParamQuotedAfterCommaController.php
│ │ │ └── AttributesClassParamQuotedAfterParenthesisController.php
│ │ ├── CustomCompiledRoute.php
│ │ ├── CustomRouteCompiler.php
│ │ ├── Enum/
│ │ │ ├── TestIntBackedEnum.php
│ │ │ ├── TestStringBackedEnum.php
│ │ │ ├── TestStringBackedEnum2.php
│ │ │ └── TestUnitEnum.php
│ │ ├── OtherAnnotatedClasses/
│ │ │ ├── NoStartTagClass.php
│ │ │ └── VariadicClass.php
│ │ ├── Psr4Controllers/
│ │ │ ├── MyController.php
│ │ │ ├── MyUnannotatedController.php
│ │ │ └── SubNamespace/
│ │ │ ├── EvenDeeperNamespace/
│ │ │ │ └── MyOtherController.php
│ │ │ ├── IrrelevantClass.php
│ │ │ ├── IrrelevantEnum.php
│ │ │ ├── IrrelevantInterface.php
│ │ │ ├── MyAbstractController.php
│ │ │ ├── MyChildController.php
│ │ │ ├── MyControllerWithATrait.php
│ │ │ └── SomeSharedImplementation.php
│ │ ├── RedirectableUrlMatcher.php
│ │ ├── TraceableAttributeClassLoader.php
│ │ ├── alias/
│ │ │ ├── alias.php
│ │ │ ├── alias.yaml
│ │ │ ├── expected.php
│ │ │ ├── invalid-alias.yaml
│ │ │ ├── invalid-deprecated-no-package.yaml
│ │ │ ├── invalid-deprecated-no-version.yaml
│ │ │ └── override.yaml
│ │ ├── annotated.php
│ │ ├── array_routes.php
│ │ ├── array_when_env.php
│ │ ├── bad_format.yml
│ │ ├── class-attributes.php
│ │ ├── class-attributes.yaml
│ │ ├── collection-defaults.php
│ │ ├── controller/
│ │ │ ├── empty_wildcard/
│ │ │ │ └── .gitignore
│ │ │ ├── import__controller.yml
│ │ │ ├── import_controller.yml
│ │ │ ├── import_override_defaults.yml
│ │ │ ├── override_defaults.yml
│ │ │ └── routing.yml
│ │ ├── defaults.php
│ │ ├── defaults.yml
│ │ ├── directory/
│ │ │ ├── recurse/
│ │ │ │ ├── routes1.yml
│ │ │ │ └── routes2.yml
│ │ │ └── routes3.yml
│ │ ├── directory_import/
│ │ │ └── import.yml
│ │ ├── dumper/
│ │ │ ├── compiled_url_matcher0.php
│ │ │ ├── compiled_url_matcher1.php
│ │ │ ├── compiled_url_matcher10.php
│ │ │ ├── compiled_url_matcher11.php
│ │ │ ├── compiled_url_matcher12.php
│ │ │ ├── compiled_url_matcher13.php
│ │ │ ├── compiled_url_matcher14.php
│ │ │ ├── compiled_url_matcher2.php
│ │ │ ├── compiled_url_matcher3.php
│ │ │ ├── compiled_url_matcher4.php
│ │ │ ├── compiled_url_matcher5.php
│ │ │ ├── compiled_url_matcher6.php
│ │ │ ├── compiled_url_matcher7.php
│ │ │ ├── compiled_url_matcher8.php
│ │ │ └── compiled_url_matcher9.php
│ │ ├── empty.yml
│ │ ├── file_resource.yml
│ │ ├── glob/
│ │ │ ├── bar.yml
│ │ │ ├── baz.yml
│ │ │ ├── import_multiple.yml
│ │ │ ├── import_single.yml
│ │ │ ├── php_dsl.php
│ │ │ ├── php_dsl_bar.php
│ │ │ └── php_dsl_baz.php
│ │ ├── import_with_name_prefix/
│ │ │ └── routing.yml
│ │ ├── import_with_no_trailing_slash/
│ │ │ └── routing.yml
│ │ ├── imported-with-defaults.php
│ │ ├── imported-with-defaults.yml
│ │ ├── importer-php-returns-array-with-import.yml
│ │ ├── importer-php-returns-array.php
│ │ ├── importer-with-defaults.php
│ │ ├── importer-with-defaults.yml
│ │ ├── incomplete.yml
│ │ ├── legacy_internal_scope.php
│ │ ├── locale_and_host/
│ │ │ ├── import-with-host-expected-collection.php
│ │ │ ├── import-with-locale-and-host-expected-collection.php
│ │ │ ├── import-with-single-host-expected-collection.php
│ │ │ ├── import-without-host-expected-collection.php
│ │ │ ├── imported.php
│ │ │ ├── imported.yml
│ │ │ ├── importer-with-host.php
│ │ │ ├── importer-with-host.yml
│ │ │ ├── importer-with-locale-and-host.php
│ │ │ ├── importer-with-locale-and-host.yml
│ │ │ ├── importer-with-single-host.php
│ │ │ ├── importer-with-single-host.yml
│ │ │ ├── importer-without-host.php
│ │ │ ├── importer-without-host.yml
│ │ │ ├── priorized-host.yml
│ │ │ ├── route-with-hosts-expected-collection.php
│ │ │ ├── route-with-hosts.php
│ │ │ └── route-with-hosts.yml
│ │ ├── localized/
│ │ │ ├── imported-with-locale-but-not-localized.yml
│ │ │ ├── imported-with-locale.yml
│ │ │ ├── imported-with-utf8.php
│ │ │ ├── imported-with-utf8.yml
│ │ │ ├── importer-with-controller-default.yml
│ │ │ ├── importer-with-locale-imports-non-localized-route.yml
│ │ │ ├── importer-with-locale.yml
│ │ │ ├── importer-with-utf8.php
│ │ │ ├── importer-with-utf8.yml
│ │ │ ├── importing-localized-route.yml
│ │ │ ├── localized-prefix.yml
│ │ │ ├── localized-route.yml
│ │ │ ├── missing-locale-in-importer.yml
│ │ │ ├── not-localized.yml
│ │ │ ├── officially_formatted_locales.yml
│ │ │ ├── route-without-path-or-locales.yml
│ │ │ ├── utf8.php
│ │ │ └── utf8.yml
│ │ ├── nonesense_resource_plus_path.yml
│ │ ├── nonesense_type_without_resource.yml
│ │ ├── nonvalid.yml
│ │ ├── nonvalid2.yml
│ │ ├── nonvalidkeys.yml
│ │ ├── php_dsl.php
│ │ ├── php_dsl_i18n.php
│ │ ├── php_dsl_sub.php
│ │ ├── php_dsl_sub_i18n.php
│ │ ├── php_dsl_sub_root.php
│ │ ├── php_object_dsl.php
│ │ ├── psr4-attributes.php
│ │ ├── psr4-attributes.yaml
│ │ ├── psr4-controllers-redirection/
│ │ │ ├── psr4-attributes.php
│ │ │ └── psr4-attributes.yaml
│ │ ├── psr4-controllers-redirection.php
│ │ ├── psr4-controllers-redirection.yaml
│ │ ├── requirements_without_placeholder_name.yml
│ │ ├── special_route_name.yml
│ │ ├── validpattern.php
│ │ ├── validpattern.yml
│ │ ├── validresource.php
│ │ ├── validresource.yml
│ │ ├── when-env.php
│ │ ├── when-env.yml
│ │ └── with_define_path_variable.php
│ ├── Generator/
│ │ ├── Dumper/
│ │ │ └── CompiledUrlGeneratorDumperTest.php
│ │ └── UrlGeneratorTest.php
│ ├── Loader/
│ │ ├── AttributeClassLoaderTest.php
│ │ ├── AttributeDirectoryLoaderTest.php
│ │ ├── AttributeFileLoaderTest.php
│ │ ├── AttributeServicesLoaderTest.php
│ │ ├── ClosureLoaderTest.php
│ │ ├── Configurator/
│ │ │ └── Traits/
│ │ │ └── PrefixTraitTest.php
│ │ ├── ContainerLoaderTest.php
│ │ ├── DirectoryLoaderTest.php
│ │ ├── FileLocatorStub.php
│ │ ├── GlobFileLoaderTest.php
│ │ ├── ObjectLoaderTest.php
│ │ ├── PhpFileLoaderTest.php
│ │ ├── Psr4DirectoryLoaderTest.php
│ │ └── YamlFileLoaderTest.php
│ ├── Matcher/
│ │ ├── CompiledRedirectableUrlMatcherTest.php
│ │ ├── CompiledUrlMatcherTest.php
│ │ ├── Dumper/
│ │ │ ├── CompiledUrlMatcherDumperTest.php
│ │ │ └── StaticPrefixCollectionTest.php
│ │ ├── ExpressionLanguageProviderTest.php
│ │ ├── RedirectableUrlMatcherTest.php
│ │ ├── TraceableUrlMatcherTest.php
│ │ └── UrlMatcherTest.php
│ ├── RequestContextTest.php
│ ├── Requirement/
│ │ ├── EnumRequirementTest.php
│ │ └── RequirementTest.php
│ ├── RouteCollectionTest.php
│ ├── RouteCompilerTest.php
│ ├── RouteTest.php
│ └── RouterTest.php
├── composer.json
└── phpunit.xml.dist
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.git* export-ignore
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Please do not submit any Pull Requests here. They will be closed.
---
Please submit your PR here instead:
https://github.com/symfony/symfony
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
================================================
FILE: .github/workflows/close-pull-request.yml
================================================
name: Close Pull Request
on:
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/symfony
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
================================================
FILE: .gitignore
================================================
vendor/
composer.lock
phpunit.xml
================================================
FILE: Alias.php
================================================
<?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;
use Symfony\Component\Routing\Exception\InvalidArgumentException;
class Alias
{
private array $deprecation = [];
public function __construct(
private string $id,
) {
}
public function withId(string $id): static
{
$new = clone $this;
$new->id = $id;
return $new;
}
/**
* Returns the target name of this alias.
*
* @return string The target name
*/
public function getId(): string
{
return $this->id;
}
/**
* Whether this alias is deprecated, that means it should not be referenced anymore.
*
* @param string $package The name of the composer package that is triggering the deprecation
* @param string $version The version of the package that introduced the deprecation
* @param string $message The deprecation message to use
*
* @return $this
*
* @throws InvalidArgumentException when the message template is invalid
*/
public function setDeprecated(string $package, string $version, string $message): static
{
if ('' !== $message) {
if (preg_match('#[\r\n]|\*/#', $message)) {
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
}
if (!str_contains($message, '%alias_id%')) {
throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.');
}
}
$this->deprecation = [
'package' => $package,
'version' => $version,
'message' => $message ?: 'The "%alias_id%" route alias is deprecated. You should stop using it, as it will be removed in the future.',
];
return $this;
}
public function isDeprecated(): bool
{
return (bool) $this->deprecation;
}
/**
* @param string $name Route name relying on this alias
*/
public function getDeprecation(string $name): array
{
return [
'package' => $this->deprecation['package'],
'version' => $this->deprecation['version'],
'message' => str_replace('%alias_id%', $name, $this->deprecation['message']),
];
}
}
================================================
FILE: Attribute/DeprecatedAlias.php
================================================
<?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\Attribute;
/**
* This class is meant to be used in {@see Route} to define an alias for a route.
*/
class DeprecatedAlias
{
public function __construct(
public readonly string $aliasName,
public readonly string $package,
public readonly string $version,
public readonly string $message = '',
) {
}
}
================================================
FILE: Attribute/Route.php
================================================
<?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\Attribute;
/**
* @author Fabien Potencier <fabien@symfony.com>
* @author Alexander M. Turek <me@derrabus.de>
*/
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
class Route
{
/** @var string[] */
public array $methods;
/** @var string[] */
public array $envs;
/** @var string[] */
public array $schemes;
/** @var (string|DeprecatedAlias)[] */
public array $aliases = [];
/**
* @param string|array<string,string>|null $path The route path (i.e. "/user/login")
* @param string|null $name The route name (i.e. "app_user_login")
* @param array<string|\Stringable> $requirements Requirements for the route attributes, @see https://symfony.com/doc/current/routing.html#parameters-validation
* @param array<string, mixed> $options Options for the route (i.e. ['prefix' => '/api'])
* @param array<string, mixed> $defaults Default values for the route attributes and query parameters
* @param string|null $host The host for which this route should be active (i.e. "localhost")
* @param string|string[] $methods The list of HTTP methods allowed by this route
* @param string|string[] $schemes The list of schemes allowed by this route (i.e. "https")
* @param string|null $condition An expression that must evaluate to true for the route to be matched, @see https://symfony.com/doc/current/routing.html#matching-expressions
* @param int|null $priority The priority of the route if multiple ones are defined for the same path
* @param string|null $locale The locale accepted by the route
* @param string|null $format The format returned by the route (i.e. "json", "xml")
* @param bool|null $utf8 Whether the route accepts UTF-8 in its parameters
* @param bool|null $stateless Whether the route is defined as stateless or stateful, @see https://symfony.com/doc/current/routing.html#stateless-routes
* @param string|string[]|null $env The env(s) in which the route is defined (i.e. "dev", "test", "prod", ["dev", "test"])
* @param string|DeprecatedAlias|(string|DeprecatedAlias)[] $alias The list of aliases for this route
*/
public function __construct(
public string|array|null $path = null,
public ?string $name = null,
public array $requirements = [],
public array $options = [],
public array $defaults = [],
public ?string $host = null,
array|string $methods = [],
array|string $schemes = [],
public ?string $condition = null,
public ?int $priority = null,
?string $locale = null,
?string $format = null,
?bool $utf8 = null,
?bool $stateless = null,
string|array|null $env = null,
string|DeprecatedAlias|array $alias = [],
) {
$this->path = $path;
$this->methods = (array) $methods;
$this->schemes = (array) $schemes;
$this->envs = (array) $env;
$this->aliases = \is_array($alias) ? $alias : [$alias];
if (null !== $locale) {
$this->defaults['_locale'] = $locale;
}
if (null !== $format) {
$this->defaults['_format'] = $format;
}
if (null !== $utf8) {
$this->options['utf8'] = $utf8;
}
if (null !== $stateless) {
$this->defaults['_stateless'] = $stateless;
}
}
}
================================================
FILE: CHANGELOG.md
================================================
CHANGELOG
=========
8.0
---
* Remove support for accessing the internal scope of the loader in PHP config files, use only its public API instead
* Providing a non-array `_query` parameter to `UrlGenerator` causes an `InvalidParameterException`
* Remove the protected `AttributeClassLoader::$routeAnnotationClass` property and the `setRouteAnnotationClass()` method, use `AttributeClassLoader::setRouteAttributeClass()` instead
* Remove class aliases in the `Annotation` namespace, use attributes instead
* Remove getters and setters in attribute classes in favor of public properties
* Remove support for the XML configuration format
7.4
---
* Add `AttributeServicesLoader` and `RoutingControllerPass` to auto-register routes from attributes on services
* Allow query-specific parameters in `UrlGenerator` using `_query`
* Add support of multiple env names in the `Symfony\Component\Routing\Attribute\Route` attribute
* Add argument `$parameters` to `RequestContext`'s constructor
* Handle declaring routes using PHP arrays that follow the same shape as corresponding yaml files
* Add `RoutesReference` to help writing PHP configs using yaml-like array-shapes
* Deprecate class aliases in the `Annotation` namespace, use attributes instead
* Deprecate getters and setters in attribute classes in favor of public properties
* Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead
* Deprecate XML configuration format, use YAML, PHP or attributes instead
7.3
---
* Allow aliases and deprecations in `#[Route]` attribute
* Add the `Requirement::MONGODB_ID` constant to validate MongoDB ObjectIDs in hexadecimal format
7.2
---
* Add the `Requirement::UID_RFC9562` constant to validate UUIDs in the RFC 9562 format
* Deprecate the `AttributeClassLoader::$routeAnnotationClass` property
7.1
---
* Add `{foo:bar}` syntax to define a mapping between a route parameter and its corresponding request attribute
7.0
---
* Add argument `$routeParameters` to `UrlMatcher::handleRouteRequirements()`
* Remove Doctrine annotations support in favor of native attributes
* Remove `AnnotationClassLoader`, use `AttributeClassLoader` instead
* Remove `AnnotationDirectoryLoader`, use `AttributeDirectoryLoader` instead
* Remove `AnnotationFileLoader`, use `AttributeFileLoader` instead
6.4
---
* Add FQCN and FQCN::method aliases for routes loaded from attributes/annotations when applicable
* Add native return type to `AnnotationClassLoader::setResolver()`
* Deprecate Doctrine annotations support in favor of native attributes
* Change the constructor signature of `AnnotationClassLoader` to `__construct(?string $env = null)`, passing an annotation reader as first argument is deprecated
* Deprecate `AnnotationClassLoader`, use `AttributeClassLoader` instead
* Deprecate `AnnotationDirectoryLoader`, use `AttributeDirectoryLoader` instead
* Deprecate `AnnotationFileLoader`, use `AttributeFileLoader` instead
* Add `AddExpressionLanguageProvidersPass` (moved from `FrameworkBundle`)
* Add aliases for all classes in the `Annotation` namespace to `Attribute`
6.2
---
* Add `Requirement::POSITIVE_INT` for common ids and pagination
6.1
---
* Add `getMissingParameters` and `getRouteName` methods on `MissingMandatoryParametersException`
* Allow using UTF-8 parameter names
* Support the `attribute` type (alias of `annotation`) in annotation loaders
* Already encoded slashes are not decoded nor double-encoded anymore when generating URLs (query parameters)
* Add `EnumRequirement` to help generate route requirements from a `\BackedEnum`
* Add `Requirement`, a collection of universal regular-expression constants to use as route parameter requirements
* Add `params` variable to condition expression
* Deprecate not passing route parameters as the fourth argument to `UrlMatcher::handleRouteRequirements()`
5.3
---
* Already encoded slashes are not decoded nor double-encoded anymore when generating URLs
* Add support for per-env configuration in XML and Yaml loaders
* Deprecate creating instances of the `Route` annotation class by passing an array of parameters
* Add `RoutingConfigurator::env()` to get the current environment
5.2.0
-----
* Added support for inline definition of requirements and defaults for host
* Added support for `\A` and `\z` as regex start and end for route requirement
* Added support for `#[Route]` attributes
5.1.0
-----
* added the protected method `PhpFileLoader::callConfigurator()` as extension point to ease custom routing configuration
* deprecated `RouteCollectionBuilder` in favor of `RoutingConfigurator`.
* added "priority" option to annotated routes
* added argument `$priority` to `RouteCollection::add()`
* deprecated the `RouteCompiler::REGEX_DELIMITER` constant
* added `ExpressionLanguageProvider` to expose extra functions to route conditions
* added support for a `stateless` keyword for configuring route stateless in PHP, YAML and XML configurations.
* added the "hosts" option to be able to configure the host per locale.
* added `RequestContext::fromUri()` to ease building the default context
5.0.0
-----
* removed `PhpGeneratorDumper` and `PhpMatcherDumper`
* removed `generator_base_class`, `generator_cache_class`, `matcher_base_class` and `matcher_cache_class` router options
* `Serializable` implementing methods for `Route` and `CompiledRoute` are final
* removed referencing service route loaders with a single colon
* Removed `ServiceRouterLoader` and `ObjectRouteLoader`.
4.4.0
-----
* Deprecated `ServiceRouterLoader` in favor of `ContainerLoader`.
* Deprecated `ObjectRouteLoader` in favor of `ObjectLoader`.
* Added a way to exclude patterns of resources from being imported by the `import()` method
4.3.0
-----
* added `CompiledUrlMatcher` and `CompiledUrlMatcherDumper`
* added `CompiledUrlGenerator` and `CompiledUrlGeneratorDumper`
* deprecated `PhpGeneratorDumper` and `PhpMatcherDumper`
* deprecated `generator_base_class`, `generator_cache_class`, `matcher_base_class` and `matcher_cache_class` router options
* `Serializable` implementing methods for `Route` and `CompiledRoute` are marked as `@internal` and `@final`.
Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible
with the new serialization methods in PHP 7.4.
* exposed `utf8` Route option, defaults "locale" and "format" in configuration loaders and configurators
* added support for invokable service route loaders
4.2.0
-----
* added fallback to cultureless locale for internationalized routes
4.0.0
-----
* dropped support for using UTF-8 route patterns without using the `utf8` option
* dropped support for using UTF-8 route requirements without using the `utf8` option
3.4.0
-----
* Added `NoConfigurationException`.
* Added the possibility to define a prefix for all routes of a controller via @Route(name="prefix_")
* Added support for prioritized routing loaders.
* Add matched and default parameters to redirect responses
* Added support for a `controller` keyword for configuring route controllers in YAML and XML configurations.
3.3.0
-----
* [DEPRECATION] Class parameters have been deprecated and will be removed in 4.0.
* router.options.generator_class
* router.options.generator_base_class
* router.options.generator_dumper_class
* router.options.matcher_class
* router.options.matcher_base_class
* router.options.matcher_dumper_class
* router.options.matcher.cache_class
* router.options.generator.cache_class
3.2.0
-----
* Added support for `bool`, `int`, `float`, `string`, `list` and `map` defaults in XML configurations.
* Added support for UTF-8 requirements
2.8.0
-----
* allowed specifying a directory to recursively load all routing configuration files it contains
* Added ObjectRouteLoader and ServiceRouteLoader that allow routes to be loaded
by calling a method on an object/service.
* [DEPRECATION] Deprecated the hardcoded value for the `$referenceType` argument of the `UrlGeneratorInterface::generate` method.
Use the constants defined in the `UrlGeneratorInterface` instead.
Before:
```php
$router->generate('blog_show', ['slug' => 'my-blog-post'], true);
```
After:
```php
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
$router->generate('blog_show', ['slug' => 'my-blog-post'], UrlGeneratorInterface::ABSOLUTE_URL);
```
2.5.0
-----
* [DEPRECATION] The `ApacheMatcherDumper` and `ApacheUrlMatcher` were deprecated and
will be removed in Symfony 3.0, since the performance gains were minimal and
it's hard to replicate the behavior of PHP implementation.
2.3.0
-----
* added RequestContext::getQueryString()
2.2.0
-----
* [DEPRECATION] Several route settings have been renamed (the old ones will be removed in 3.0):
* The `pattern` setting for a route has been deprecated in favor of `path`
* The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings
Before:
```yaml
article_edit:
pattern: /article/{id}
requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' }
```
```xml
<route id="article_edit" pattern="/article/{id}">
<requirement key="_method">POST|PUT</requirement>
<requirement key="_scheme">https</requirement>
<requirement key="id">\d+</requirement>
</route>
```
```php
$route = new Route();
$route->setPattern('/article/{id}');
$route->setRequirement('_method', 'POST|PUT');
$route->setRequirement('_scheme', 'https');
```
After:
```yaml
article_edit:
path: /article/{id}
methods: [POST, PUT]
schemes: https
requirements: { 'id': '\d+' }
```
```xml
<route id="article_edit" pattern="/article/{id}" methods="POST PUT" schemes="https">
<requirement key="id">\d+</requirement>
</route>
```
```php
$route = new Route();
$route->setPath('/article/{id}');
$route->setMethods(['POST', 'PUT']);
$route->setSchemes('https');
```
* [BC BREAK] RouteCollection does not behave like a tree structure anymore but as
a flat array of Routes. So when using PHP to build the RouteCollection, you must
make sure to add routes to the sub-collection before adding it to the parent
collection (this is not relevant when using YAML or XML for Route definitions).
Before:
```php
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$rootCollection->addCollection($subCollection);
$subCollection->add('foo', new Route('/foo'));
```
After:
```php
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$subCollection->add('foo', new Route('/foo'));
$rootCollection->addCollection($subCollection);
```
Also one must call `addCollection` from the bottom to the top hierarchy.
So the correct sequence is the following (and not the reverse):
```php
$childCollection->addCollection($grandchildCollection);
$rootCollection->addCollection($childCollection);
```
* [DEPRECATION] The methods `RouteCollection::getParent()` and `RouteCollection::getRoot()`
have been deprecated and will be removed in Symfony 2.3.
* [BC BREAK] Misusing the `RouteCollection::addPrefix` method to add defaults, requirements
or options without adding a prefix is not supported anymore. So if you called `addPrefix`
with an empty prefix or `/` only (both have no relevance), like
`addPrefix('', $defaultsArray, $requirementsArray, $optionsArray)`
you need to use the new dedicated methods `addDefaults($defaultsArray)`,
`addRequirements($requirementsArray)` or `addOptions($optionsArray)` instead.
* [DEPRECATION] The `$options` parameter to `RouteCollection::addPrefix()` has been deprecated
because adding options has nothing to do with adding a path prefix. If you want to add options
to all child routes of a RouteCollection, you can use `addOptions()`.
* [DEPRECATION] The method `RouteCollection::getPrefix()` has been deprecated
because it suggested that all routes in the collection would have this prefix, which is
not necessarily true. On top of that, since there is no tree structure anymore, this method
is also useless. Don't worry about performance, prefix optimization for matching is still done
in the dumper, which was also improved in 2.2.0 to find even more grouping possibilities.
* [DEPRECATION] `RouteCollection::addCollection(RouteCollection $collection)` should now only be
used with a single parameter. The other params `$prefix`, `$default`, `$requirements` and `$options`
will still work, but have been deprecated. The `addPrefix` method should be used for this
use-case instead.
Before: `$parentCollection->addCollection($collection, '/prefix', [...], [...])`
After:
```php
$collection->addPrefix('/prefix', [...], [...]);
$parentCollection->addCollection($collection);
```
* added support for the method default argument values when defining a @Route
* Adjacent placeholders without separator work now, e.g. `/{x}{y}{z}.{_format}`.
* Characters that function as separator between placeholders are now whitelisted
to fix routes with normal text around a variable, e.g. `/prefix{var}suffix`.
* [BC BREAK] The default requirement of a variable has been changed slightly.
Previously it disallowed the previous and the next char around a variable. Now
it disallows the slash (`/`) and the next char. Using the previous char added
no value and was problematic because the route `/index.{_format}` would be
matched by `/index.ht/ml`.
* The default requirement now uses possessive quantifiers when possible which
improves matching performance by up to 20% because it prevents backtracking
when it's not needed.
* The ConfigurableRequirementsInterface can now also be used to disable the requirements
check on URL generation completely by calling `setStrictRequirements(null)`. It
improves performance in production environment as you should know that params always
pass the requirements (otherwise it would break your link anyway).
* There is no restriction on the route name anymore. So non-alphanumeric characters
are now also allowed.
* [BC BREAK] `RouteCompilerInterface::compile(Route $route)` was made static
(only relevant if you implemented your own RouteCompiler).
* Added possibility to generate relative paths and network paths in the UrlGenerator, e.g.
"../parent-file" and "//example.com/dir/file". The third parameter in
`UrlGeneratorInterface::generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)`
now accepts more values and you should use the constants defined in `UrlGeneratorInterface` for
claritiy. The old method calls with a Boolean parameter will continue to work because they
equal the signature using the constants.
2.1.0
-----
* added RequestMatcherInterface
* added RequestContext::fromRequest()
* the UrlMatcher does not throw a \LogicException anymore when the required
scheme is not the current one
* added TraceableUrlMatcher
* added the possibility to define options, default values and requirements
for placeholders in prefix, including imported routes
* added RouterInterface::getRouteCollection
* [BC BREAK] the UrlMatcher urldecodes the route parameters only once, they
were decoded twice before. Note that the `urldecode()` calls have been
changed for a single `rawurldecode()` in order to support `+` for input
paths.
* added RouteCollection::getRoot method to retrieve the root of a
RouteCollection tree
* [BC BREAK] made RouteCollection::setParent private which could not have
been used anyway without creating inconsistencies
* [BC BREAK] RouteCollection::remove also removes a route from parent
collections (not only from its children)
* added ConfigurableRequirementsInterface that allows to disable exceptions
(and generate empty URLs instead) when generating a route with an invalid
parameter value
================================================
FILE: CompiledRoute.php
================================================
<?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;
/**
* CompiledRoutes are returned by the RouteCompiler class.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class CompiledRoute implements \Serializable
{
/**
* @param string $staticPrefix The static prefix of the compiled route
* @param string $regex The regular expression to use to match this route
* @param array $tokens An array of tokens to use to generate URL for this route
* @param array $pathVariables An array of path variables
* @param string|null $hostRegex Host regex
* @param array $hostTokens Host tokens
* @param array $hostVariables An array of host variables
* @param array $variables An array of variables (variables defined in the path and in the host patterns)
*/
public function __construct(
private string $staticPrefix,
private string $regex,
private array $tokens,
private array $pathVariables,
private ?string $hostRegex = null,
private array $hostTokens = [],
private array $hostVariables = [],
private array $variables = [],
) {
}
public function __serialize(): array
{
return [
'vars' => $this->variables,
'path_prefix' => $this->staticPrefix,
'path_regex' => $this->regex,
'path_tokens' => $this->tokens,
'path_vars' => $this->pathVariables,
'host_regex' => $this->hostRegex,
'host_tokens' => $this->hostTokens,
'host_vars' => $this->hostVariables,
];
}
/**
* @internal
*/
final public function serialize(): string
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
public function __unserialize(array $data): void
{
$this->variables = $data['vars'];
$this->staticPrefix = $data['path_prefix'];
$this->regex = $data['path_regex'];
$this->tokens = $data['path_tokens'];
$this->pathVariables = $data['path_vars'];
$this->hostRegex = $data['host_regex'];
$this->hostTokens = $data['host_tokens'];
$this->hostVariables = $data['host_vars'];
}
/**
* @internal
*/
final public function unserialize(string $serialized): void
{
$this->__unserialize(unserialize($serialized, ['allowed_classes' => false]));
}
/**
* Returns the static prefix.
*/
public function getStaticPrefix(): string
{
return $this->staticPrefix;
}
/**
* Returns the regex.
*/
public function getRegex(): string
{
return $this->regex;
}
/**
* Returns the host regex.
*/
public function getHostRegex(): ?string
{
return $this->hostRegex;
}
/**
* Returns the tokens.
*/
public function getTokens(): array
{
return $this->tokens;
}
/**
* Returns the host tokens.
*/
public function getHostTokens(): array
{
return $this->hostTokens;
}
/**
* Returns the variables.
*/
public function getVariables(): array
{
return $this->variables;
}
/**
* Returns the path variables.
*/
public function getPathVariables(): array
{
return $this->pathVariables;
}
/**
* Returns the host variables.
*/
public function getHostVariables(): array
{
return $this->hostVariables;
}
}
================================================
FILE: DependencyInjection/AddExpressionLanguageProvidersPass.php
================================================
<?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\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Registers the expression language providers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class AddExpressionLanguageProvidersPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
if (!$container->has('router.default')) {
return;
}
$definition = $container->findDefinition('router.default');
foreach ($container->findTaggedServiceIds('routing.expression_language_provider', true) as $id => $attributes) {
$definition->addMethodCall('addExpressionLanguageProvider', [new Reference($id)]);
}
}
}
================================================
FILE: DependencyInjection/RoutingControllerPass.php
================================================
<?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\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
final class RoutingControllerPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
public function process(ContainerBuilder $container): void
{
if (!$container->hasDefinition('routing.loader.attribute.services')) {
return;
}
$resolve = $container->getParameterBag()->resolveValue(...);
$taggedClasses = [];
foreach ($this->findAndSortTaggedServices('routing.controller', $container) as $id) {
$taggedClasses[$resolve($container->getDefinition($id)->getClass())] = true;
}
$container->getDefinition('routing.loader.attribute.services')
->replaceArgument(0, array_keys($taggedClasses));
}
}
================================================
FILE: DependencyInjection/RoutingResolverPass.php
================================================
<?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\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Adds tagged routing.loader services to routing.resolver service.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class RoutingResolverPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
public function process(ContainerBuilder $container): void
{
if (false === $container->hasDefinition('routing.resolver')) {
return;
}
$definition = $container->getDefinition('routing.resolver');
foreach ($this->findAndSortTaggedServices('routing.loader', $container) as $id) {
$definition->addMethodCall('addLoader', [new Reference($id)]);
}
}
}
================================================
FILE: Exception/ExceptionInterface.php
================================================
<?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\Exception;
/**
* ExceptionInterface.
*
* @author Alexandre Salomé <alexandre.salome@gmail.com>
*/
interface ExceptionInterface extends \Throwable
{
}
================================================
FILE: Exception/InvalidArgumentException.php
================================================
<?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\Exception;
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
================================================
FILE: Exception/InvalidParameterException.php
================================================
<?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\Exception;
/**
* Exception thrown when a parameter is not valid.
*
* @author Alexandre Salomé <alexandre.salome@gmail.com>
*/
class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface
{
}
================================================
FILE: Exception/LogicException.php
================================================
<?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\Exception;
class LogicException extends \LogicException
{
}
================================================
FILE: Exception/MethodNotAllowedException.php
================================================
<?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\Exception;
/**
* The resource was found but the request method is not allowed.
*
* This exception should trigger an HTTP 405 response in your application code.
*
* @author Kris Wallsmith <kris@symfony.com>
*/
class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface
{
protected array $allowedMethods = [];
/**
* @param string[] $allowedMethods
*/
public function __construct(array $allowedMethods, string $message = '', int $code = 0, ?\Throwable $previous = null)
{
$this->allowedMethods = array_map('strtoupper', $allowedMethods);
parent::__construct($message, $code, $previous);
}
/**
* Gets the allowed HTTP methods.
*
* @return string[]
*/
public function getAllowedMethods(): array
{
return $this->allowedMethods;
}
}
================================================
FILE: Exception/MissingMandatoryParametersException.php
================================================
<?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\Exception;
/**
* Exception thrown when a route cannot be generated because of missing
* mandatory parameters.
*
* @author Alexandre Salomé <alexandre.salome@gmail.com>
*/
class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface
{
private string $routeName = '';
private array $missingParameters = [];
/**
* @param string[] $missingParameters
*/
public function __construct(string $routeName = '', array $missingParameters = [], int $code = 0, ?\Throwable $previous = null)
{
$this->routeName = $routeName;
$this->missingParameters = $missingParameters;
$message = \sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', $missingParameters), $routeName);
parent::__construct($message, $code, $previous);
}
/**
* @return string[]
*/
public function getMissingParameters(): array
{
return $this->missingParameters;
}
public function getRouteName(): string
{
return $this->routeName;
}
}
================================================
FILE: Exception/NoConfigurationException.php
================================================
<?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\Exception;
/**
* Exception thrown when no routes are configured.
*
* @author Yonel Ceruto <yonelceruto@gmail.com>
*/
class NoConfigurationException extends ResourceNotFoundException
{
}
================================================
FILE: Exception/ResourceNotFoundException.php
================================================
<?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\Exception;
/**
* The resource was not found.
*
* This exception should trigger an HTTP 404 response in your application code.
*
* @author Kris Wallsmith <kris@symfony.com>
*/
class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface
{
}
================================================
FILE: Exception/RouteCircularReferenceException.php
================================================
<?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\Exception;
class RouteCircularReferenceException extends RuntimeException
{
public function __construct(string $routeId, array $path)
{
parent::__construct(\sprintf('Circular reference detected for route "%s", path: "%s".', $routeId, implode(' -> ', $path)));
}
}
================================================
FILE: Exception/RouteNotFoundException.php
================================================
<?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\Exception;
/**
* Exception thrown when a route does not exist.
*
* @author Alexandre Salomé <alexandre.salome@gmail.com>
*/
class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface
{
}
================================================
FILE: Exception/RuntimeException.php
================================================
<?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\Exception;
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
================================================
FILE: Generator/CompiledUrlGenerator.php
================================================
<?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\Generator;
use Psr\Log\LoggerInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\RequestContext;
/**
* Generates URLs based on rules dumped by CompiledUrlGeneratorDumper.
*/
class CompiledUrlGenerator extends UrlGenerator
{
private array $compiledRoutes = [];
public function __construct(
array $compiledRoutes,
RequestContext $context,
?LoggerInterface $logger = null,
private ?string $defaultLocale = null,
) {
$this->compiledRoutes = $compiledRoutes;
$this->context = $context;
$this->logger = $logger;
}
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string
{
$locale = $parameters['_locale']
?? $this->context->getParameter('_locale')
?: $this->defaultLocale;
if (null !== $locale) {
do {
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
$name .= '.'.$locale;
break;
}
} while (false !== $locale = strstr($locale, '_', true));
}
if (!isset($this->compiledRoutes[$name])) {
throw new RouteNotFoundException(\sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
}
[$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes, $deprecations] = $this->compiledRoutes[$name] + [6 => []];
foreach ($deprecations as $deprecation) {
trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
}
if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
if (!\in_array('_locale', $variables, true)) {
unset($parameters['_locale']);
} elseif (!isset($parameters['_locale'])) {
$parameters['_locale'] = $defaults['_locale'];
}
}
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
}
}
================================================
FILE: Generator/ConfigurableRequirementsInterface.php
================================================
<?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\Generator;
/**
* ConfigurableRequirementsInterface must be implemented by URL generators that
* can be configured whether an exception should be generated when the parameters
* do not match the requirements. It is also possible to disable the requirements
* check for URL generation completely.
*
* The possible configurations and use-cases:
* - setStrictRequirements(true): Throw an exception for mismatching requirements. This
* is mostly useful in development environment.
* - setStrictRequirements(false): Don't throw an exception but return an empty string as URL for
* mismatching requirements and log the problem. Useful when you cannot control all
* params because they come from third party libs but don't want to have a 404 in
* production environment. It should log the mismatch so one can review it.
* - setStrictRequirements(null): Return the URL with the given parameters without
* checking the requirements at all. When generating a URL you should either trust
* your params or you validated them beforehand because otherwise it would break your
* link anyway. So in production environment you should know that params always pass
* the requirements. Thus this option allows to disable the check on URL generation for
* performance reasons (saving a preg_match for each requirement every time a URL is
* generated).
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
*/
interface ConfigurableRequirementsInterface
{
/**
* Enables or disables the exception on incorrect parameters.
* Passing null will deactivate the requirements check completely.
*/
public function setStrictRequirements(?bool $enabled): void;
/**
* Returns whether to throw an exception on incorrect parameters.
* Null means the requirements check is deactivated completely.
*/
public function isStrictRequirements(): ?bool;
}
================================================
FILE: Generator/Dumper/CompiledUrlGeneratorDumper.php
================================================
<?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\Generator\Dumper;
use Symfony\Component\Routing\Exception\RouteCircularReferenceException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
/**
* CompiledUrlGeneratorDumper creates a PHP array to be used with CompiledUrlGenerator.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
* @author Nicolas Grekas <p@tchwork.com>
*/
class CompiledUrlGeneratorDumper extends GeneratorDumper
{
public function getCompiledRoutes(): array
{
$compiledRoutes = [];
foreach ($this->getRoutes()->all() as $name => $route) {
$compiledRoute = $route->compile();
$compiledRoutes[$name] = [
$compiledRoute->getVariables(),
$route->getDefaults(),
$route->getRequirements(),
$compiledRoute->getTokens(),
$compiledRoute->getHostTokens(),
$route->getSchemes(),
[],
];
}
return $compiledRoutes;
}
public function getCompiledAliases(): array
{
$routes = $this->getRoutes();
$compiledAliases = [];
foreach ($routes->getAliases() as $name => $alias) {
$deprecations = $alias->isDeprecated() ? [$alias->getDeprecation($name)] : [];
$currentId = $alias->getId();
$visited = [];
while (null !== $alias = $routes->getAlias($currentId) ?? null) {
if (false !== $searchKey = array_search($currentId, $visited)) {
$visited[] = $currentId;
throw new RouteCircularReferenceException($currentId, \array_slice($visited, $searchKey));
}
if ($alias->isDeprecated()) {
$deprecations[] = $deprecation = $alias->getDeprecation($currentId);
trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
}
$visited[] = $currentId;
$currentId = $alias->getId();
}
if (null === $target = $routes->get($currentId)) {
throw new RouteNotFoundException(\sprintf('Target route "%s" for alias "%s" does not exist.', $currentId, $name));
}
$compiledTarget = $target->compile();
$defaults = $target->getDefaults();
if (isset($defaults['_locale']) && str_ends_with($name, '.'.$defaults['_locale'])) {
$defaults['_canonical_route'] = substr($name, 0, -\strlen($defaults['_locale']) - 1);
}
$compiledAliases[$name] = [
$compiledTarget->getVariables(),
$defaults,
$target->getRequirements(),
$compiledTarget->getTokens(),
$compiledTarget->getHostTokens(),
$target->getSchemes(),
$deprecations,
];
}
return $compiledAliases;
}
public function dump(array $options = []): string
{
return <<<EOF
<?php
// This file has been auto-generated by the Symfony Routing Component.
return [{$this->generateDeclaredRoutes()}
];
EOF;
}
/**
* Generates PHP code representing an array of defined routes
* together with the routes properties (e.g. requirements).
*/
private function generateDeclaredRoutes(): string
{
$routes = '';
foreach ($this->getCompiledRoutes() as $name => $properties) {
$routes .= \sprintf("\n '%s' => %s,", $name, CompiledUrlMatcherDumper::export($properties));
}
foreach ($this->getCompiledAliases() as $alias => $properties) {
$routes .= \sprintf("\n '%s' => %s,", $alias, CompiledUrlMatcherDumper::export($properties));
}
return $routes;
}
}
================================================
FILE: Generator/Dumper/GeneratorDumper.php
================================================
<?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\Generator\Dumper;
use Symfony\Component\Routing\RouteCollection;
/**
* GeneratorDumper is the base class for all built-in generator dumpers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class GeneratorDumper implements GeneratorDumperInterface
{
public function __construct(
private RouteCollection $routes,
) {
}
public function getRoutes(): RouteCollection
{
return $this->routes;
}
}
================================================
FILE: Generator/Dumper/GeneratorDumperInterface.php
================================================
<?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\Generator\Dumper;
use Symfony\Component\Routing\RouteCollection;
/**
* GeneratorDumperInterface is the interface that all generator dumper classes must implement.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface GeneratorDumperInterface
{
/**
* Dumps a set of routes to a string representation of executable code
* that can then be used to generate a URL of such a route.
*/
public function dump(array $options = []): string;
/**
* Gets the routes to dump.
*/
public function getRoutes(): RouteCollection;
}
================================================
FILE: Generator/UrlGenerator.php
================================================
<?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\Generator;
use Psr\Log\LoggerInterface;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
/**
* UrlGenerator can generate a URL or a path for any route in the RouteCollection
* based on the passed parameters.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
*/
class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface
{
private const QUERY_FRAGMENT_DECODED = [
// RFC 3986 explicitly allows those in the query/fragment to reference other URIs unencoded
'%2F' => '/',
'%252F' => '%2F',
'%3F' => '?',
// reserved chars that have no special meaning for HTTP URIs in a query or fragment
// this excludes esp. "&", "=" and also "+" because PHP would treat it as a space (form-encoded)
'%40' => '@',
'%3A' => ':',
'%21' => '!',
'%3B' => ';',
'%2C' => ',',
'%2A' => '*',
];
protected ?bool $strictRequirements = true;
/**
* This array defines the characters (besides alphanumeric ones) that will not be percent-encoded in the path segment of the generated URL.
*
* PHP's rawurlencode() encodes all chars except "a-zA-Z0-9-._~" according to RFC 3986. But we want to allow some chars
* to be used in their literal form (reasons below). Other chars inside the path must of course be encoded, e.g.
* "?" and "#" (would be interpreted wrongly as query and fragment identifier),
* "'" and """ (are used as delimiters in HTML).
*/
protected array $decodedChars = [
// the slash can be used to designate a hierarchical structure and we want allow using it with this meaning
// some webservers don't allow the slash in encoded form in the path for security reasons anyway
// see http://stackoverflow.com/questions/4069002/http-400-if-2f-part-of-get-url-in-jboss
'%2F' => '/',
'%252F' => '%2F',
// the following chars are general delimiters in the URI specification but have only special meaning in the authority component
// so they can safely be used in the path in unencoded form
'%40' => '@',
'%3A' => ':',
// these chars are only sub-delimiters that have no predefined meaning and can therefore be used literally
// so URI producing applications can use these chars to delimit subcomponents in a path segment without being encoded for better readability
'%3B' => ';',
'%2C' => ',',
'%3D' => '=',
'%2B' => '+',
'%21' => '!',
'%2A' => '*',
'%7C' => '|',
];
public function __construct(
protected RouteCollection $routes,
protected RequestContext $context,
protected ?LoggerInterface $logger = null,
private ?string $defaultLocale = null,
) {
}
public function setContext(RequestContext $context): void
{
$this->context = $context;
}
public function getContext(): RequestContext
{
return $this->context;
}
public function setStrictRequirements(?bool $enabled): void
{
$this->strictRequirements = $enabled;
}
public function isStrictRequirements(): ?bool
{
return $this->strictRequirements;
}
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string
{
$route = null;
$locale = $parameters['_locale'] ?? $this->context->getParameter('_locale') ?: $this->defaultLocale;
if (null !== $locale) {
do {
$route = $this->routes->get($name.'.'.$locale);
if ($route && ($route->getDefault('_canonical_route') === $name || $this->routes->getAlias($name.'.'.$locale))) {
break;
}
} while (false !== $locale = strstr($locale, '_', true));
}
if (null === $route ??= $this->routes->get($name)) {
throw new RouteNotFoundException(\sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
}
// the Route has a cache of its own and is not recompiled as long as it does not get modified
$compiledRoute = $route->compile();
$defaults = $route->getDefaults();
$variables = $compiledRoute->getVariables();
if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
if (!\in_array('_locale', $variables, true)) {
unset($parameters['_locale']);
} elseif (!isset($parameters['_locale'])) {
$parameters['_locale'] = $defaults['_locale'];
}
}
return $this->doGenerate($variables, $defaults, $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
}
/**
* @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
* it does not match the requirement
*/
protected function doGenerate(array $variables, array $defaults, array $requirements, array $tokens, array $parameters, string $name, int $referenceType, array $hostTokens, array $requiredSchemes = []): string
{
$queryParameters = [];
if (isset($parameters['_query'])) {
if (\is_array($parameters['_query'])) {
$queryParameters = $parameters['_query'];
unset($parameters['_query']);
} else {
throw new InvalidParameterException('Parameter "_query" must be an array of query parameters.');
}
}
$variables = array_flip($variables);
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
// all params must be given
if ($diff = array_diff_key($variables, $mergedParams)) {
throw new MissingMandatoryParametersException($name, array_keys($diff));
}
$url = '';
$optional = true;
$message = 'Parameter "{parameter}" for route "{route}" must match "{expected}" ("{given}" given) to generate a corresponding URL.';
foreach ($tokens as $token) {
if ('variable' === $token[0]) {
$varName = $token[3];
// variable is not important by default
$important = $token[5] ?? false;
if (!$optional || $important || !\array_key_exists($varName, $defaults) || (null !== $mergedParams[$varName] && (string) $mergedParams[$varName] !== (string) $defaults[$varName])) {
// check requirement (while ignoring look-around patterns)
if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\(\?(?:=|<=|!|<!)((?:[^()\\\\]+|\\\\.|\((?1)\))*)\)/', '', $token[2]).'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]] ?? '')) {
if ($this->strictRequirements) {
throw new InvalidParameterException(strtr($message, ['{parameter}' => $varName, '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$varName]]));
}
$this->logger?->error($message, ['parameter' => $varName, 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$varName]]);
return '';
}
$url = $token[1].$mergedParams[$varName].$url;
$optional = false;
}
} else {
// static text
$url = $token[1].$url;
$optional = false;
}
}
if ('' === $url) {
$url = '/';
}
// the contexts base URL is already encoded (see Symfony\Component\HttpFoundation\Request)
$url = strtr(rawurlencode($url), $this->decodedChars);
// the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
// so we need to encode them as they are not used for this purpose here
// otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
$url = strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/']);
if (str_ends_with($url, '/..')) {
$url = substr($url, 0, -2).'%2E%2E';
} elseif (str_ends_with($url, '/.')) {
$url = substr($url, 0, -1).'%2E';
}
$schemeAuthority = '';
$host = $this->context->getHost();
$scheme = $this->context->getScheme();
if ($requiredSchemes) {
if (!\in_array($scheme, $requiredSchemes, true)) {
$referenceType = self::ABSOLUTE_URL;
$scheme = current($requiredSchemes);
}
}
if ($hostTokens) {
$routeHost = '';
foreach ($hostTokens as $token) {
if ('variable' === $token[0]) {
// check requirement (while ignoring look-around patterns)
if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\(\?(?:=|<=|!|<!)((?:[^()\\\\]+|\\\\.|\((?1)\))*)\)/', '', $token[2]).'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
if ($this->strictRequirements) {
throw new InvalidParameterException(strtr($message, ['{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]]));
}
$this->logger?->error($message, ['parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]]);
return '';
}
$routeHost = $token[1].$mergedParams[$token[3]].$routeHost;
} else {
$routeHost = $token[1].$routeHost;
}
}
if ($routeHost !== $host) {
$host = $routeHost;
if (self::ABSOLUTE_URL !== $referenceType) {
$referenceType = self::NETWORK_PATH;
}
}
}
if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) {
if ('' !== $host || ('' !== $scheme && 'http' !== $scheme && 'https' !== $scheme)) {
$port = '';
if ('http' === $scheme && 80 !== $this->context->getHttpPort()) {
$port = ':'.$this->context->getHttpPort();
} elseif ('https' === $scheme && 443 !== $this->context->getHttpsPort()) {
$port = ':'.$this->context->getHttpsPort();
}
$schemeAuthority = self::NETWORK_PATH === $referenceType || '' === $scheme ? '//' : "$scheme://";
$schemeAuthority .= $host.$port;
}
}
if (self::RELATIVE_PATH === $referenceType) {
$url = self::getRelativePath($this->context->getPathInfo(), $url);
} else {
$url = $schemeAuthority.$this->context->getBaseUrl().$url;
}
// add a query string if needed
$extra = array_udiff_assoc(array_diff_key($parameters, $variables), $defaults, static fn ($a, $b) => $a == $b ? 0 : 1);
$extra = array_replace($extra, $queryParameters);
array_walk_recursive($extra, $caster = static function (&$v) use (&$caster) {
if (\is_object($v)) {
if ($vars = get_object_vars($v)) {
array_walk_recursive($vars, $caster);
$v = $vars;
} elseif ($v instanceof \Stringable) {
$v = (string) $v;
}
}
});
// extract fragment
$fragment = $defaults['_fragment'] ?? '';
if (isset($extra['_fragment'])) {
$fragment = $extra['_fragment'];
unset($extra['_fragment']);
}
if ($extra && $query = http_build_query($extra, '', '&', \PHP_QUERY_RFC3986)) {
$url .= '?'.strtr($query, self::QUERY_FRAGMENT_DECODED);
}
if ('' !== $fragment) {
$url .= '#'.strtr(rawurlencode($fragment), self::QUERY_FRAGMENT_DECODED);
}
return $url;
}
/**
* Returns the target path as relative reference from the base path.
*
* Only the URIs path component (no schema, host etc.) is relevant and must be given, starting with a slash.
* Both paths must be absolute and not contain relative parts.
* Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
* Furthermore, they can be used to reduce the link size in documents.
*
* Example target paths, given a base path of "/a/b/c/d":
* - "/a/b/c/d" -> ""
* - "/a/b/c/" -> "./"
* - "/a/b/" -> "../"
* - "/a/b/c/other" -> "other"
* - "/a/x/y" -> "../../x/y"
*
* @param string $basePath The base path
* @param string $targetPath The target path
*/
public static function getRelativePath(string $basePath, string $targetPath): string
{
if ($basePath === $targetPath) {
return '';
}
$sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);
$targetDirs = explode('/', isset($targetPath[0]) && '/' === $targetPath[0] ? substr($targetPath, 1) : $targetPath);
array_pop($sourceDirs);
$targetFile = array_pop($targetDirs);
foreach ($sourceDirs as $i => $dir) {
if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
unset($sourceDirs[$i], $targetDirs[$i]);
} else {
break;
}
}
$targetDirs[] = $targetFile;
$path = str_repeat('../', \count($sourceDirs)).implode('/', $targetDirs);
// A reference to the same base directory or an empty subdirectory must be prefixed with "./".
// This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
// as the first segment of a relative-path reference, as it would be mistaken for a scheme name
// (see http://tools.ietf.org/html/rfc3986#section-4.2).
return '' === $path || '/' === $path[0]
|| false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
? "./$path" : $path;
}
}
================================================
FILE: Generator/UrlGeneratorInterface.php
================================================
<?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\Generator;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\RequestContextAwareInterface;
/**
* UrlGeneratorInterface is the interface that all URL generator classes must implement.
*
* The constants in this interface define the different types of resource references that
* are declared in RFC 3986: http://tools.ietf.org/html/rfc3986
* We are using the term "URL" instead of "URI" as this is more common in web applications
* and we do not need to distinguish them as the difference is mostly semantical and
* less technical. Generating URIs, i.e. representation-independent resource identifiers,
* is also possible.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
*/
interface UrlGeneratorInterface extends RequestContextAwareInterface
{
/**
* Generates an absolute URL, e.g. "http://example.com/dir/file".
*/
public const ABSOLUTE_URL = 0;
/**
* Generates an absolute path, e.g. "/dir/file".
*/
public const ABSOLUTE_PATH = 1;
/**
* Generates a relative path based on the current request path, e.g. "../parent-file".
*
* @see UrlGenerator::getRelativePath()
*/
public const RELATIVE_PATH = 2;
/**
* Generates a network path, e.g. "//example.com/dir/file".
* Such reference reuses the current scheme but specifies the host.
*/
public const NETWORK_PATH = 3;
/**
* Generates a URL or path for a specific route based on the given parameters.
*
* Parameters that reference placeholders in the route pattern will substitute them in the
* path or host. Extra params are added as query string to the URL.
*
* When the passed reference type cannot be generated for the route because it requires a different
* host or scheme than the current one, the method will return a more comprehensive reference
* that includes the required params. For example, when you call this method with $referenceType = ABSOLUTE_PATH
* but the route requires the https scheme whereas the current scheme is http, it will instead return an
* ABSOLUTE_URL with the https scheme and the current host. This makes sure the generated URL matches
* the route in any case.
*
* If there is no route with the given name, the generator must throw the RouteNotFoundException.
*
* The special parameter _fragment will be used as the document fragment suffixed to the final URL.
*
* @throws RouteNotFoundException If the named route doesn't exist
* @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
* @throws InvalidParameterException When a parameter value for a placeholder is not correct because
* it does not match the requirement
*/
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string;
}
================================================
FILE: LICENSE
================================================
Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: Loader/AttributeClassLoader.php
================================================
<?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\Loader\LoaderInterface;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
use Symfony\Component\Config\Resource\ReflectionClassResource;
use Symfony\Component\Routing\Attribute\DeprecatedAlias;
use Symfony\Component\Routing\Attribute\Route as RouteAttribute;
use Symfony\Component\Routing\Exception\InvalidArgumentException;
use Symfony\Component\Routing\Exception\LogicException;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* AttributeClassLoader loads routing information from a PHP class and its methods.
*
* You need to define an implementation for the configureRoute() method. Most of the
* time, this method should define some PHP callable to be called for the route
* (a controller in MVC speak).
*
* The #[Route] attribute can be set on the class (for global parameters),
* and on each method.
*
* The #[Route] attribute main value is the route path. The attribute also
* recognizes several parameters: requirements, options, defaults, schemes,
* methods, host, and name. The name parameter is mandatory.
* Here is an example of how you should be able to use it:
*
* #[Route('/Blog')]
* class Blog
* {
* #[Route('/', name: 'blog_index')]
* public function index()
* {
* }
* #[Route('/{id}', name: 'blog_post', requirements: ["id" => '\d+'])]
* public function show()
* {
* }
* }
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Alexander M. Turek <me@derrabus.de>
* @author Alexandre Daubois <alex.daubois@gmail.com>
*/
abstract class AttributeClassLoader implements LoaderInterface
{
private string $routeAttributeClass = RouteAttribute::class;
protected int $defaultRouteIndex = 0;
public function __construct(
protected readonly ?string $env = null,
) {
}
/**
* Sets the attribute class to read route properties from.
*/
public function setRouteAttributeClass(string $class): void
{
$this->routeAttributeClass = $class;
}
/**
* @throws \InvalidArgumentException When route can't be parsed
*/
public function load(mixed $class, ?string $type = null): RouteCollection
{
if (!class_exists($class)) {
throw new \InvalidArgumentException(\sprintf('Class "%s" does not exist.', $class));
}
$class = new \ReflectionClass($class);
if ($class->isAbstract()) {
throw new \InvalidArgumentException(\sprintf('Attributes from class "%s" cannot be read as it is abstract.', $class->getName()));
}
$globals = $this->getGlobals($class);
$collection = new RouteCollection();
$collection->addResource(new ReflectionClassResource($class));
if ($globals['env'] && !\in_array($this->env, $globals['env'], true)) {
return $collection;
}
$fqcnAlias = false;
if (!$class->hasMethod('__invoke')) {
foreach ($this->getAttributes($class) as $attr) {
if ($attr->aliases) {
throw new InvalidArgumentException(\sprintf('Route aliases cannot be used on non-invokable class "%s".', $class->getName()));
}
}
}
foreach ($class->getMethods() as $method) {
$this->defaultRouteIndex = 0;
$routeNamesBefore = array_keys($collection->all());
foreach ($this->getAttributes($method) as $attr) {
$this->addRoute($collection, $attr, $globals, $class, $method);
if ('__invoke' === $method->name) {
$fqcnAlias = true;
}
}
if (1 === $collection->count() - \count($routeNamesBefore)) {
$newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore));
if ($newRouteName !== $aliasName = \sprintf('%s::%s', $class->name, $method->name)) {
$collection->addAlias($aliasName, $newRouteName);
}
}
}
if (0 === $collection->count() && $class->hasMethod('__invoke')) {
$globals = $this->resetGlobals();
foreach ($this->getAttributes($class) as $attr) {
$this->addRoute($collection, $attr, $globals, $class, $class->getMethod('__invoke'));
$fqcnAlias = true;
}
}
if ($fqcnAlias && 1 === $collection->count()) {
$invokeRouteName = key($collection->all());
if ($invokeRouteName !== $class->name) {
$collection->addAlias($class->name, $invokeRouteName);
}
if ($invokeRouteName !== $aliasName = \sprintf('%s::__invoke', $class->name)) {
$collection->addAlias($aliasName, $invokeRouteName);
}
}
return $collection;
}
/**
* @param RouteAttribute $attr or an object that exposes a similar interface
*/
protected function addRoute(RouteCollection $collection, object $attr, array $globals, \ReflectionClass $class, \ReflectionMethod $method): void
{
if ($attr->envs && !\in_array($this->env, $attr->envs, true)) {
return;
}
$name = $attr->name ?? $this->getDefaultRouteName($class, $method);
$name = $globals['name'].$name;
$requirements = $attr->requirements;
foreach ($requirements as $placeholder => $requirement) {
if (\is_int($placeholder)) {
throw new \InvalidArgumentException(\sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement "%s" of route "%s" in "%s::%s()"?', $placeholder, $requirement, $name, $class->getName(), $method->getName()));
}
}
$defaults = array_replace($globals['defaults'], $attr->defaults);
$requirements = array_replace($globals['requirements'], $requirements);
$options = array_replace($globals['options'], $attr->options);
$schemes = array_unique(array_merge($globals['schemes'], $attr->schemes));
$methods = array_unique(array_merge($globals['methods'], $attr->methods));
$host = $attr->host ?? $globals['host'];
$condition = $attr->condition ?? $globals['condition'];
$priority = $attr->priority ?? $globals['priority'];
$path = $attr->path;
$prefix = $globals['localized_paths'] ?: $globals['path'];
$paths = [];
if (\is_array($path)) {
if (!\is_array($prefix)) {
foreach ($path as $locale => $localePath) {
$paths[$locale] = $prefix.$localePath;
}
} elseif ($missing = array_diff_key($prefix, $path)) {
throw new \LogicException(\sprintf('Route to "%s" is missing paths for locale(s) "%s".', $class->name.'::'.$method->name, implode('", "', array_keys($missing))));
} else {
foreach ($path as $locale => $localePath) {
if (!isset($prefix[$locale])) {
throw new \LogicException(\sprintf('Route to "%s" with locale "%s" is missing a corresponding prefix in class "%s".', $method->name, $locale, $class->name));
}
$paths[$locale] = $prefix[$locale].$localePath;
}
}
} elseif (\is_array($prefix)) {
foreach ($prefix as $locale => $localePrefix) {
$paths[$locale] = $localePrefix.$path;
}
} else {
$paths[] = $prefix.$path;
}
foreach ($method->getParameters() as $param) {
if (isset($defaults[$param->name]) || !$param->isDefaultValueAvailable()) {
continue;
}
foreach ($paths as $locale => $path) {
if (preg_match(\sprintf('/\{(?|([^\}:<]++):%s(?:\.[^\}<]++)?|(%1$s))(?:<.*?>)?\}/', preg_quote($param->name)), $path, $matches)) {
if (\is_scalar($defaultValue = $param->getDefaultValue()) || null === $defaultValue) {
$defaults[$matches[1]] = $defaultValue;
} elseif ($defaultValue instanceof \BackedEnum) {
$defaults[$matches[1]] = $defaultValue->value;
}
break;
}
}
}
foreach ($paths as $locale => $path) {
$route = $this->createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
$this->configureRoute($route, $class, $method, $attr);
if (0 !== $locale) {
$route->setDefault('_locale', $locale);
$route->setRequirement('_locale', preg_quote($locale));
$route->setDefault('_canonical_route', $name);
$collection->add($name.'.'.$locale, $route, $priority);
} else {
$collection->add($name, $route, $priority);
}
}
foreach ($attr->aliases as $aliasAttribute) {
$aliasName = $aliasAttribute instanceof DeprecatedAlias ? $aliasAttribute->aliasName : $aliasAttribute;
foreach (array_keys($paths) as $locale) {
$suffix = 0 !== $locale ? '.'.$locale : '';
$alias = $collection->addAlias($aliasName.$suffix, $name.$suffix);
if ($aliasAttribute instanceof DeprecatedAlias) {
$alias->setDeprecated(
$aliasAttribute->package,
$aliasAttribute->version,
$aliasAttribute->message
);
}
}
}
}
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 || 'attribute' === $type);
}
public function setResolver(LoaderResolverInterface $resolver): void
{
}
public function getResolver(): LoaderResolverInterface
{
throw new LogicException(\sprintf('The "%s()" method must not be called.', __METHOD__));
}
/**
* Gets the default route name for a class method.
*/
protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method): string
{
$name = str_replace('\\', '_', $class->name).'_'.$method->name;
$name = \function_exists('mb_strtolower') && preg_match('//u', $name) ? mb_strtolower($name, 'UTF-8') : strtolower($name);
if ($this->defaultRouteIndex > 0) {
$name .= '_'.$this->defaultRouteIndex;
}
++$this->defaultRouteIndex;
return $name;
}
/**
* @return array<string, mixed>
*/
protected function getGlobals(\ReflectionClass $class): array
{
$globals = $this->resetGlobals();
if ($attribute = $class->getAttributes($this->routeAttributeClass, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
$attr = $attribute->newInstance();
if (null !== $attr->name) {
$globals['name'] = $attr->name;
}
if (\is_string($attr->path)) {
$globals['path'] = $attr->path;
$globals['localized_paths'] = [];
} else {
$globals['localized_paths'] = $attr->path ?? [];
}
if (null !== $attr->requirements) {
$globals['requirements'] = $attr->requirements;
}
if (null !== $attr->options) {
$globals['options'] = $attr->options;
}
if (null !== $attr->defaults) {
$globals['defaults'] = $attr->defaults;
}
if (null !== $attr->schemes) {
$globals['schemes'] = $attr->schemes;
}
if (null !== $attr->methods) {
$globals['methods'] = $attr->methods;
}
if (null !== $attr->host) {
$globals['host'] = $attr->host;
}
if (null !== $attr->condition) {
$globals['condition'] = $attr->condition;
}
$globals['priority'] = $attr->priority ?? 0;
$globals['env'] = $attr->envs;
foreach ($globals['requirements'] as $placeholder => $requirement) {
if (\is_int($placeholder)) {
throw new \InvalidArgumentException(\sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement "%s" in "%s"?', $placeholder, $requirement, $class->getName()));
}
}
}
return $globals;
}
private function resetGlobals(): array
{
return [
'path' => null,
'localized_paths' => [],
'requirements' => [],
'options' => [],
'defaults' => [],
'schemes' => [],
'methods' => [],
'host' => '',
'condition' => '',
'name' => '',
'priority' => 0,
'env' => null,
];
}
protected function createRoute(string $path, array $defaults, array $requirements, array $options, ?string $host, array $schemes, array $methods, ?string $condition): Route
{
return new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
}
/**
* @param RouteAttribute $attr or an object that exposes a similar interface
*/
abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $attr): void;
/**
* @return iterable<int, RouteAttribute>
*/
private function getAttributes(\ReflectionClass|\ReflectionMethod $reflection): iterable
{
foreach ($reflection->getAttributes($this->routeAttributeClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
yield $attribute->newInstance();
}
}
}
================================================
FILE: Loader/AttributeDirectoryLoader.php
================================================
<?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\Resource\GlobResource;
use Symfony\Component\Routing\RouteCollection;
/**
* AttributeDirectoryLoader loads routing information from attributes set
* on PHP classes and methods.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Alexandre Daubois <alex.daubois@gmail.com>
*/
class AttributeDirectoryLoader extends AttributeFileLoader
{
/**
* @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed
*/
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();
}
$collection = new RouteCollection();
$collection->addResource(new GlobResource($dir, '/*.php', true));
$files = iterator_to_array(new \RecursiveIteratorIterator(
new \RecursiveCallbackFilterIterator(
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
static fn (\SplFileInfo $current) => !str_starts_with($current->getBasename(), '.')
),
\RecursiveIteratorIterator::LEAVES_ONLY
));
usort($files, static fn (\SplFileInfo $a, \SplFileInfo $b) => (string) $a > (string) $b ? 1 : -1);
foreach ($files as $file) {
if (!$file->isFile() || !str_ends_with($file->getFilename(), '.php')) {
continue;
}
if ($class = $this->findClass($file)) {
$refl = new \ReflectionClass($class);
if ($refl->isAbstract()) {
continue;
}
$collection->addCollection($this->loader->load($class, $type));
}
}
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
if (!\is_string($resource)) {
return false;
}
if ('attribute' === $type) {
return true;
}
if ($type) {
return false;
}
try {
return is_dir($this->locator->locate($resource));
} catch (\Exception) {
return false;
}
}
}
================================================
FILE: Loader/AttributeFileLoader.php
================================================
<?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\FileLoader;
use Symfony\Component\Config\Resource\ReflectionClassResource;
use Symfony\Component\Routing\RouteCollection;
/**
* AttributeFileLoader loads routing information from attributes set
* on a PHP class and its methods.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Alexandre Daubois <alex.daubois@gmail.com>
*/
class AttributeFileLoader extends FileLoader
{
public function __construct(
FileLocatorInterface $locator,
protected AttributeClassLoader $loader,
) {
if (!\function_exists('token_get_all')) {
throw new \LogicException('The Tokenizer extension is required for the routing attribute loader.');
}
parent::__construct($locator);
}
/**
* Loads from attributes from a file.
*
* @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
*/
public function load(mixed $file, ?string $type = null): ?RouteCollection
{
$path = $this->locator->locate($file);
$collection = new RouteCollection();
if ($class = $this->findClass($path)) {
$refl = new \ReflectionClass($class);
if ($refl->isAbstract()) {
return null;
}
$collection->addResource(new ReflectionClassResource($refl));
$collection->addCollection($this->loader->load($class, $type));
}
gc_mem_caches();
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'attribute' === $type);
}
/**
* Returns the full class name for the first class in the file.
*/
protected function findClass(string $file): string|false
{
$class = false;
$namespace = false;
$tokens = token_get_all(file_get_contents($file));
if (1 === \count($tokens) && \T_INLINE_HTML === $tokens[0][0]) {
throw new \InvalidArgumentException(\sprintf('The file "%s" does not contain PHP code. Did you forget to add the "<?php" start tag at the beginning of the file?', $file));
}
$nsTokens = [\T_NS_SEPARATOR => true, \T_STRING => true, \T_NAME_QUALIFIED => true];
for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];
if (!isset($token[1])) {
continue;
}
if (true === $class && \T_STRING === $token[0]) {
return $namespace.'\\'.$token[1];
}
if (true === $namespace && isset($nsTokens[$token[0]])) {
$namespace = $token[1];
while (isset($tokens[++$i][1], $nsTokens[$tokens[$i][0]])) {
$namespace .= $tokens[$i][1];
}
$token = $tokens[$i];
}
if (\T_CLASS === $token[0]) {
// Skip usage of ::class constant and anonymous classes
$skipClassToken = false;
for ($j = $i - 1; $j > 0; --$j) {
if (!isset($tokens[$j][1])) {
if ('(' === $tokens[$j] || ',' === $tokens[$j]) {
$skipClassToken = true;
}
break;
}
if (\T_DOUBLE_COLON === $tokens[$j][0] || \T_NEW === $tokens[$j][0]) {
$skipClassToken = true;
break;
} elseif (!\in_array($tokens[$j][0], [\T_WHITESPACE, \T_DOC_COMMENT, \T_COMMENT], true)) {
break;
}
}
if (!$skipClassToken) {
$class = true;
}
}
if (\T_NAMESPACE === $token[0]) {
$namespace = true;
}
}
return false;
}
}
================================================
FILE: Loader/AttributeServicesLoader.php
================================================
<?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\Loader\Loader;
use Symfony\Component\Routing\RouteCollection;
/**
* Loads routes from a list of tagged classes by delegating to the attribute class loader.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
final class AttributeServicesLoader extends Loader
{
/**
* @param class-string[] $taggedClasses
*/
public function __construct(
private array $taggedClasses = [],
) {
}
public function load(mixed $resource, ?string $type = null): RouteCollection
{
$collection = new RouteCollection();
foreach ($this->taggedClasses as $class) {
$collection->addCollection($this->import($class, 'attribute'));
}
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
return 'routing.controllers' === $resource;
}
}
================================================
FILE: Loader/ClosureLoader.php
================================================
<?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\Loader\Loader;
use Symfony\Component\Routing\RouteCollection;
/**
* ClosureLoader loads routes from a PHP closure.
*
* The Closure must return a RouteCollection instance.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ClosureLoader extends Loader
{
/**
* Loads a Closure.
*/
public function load(mixed $closure, ?string $type = null): RouteCollection
{
return $closure($this->env);
}
public function supports(mixed $resource, ?string $type = null): bool
{
return $resource instanceof \Closure && (!$type || 'closure' === $type);
}
}
================================================
FILE: Loader/Configurator/AliasConfigurator.php
================================================
<?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\Configurator;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\Routing\Alias;
class AliasConfigurator
{
public function __construct(
private Alias $alias,
) {
}
/**
* Whether this alias is deprecated, that means it should not be called anymore.
*
* @param string $package The name of the composer package that is triggering the deprecation
* @param string $version The version of the package that introduced the deprecation
* @param string $message The deprecation message to use
*
* @return $this
*
* @throws InvalidArgumentException when the message template is invalid
*/
public function deprecate(string $package, string $version, string $message): static
{
$this->alias->setDeprecated($package, $version, $message);
return $this;
}
}
================================================
FILE: Loader/Configurator/CollectionConfigurator.php
================================================
<?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\Configurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class CollectionConfigurator
{
use Traits\AddTrait;
use Traits\HostTrait;
use Traits\RouteTrait;
private string|array|null $host = null;
public function __construct(
private RouteCollection $parent,
string $name,
private ?self $parentConfigurator = null, // for GC control
private ?array $parentPrefixes = null,
) {
$this->name = $name;
$this->collection = new RouteCollection();
$this->route = new Route('');
}
public function __serialize(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
public function __unserialize(array $data): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
public function __destruct()
{
if (null === $this->prefixes) {
$this->collection->addPrefix($this->route->getPath());
}
if (null !== $this->host) {
$this->addHost($this->collection, $this->host);
}
$this->parent->addCollection($this->collection);
}
/**
* Creates a sub-collection.
*/
final public function collection(string $name = ''): self
{
return new self($this->collection, $this->name.$name, $this, $this->prefixes);
}
/**
* Sets the prefix to add to the path of all child routes.
*
* @param string|array $prefix the prefix, or the localized prefixes
*
* @return $this
*/
final public function prefix(string|array $prefix): static
{
if (\is_array($prefix)) {
if (null === $this->parentPrefixes) {
// no-op
} elseif ($missing = array_diff_key($this->parentPrefixes, $prefix)) {
throw new \LogicException(\sprintf('Collection "%s" is missing prefixes for locale(s) "%s".', $this->name, implode('", "', array_keys($missing))));
} else {
foreach ($prefix as $locale => $localePrefix) {
if (!isset($this->parentPrefixes[$locale])) {
throw new \LogicException(\sprintf('Collection "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $this->name, $locale));
}
$prefix[$locale] = $this->parentPrefixes[$locale].$localePrefix;
}
}
$this->prefixes = $prefix;
$this->route->setPath('/');
} else {
$this->prefixes = null;
$this->route->setPath($prefix);
}
return $this;
}
/**
* Sets the host to use for all child routes.
*
* @param string|array $host the host, or the localized hosts
*
* @return $this
*/
final public function host(string|array $host): static
{
$this->host = $host;
return $this;
}
/**
* This method overrides the one from LocalizedRouteTrait.
*/
private function createRoute(string $path): Route
{
return (clone $this->route)->setPath($path);
}
}
================================================
FILE: Loader/Configurator/ImportConfigurator.php
================================================
<?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\Configurator;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ImportConfigurator
{
use Traits\HostTrait;
use Traits\PrefixTrait;
use Traits\RouteTrait;
public function __construct(
private RouteCollection $parent,
RouteCollection $route,
) {
$this->route = $route;
}
public function __serialize(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
public function __unserialize(array $data): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
public function __destruct()
{
$this->parent->addCollection($this->route);
}
/**
* Sets the prefix to add to the path of all child routes.
*
* @param string|array $prefix the prefix, or the localized prefixes
*
* @return $this
*/
final public function prefix(string|array $prefix, bool $trailingSlashOnRoot = true): static
{
$this->addPrefix($this->route, $prefix, $trailingSlashOnRoot);
return $this;
}
/**
* Sets the prefix to add to the name of all child routes.
*
* @return $this
*/
final public function namePrefix(string $namePrefix): static
{
$this->route->addNamePrefix($namePrefix);
return $this;
}
/**
* Sets the host to use for all child routes.
*
* @param string|array $host the host, or the localized hosts
*
* @return $this
*/
final public function host(string|array $host): static
{
$this->addHost($this->route, $host);
return $this;
}
}
================================================
FILE: Loader/Configurator/RouteConfigurator.php
================================================
<?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\Configurator;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class RouteConfigurator
{
use Traits\AddTrait;
use Traits\HostTrait;
use Traits\RouteTrait;
public function __construct(
RouteCollection $collection,
RouteCollection $route,
string $name = '',
protected ?CollectionConfigurator $parentConfigurator = null, // for GC control
?array $prefixes = null,
) {
$this->collection = $collection;
$this->route = $route;
$this->name = $name;
$this->prefixes = $prefixes;
}
/**
* Sets the host to use for all child routes.
*
* @param string|array $host the host, or the localized hosts
*
* @return $this
*/
final public function host(string|array $host): static
{
$previousRoutes = clone $this->route;
$this->addHost($this->route, $host);
foreach ($previousRoutes as $name => $route) {
if (!$this->route->get($name)) {
$this->collection->remove($name);
}
}
$this->collection->addCollection($this->route);
return $this;
}
}
================================================
FILE: Loader/Configurator/RoutesReference.php
================================================
<?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\Configurator;
// For the phpdoc to remain compatible with the generation of per-app Routes class,
// this file should have no "use" statements: all symbols referenced by
// the phpdoc need to be in the current namespace or be root-scoped.
/**
* This class provides array-shapes for configuring the routes of an application.
*
* Example:
*
* ```php
* // config/routes.php
* namespace Symfony\Component\Routing\Loader\Configurator;
*
* return Routes::config([
* 'controllers' => [
* 'resource' => 'routing.controllers',
* ],
* ]);
* ```
*
* @psalm-type RouteConfig = array{
* path: string|array<string,string>,
* controller?: string,
* methods?: string|list<string>,
* requirements?: array<string,string>,
* defaults?: array<string,mixed>,
* options?: array<string,mixed>,
* host?: string|array<string,string>,
* schemes?: string|list<string>,
* condition?: string,
* locale?: string,
* format?: string,
* utf8?: bool,
* stateless?: bool,
* }
* @psalm-type ImportConfig = array{
* resource: string,
* type?: string,
* exclude?: string|list<string>,
* prefix?: string|array<string,string>,
* name_prefix?: string,
* trailing_slash_on_root?: bool,
* controller?: string,
* methods?: string|list<string>,
* requirements?: array<string,string>,
* defaults?: array<string,mixed>,
* options?: array<string,mixed>,
* host?: string|array<string,string>,
* schemes?: string|list<string>,
* condition?: string,
* locale?: string,
* format?: string,
* utf8?: bool,
* stateless?: bool,
* }
* @psalm-type AliasConfig = array{
* alias: string,
* deprecated?: array{package:string, version:string, message?:string},
* }
* @psalm-type RoutesConfig = array<string, RouteConfig|ImportConfig|AliasConfig|array<string, RouteConfig|ImportConfig|AliasConfig>>
*/
class RoutesReference
{
/**
* @param RoutesConfig $config
*
* @psalm-return RoutesConfig
*/
public static function config(array $config): array
{
return $config;
}
}
================================================
FILE: Loader/Configurator/RoutingConfigurator.php
================================================
<?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\Configurator;
use Symfony\Component\Routing\Loader\PhpFileLoader;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class RoutingConfigurator
{
use Traits\AddTrait;
public function __construct(
RouteCollection $collection,
private PhpFileLoader $loader,
private string $path,
private string $file,
private ?string $env = null,
) {
$this->collection = $collection;
}
/**
* @param string|string[]|null $exclude Glob patterns to exclude from the import
*/
final public function import(string|array $resource, ?string $type = null, bool $ignoreErrors = false, string|array|null $exclude = null): ImportConfigurator
{
$this->loader->setCurrentDir(\dirname($this->path));
$imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file, $exclude) ?: [];
if (!\is_array($imported)) {
return new ImportConfigurator($this->collection, $imported);
}
$mergedCollection = new RouteCollection();
foreach ($imported as $subCollection) {
$mergedCollection->addCollection($subCollection);
}
return new ImportConfigurator($this->collection, $mergedCollection);
}
final public function collection(string $name = ''): CollectionConfigurator
{
return new CollectionConfigurator($this->collection, $name);
}
/**
* Get the current environment to be able to write conditional configuration.
*/
final public function env(): ?string
{
return $this->env;
}
final public function withPath(string $path): static
{
$clone = clone $this;
$clone->path = $clone->file = $path;
return $clone;
}
}
================================================
FILE: Loader/Configurator/Traits/AddTrait.php
================================================
<?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\Configurator\Traits;
use Symfony\Component\Routing\Loader\Configurator\AliasConfigurator;
use Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
trait AddTrait
{
use LocalizedRouteTrait;
protected RouteCollection $collection;
protected string $name = '';
protected ?array $prefixes = null;
/**
* Adds a route.
*
* @param string|array $path the path, or the localized paths of the route
*/
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);
return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes);
}
public function alias(string $name, string $alias): AliasConfigurator
{
return new AliasConfigurator($this->collection->addAlias($name, $alias));
}
/**
* Adds a route.
*
* @param string|array $path the path, or the localized paths of the route
*/
public function __invoke(string $name, string|array $path): RouteConfigurator
{
return $this->add($name, $path);
}
}
================================================
FILE: Loader/Configurator/Traits/HostTrait.php
================================================
<?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\Configurator\Traits;
use Symfony\Component\Routing\RouteCollection;
/**
* @internal
*/
trait HostTrait
{
final protected function addHost(RouteCollection $routes, string|array $hosts): void
{
if (!$hosts || !\is_array($hosts)) {
$routes->setHost($hosts ?: '');
return;
}
foreach ($routes->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) {
$priority = $routes->getPriority($name) ?? 0;
$routes->remove($name);
foreach ($hosts as $locale => $host) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setRequirement('_locale', preg_quote($locale));
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setHost($host);
$routes->add($name.'.'.$locale, $localizedRoute, $priority);
}
} elseif (!isset($hosts[$locale])) {
throw new \InvalidArgumentException(\sprintf('Route "%s" with locale "%s" is missing a corresponding host in its parent collection.', $name, $locale));
} else {
$route->setHost($hosts[$locale]);
$route->setRequirement('_locale', preg_quote($locale));
$routes->add($name, $route, $routes->getPriority($name) ?? 0);
}
}
}
}
================================================
FILE: Loader/Configurator/Traits/LocalizedRouteTrait.php
================================================
<?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\Configurator\Traits;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @internal
*
* @author Nicolas Grekas <p@tchwork.com>
* @author Jules Pietri <jules@heahprod.com>
*/
trait LocalizedRouteTrait
{
/**
* Creates one or many routes.
*
* @param string|array $path the path, or the localized paths of the route
*/
final protected function createLocalizedRoute(RouteCollection $collection, string $name, string|array $path, string $namePrefix = '', ?array $prefixes = null): RouteCollection
{
$paths = [];
$routes = new RouteCollection();
if (\is_array($path)) {
if (null === $prefixes) {
$paths = $path;
} elseif ($missing = array_diff_key($prefixes, $path)) {
throw new \LogicException(\sprintf('Route "%s" is missing routes for locale(s) "%s".', $name, implode('", "', array_keys($missing))));
} else {
foreach ($path as $locale => $localePath) {
if (!isset($prefixes[$locale])) {
throw new \LogicException(\sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale));
}
$paths[$locale] = $prefixes[$locale].$localePath;
}
}
} elseif (null !== $prefixes) {
foreach ($prefixes as $locale => $prefix) {
$paths[$locale] = $prefix.$path;
}
} else {
$routes->add($namePrefix.$name, $route = $this->createRoute($path));
$collection->add($namePrefix.$name, $route);
return $routes;
}
foreach ($paths as $locale => $path) {
$routes->add($name.'.'.$locale, $route = $this->createRoute($path));
$collection->add($namePrefix.$name.'.'.$locale, $route);
$route->setDefault('_locale', $locale);
$route->setRequirement('_locale', preg_quote($locale));
$route->setDefault('_canonical_route', $namePrefix.$name);
}
return $routes;
}
private function createRoute(string $path): Route
{
return new Route($path);
}
}
================================================
FILE: Loader/Configurator/Traits/PrefixTrait.php
================================================
<?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\Configurator\Traits;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @internal
*
* @author Nicolas Grekas <p@tchwork.com>
*/
trait PrefixTrait
{
final protected function addPrefix(RouteCollection $routes, string|array $prefix, bool $trailingSlashOnRoot): void
{
if (\is_array($prefix)) {
foreach ($prefix as $locale => $localePrefix) {
$prefix[$locale] = trim(trim($localePrefix), '/');
}
$aliases = [];
foreach ($routes->getAliases() as $name => $alias) {
$aliases[$alias->getId()][] = $name;
}
foreach ($routes->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) {
$priority = $routes->getPriority($name) ?? 0;
$routes->remove($name);
foreach ($aliases[$name] ?? [] as $aliasName) {
$routes->remove($aliasName);
}
foreach ($prefix as $locale => $localePrefix) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setRequirement('_locale', preg_quote($locale));
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$routes->add($name.'.'.$locale, $localizedRoute, $priority);
foreach ($aliases[$name] ?? [] as $aliasName) {
$routes->addAlias($aliasName.'.'.$locale, $name.'.'.$locale);
}
}
} elseif (!isset($prefix[$locale])) {
throw new \InvalidArgumentException(\sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale));
} else {
$route->setPath($prefix[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$routes->add($name, $route, $routes->getPriority($name) ?? 0);
}
}
return;
}
$routes->addPrefix($prefix);
if (!$trailingSlashOnRoot) {
$rootPath = (new Route(trim(trim($prefix), '/').'/'))->getPath();
foreach ($routes->all() as $route) {
if ($route->getPath() === $rootPath) {
$route->setPath(rtrim($rootPath, '/'));
}
}
}
}
}
================================================
FILE: Loader/Configurator/Traits/RouteTrait.php
================================================
<?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\Configurator\Traits;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
trait RouteTrait
{
protected RouteCollection|Route $route;
/**
* Adds defaults.
*
* @return $this
*/
final public function defaults(array $defaults): static
{
$this->route->addDefaults($defaults);
return $this;
}
/**
* Adds requirements.
*
* @return $this
*/
final public function requirements(array $requirements): static
{
$this->route->addRequirements($requirements);
return $this;
}
/**
* Adds options.
*
* @return $this
*/
final public function options(array $options): static
{
$this->route->addOptions($options);
return $this;
}
/**
* Whether paths should accept utf8 encoding.
*
* @return $this
*/
final public function utf8(bool $utf8 = true): static
{
$this->route->addOptions(['utf8' => $utf8]);
return $this;
}
/**
* Sets the condition.
*
* @return $this
*/
final public function condition(string $condition): static
{
$this->route->setCondition($condition);
return $this;
}
/**
* Sets the pattern for the host.
*
* @return $this
*/
final public function host(string $pattern): static
{
$this->route->setHost($pattern);
return $this;
}
/**
* Sets the schemes (e.g. 'https') this route is restricted to.
* So an empty array means that any scheme is allowed.
*
* @param string[] $schemes
*
* @return $this
*/
final public function schemes(array $schemes): static
{
$this->route->setSchemes($schemes);
return $this;
}
/**
* Sets the HTTP methods (e.g. 'POST') this route is restricted to.
* So an empty array means that any method is allowed.
*
* @param string[] $methods
*
* @return $this
*/
final public function methods(array $methods): static
{
$this->route->setMethods($methods);
return $this;
}
/**
* Adds the "_controller" entry to defaults.
*
* @param callable|string|array $controller a callable or parseable pseudo-callable
*
* @return $this
*/
final public function controller(callable|string|array $controller): static
{
$this->route->addDefaults(['_controller' => $controller]);
return $this;
}
/**
* Adds the "_locale" entry to defaults.
*
* @return $this
*/
final public function locale(string $locale): static
{
$this->route->addDefaults(['_locale' => $locale]);
return $this;
}
/**
* Adds the "_format" entry to defaults.
*
* @return $this
*/
final public function format(string $format): static
{
$this->route->addDefaults(['_format' => $format]);
return $this;
}
/**
* Adds the "_stateless" entry to defaults.
*
* @return $this
*/
final public function stateless(bool $stateless = true): static
{
$this->route->addDefaults(['_stateless' => $stateless]);
return $this;
}
}
================================================
FILE: Loader/ContainerLoader.php
================================================
<?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 Psr\Container\ContainerInterface;
/**
* A route loader that executes a service from a PSR-11 container to load the routes.
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
class ContainerLoader extends ObjectLoader
{
public function __construct(
private ContainerInterface $container,
?string $env = null,
) {
parent::__construct($env);
}
public function supports(mixed $resource, ?string $type = null): bool
{
return 'service' === $type && \is_string($resource);
}
protected function getObject(string $id): object
{
return $this->container->get($id);
}
}
================================================
FILE: Loader/ContentLoaderTrait.php
================================================
<?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\Routing\Loader\Configurator\Traits\LocalizedRouteTrait;
use Symfony\Component\Routing\Loader\Configurator\Traits\PrefixTrait;
use Symfony\Component\Routing\RouteCollection;
/**
* @internal
*/
trait ContentLoaderTrait
{
use LocalizedRouteTrait;
use PrefixTrait;
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 function loadContent(RouteCollection $collection, array $config, string $path, string $file): void
{
foreach ($config as $name => $config) {
if (!str_starts_with($when = $name, 'when@')) {
$config = [$name => $config];
} elseif (!$this->env || 'when@'.$this->env !== $name) {
continue;
} else {
$when .= '" when "@'.$this->env;
}
foreach ($config as $name => $config) {
$this->validate($config, $when, $path);
if (isset($config['resource'])) {
$this->parseImport($collection, $config, $path, $file);
} else {
$this->parseRoute($collection, $name, $config, $path);
}
}
}
}
/**
* Parses a route and adds it to the RouteCollection.
*/
private function parseRoute(RouteCollection $collection, string $name, array $config, string $path): void
{
if (isset($config['alias'])) {
$alias = $collection->addAlias($name, $config['alias']);
$deprecation = $config['deprecated'] ?? null;
if (null !== $deprecation) {
$alias->setDeprecated(
$deprecation['package'],
$deprecation['version'],
$deprecation['message'] ?? ''
);
}
return;
}
$defaults = $config['defaults'] ?? [];
$requirements = $config['requirements'] ?? [];
$options = $config['options'] ?? [];
foreach ($requirements as $placeholder => $requirement) {
if (\is_int($placeholder)) {
throw new \InvalidArgumentException(\sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement "%s" of route "%s" in "%s"?', $placeholder, $requirement, $name, $path));
}
}
if (isset($config['controller'])) {
$defaults['_controller'] = $config['controller'];
}
if (isset($config['locale'])) {
$defaults['_locale'] = $config['locale'];
}
if (isset($config['format'])) {
$defaults['_format'] = $config['format'];
}
if (isset($config['utf8'])) {
$options['utf8'] = $config['utf8'];
}
if (isset($config['stateless'])) {
$defaults['_stateless'] = $config['stateless'];
}
$routes = $this->createLocalizedRoute(new RouteCollection(), $name, $config['path']);
$routes->addDefaults($defaults);
$routes->addRequirements($requirements);
$routes->addOptions($options);
$routes->setSchemes($config['schemes'] ?? []);
$routes->setMethods($config['methods'] ?? []);
$routes->setCondition($config['condition'] ?? null);
if (isset($config['host'])) {
$this->addHost($routes, $config['host']);
}
$collection->addCollection($routes);
}
/**
* Parses an import and adds the routes in the resource to the RouteCollection.
*/
private function parseImport(RouteCollection $collection, array $config, string $path, string $file): void
{
$type = $config['type'] ?? null;
$prefix = $config['prefix'] ?? '';
$defaults = $config['defaults'] ?? [];
$requirements = $config['requirements'] ?? [];
$options = $config['options'] ?? [];
$host = $config['host'] ?? null;
$condition = $config['condition'] ?? null;
$schemes = $config['schemes'] ?? null;
$methods = $config['methods'] ?? null;
$trailingSlashOnRoot = $config['trailing_slash_on_root'] ?? true;
$namePrefix = $config['name_prefix'] ?? null;
$exclude = $config['exclude'] ?? null;
if (isset($config['controller'])) {
$defaults['_controller'] = $config['controller'];
}
if (isset($config['locale'])) {
$defaults['_locale'] = $config['locale'];
}
if (isset($config['format'])) {
$defaults['_format'] = $config['format'];
}
if (isset($config['utf8'])) {
$options['utf8'] = $config['utf8'];
}
if (isset($config['stateless'])) {
$defaults['_stateless'] = $config['stateless'];
}
$this->setCurrentDir(\dirname($path));
/** @var RouteCollection[] $imported */
$imported = $this->import($config['resource'], $type, false, $file, $exclude) ?: [];
if (!\is_array($imported)) {
$imported = [$imported];
}
foreach ($imported as $subCollection) {
$this->addPrefix($subCollection, $prefix, $trailingSlashOnRoot);
if (null !== $host) {
$this->addHost($subCollection, $host);
}
if (null !== $condition) {
$subCollection->setCondition($condition);
}
if (null !== $schemes) {
$subCollection->setSchemes($schemes);
}
if (null !== $methods) {
$subCollection->setMethods($methods);
}
if (null !== $namePrefix) {
$subCollection->addNamePrefix($namePrefix);
}
$subCollection->addDefaults($defaults);
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
$collection->addCollection($subCollection);
}
}
/**
* @throws \InvalidArgumentException If one of the provided config keys is not supported,
* something is missing or the combination is nonsense
*/
private function validate(mixed $config, string $name, string $path): void
{
if (!\is_array($config)) {
throw new \InvalidArgumentException(\sprintf('The definition of "%s" in "%s" must be an array.', $name, $path));
}
if (isset($config['alias'])) {
$this->validateAlias($config, $name, $path);
return;
}
if ($extraKeys = array_diff(array_keys($config), self::AVAILABLE_KEYS)) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".', $path, $name, implode('", "', $extraKeys), implode('", "', self::AVAILABLE_KEYS)));
}
if (isset($config['resource']) && isset($config['path'])) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.', $path, $name));
}
if (!isset($config['resource']) && isset($config['type'])) {
throw new \InvalidArgumentException(\sprintf('The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.', $name, $path));
}
if (!isset($config['resource']) && !isset($config['path'])) {
throw new \InvalidArgumentException(\sprintf('You must define a "path" for the route "%s" in file "%s".', $name, $path));
}
if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
}
if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "stateless" key and the defaults key "_stateless" for "%s".', $path, $name));
}
}
/**
* @throws \InvalidArgumentException If one of the provided config keys is not supported,
* something is missing or the combination is nonsense
*/
private function validateAlias(array $config, string $name, string $path): void
{
foreach ($config as $key => $value) {
if (!\in_array($key, ['alias', 'deprecated'], true)) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify other keys than "alias" and "deprecated" for "%s".', $path, $name));
}
if ('deprecated' === $key) {
if (!isset($value['package'])) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" must specify the attribute "package" of the "deprecated" option for "%s".', $path, $name));
}
if (!isset($value['version'])) {
throw new \InvalidArgumentException(\sprintf('The routing file "%s" must specify the attribute "version" of the "deprecated" option for "%s".', $path, $name));
}
}
}
}
}
================================================
FILE: Loader/DirectoryLoader.php
================================================
<?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\Loader\FileLoader;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Routing\RouteCollection;
class DirectoryLoader extends FileLoader
{
public function load(mixed $file, ?string $type = null): mixed
{
$path = $this->locator->locate($file);
$collection = new RouteCollection();
$collection->addResource(new DirectoryResource($path));
foreach (scandir($path) as $dir) {
if ('.' !== $dir[0]) {
$this->setCurrentDir($path);
$subPath = $path.'/'.$dir;
$subType = null;
if (is_dir($subPath)) {
$subPath .= '/';
$subType = 'directory';
}
$subCollection = $this->import($subPath, $subType, false, $path);
$collection->addCollection($subCollection);
}
}
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
// only when type is forced to directory, not to conflict with AttributeLoader
return 'directory' === $type;
}
}
================================================
FILE: Loader/GlobFileLoader.php
================================================
<?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\Loader\FileLoader;
use Symfony\Component\Routing\RouteCollection;
/**
* GlobFileLoader loads files from a glob pattern.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class GlobFileLoader extends FileLoader
{
public function load(mixed $resource, ?string $type = null): mixed
{
$collection = new RouteCollection();
foreach ($this->glob($resource, false, $globResource) as $path => $info) {
$collection->addCollection($this->import($path));
}
$collection->addResource($globResource);
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
return 'glob' === $type;
}
}
================================================
FILE: Loader/ObjectLoader.php
================================================
<?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\Loader\Loader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\RouteCollection;
/**
* A route loader that calls a method on an object to load the routes.
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
abstract class ObjectLoader extends Loader
{
/**
* Returns the object that the method will be called on to load routes.
*
* For example, if your application uses a service container,
* the $id may be a service id.
*/
abstract protected function getObject(string $id): object;
/**
* Calls the object method that will load the routes.
*/
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'));
}
$parts = explode('::', $resource);
$method = $parts[1] ?? '__invoke';
$loaderObject = $this->getObject($parts[0]);
if (!\is_callable([$loaderObject, $method])) {
throw new \BadMethodCallException(\sprintf('Method "%s" not found on "%s" when importing routing resource "%s".', $method, get_debug_type($loaderObject), $resource));
}
$routeCollection = $loaderObject->$method($this, $this->env);
if (!$routeCollection instanceof RouteCollection) {
$type = get_debug_type($routeCollection);
throw new \LogicException(\sprintf('The "%s::%s()" method must return a RouteCollection: "%s" returned.', get_debug_type($loaderObject), $method, $type));
}
// make the object file tracked so that if it changes, the cache rebuilds
$this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
return $routeCollection;
}
private function addClassResource(\ReflectionClass $class, RouteCollection $collection): void
{
do {
if (is_file($class->getFileName())) {
$collection->addResource(new FileResource($class->getFileName()));
}
} while ($class = $class->getParentClass());
}
}
================================================
FILE: Loader/PhpFileLoader.php
================================================
<?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\Loader\FileLoader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\Exception\InvalidArgumentException;
use Symfony\Component\Routing\Loader\Configurator\Routes;
use Symfony\Component\Routing\Loader\Configurator\RoutesReference;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use Symfony\Component\Routing\RouteCollection;
/**
* PhpFileLoader loads routes from a PHP file.
*
* The file must return a RouteCollection instance.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Nicolas grekas <p@tchwork.com>
* @author Jules Pietri <jules@heahprod.com>
*/
class PhpFileLoader extends FileLoader
{
use ContentLoaderTrait;
/**
* Loads a PHP file.
*/
public function load(mixed $file, ?string $type = null): RouteCollection
{
$path = $this->locator->locate($file);
$this->setCurrentDir(\dirname($path));
// Expose RoutesReference::config() as Routes::config()
if (!class_exists(Routes::class)) {
class_alias(RoutesReference::class, Routes::class);
}
// the closure forbids access to the private scope in the included file
$loader = $this;
$load = \Closure::bind(static function ($file) use ($loader) {
return include $file;
}, null, null);
if (1 === $result = $load($path)) {
$result = null;
}
if (\is_object($result) && \is_callable($result)) {
$collection = $this->callConfigurator($result, $path, $file);
} elseif (\is_array($result)) {
$collection = new RouteCollection();
$this->loadContent($collection, $result, $path, $file);
} elseif (!($collection = $result) instanceof RouteCollection) {
throw new InvalidArgumentException(\sprintf('The return value in config file "%s" is expected to be a RouteCollection, an array or a configurator callable, but got "%s".', $path, get_debug_type($result)));
}
$collection->addResource(new FileResource($path));
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'php' === $type);
}
protected function callConfigurator(callable $callback, string $path, string $file): RouteCollection
{
$collection = new RouteCollection();
$callback(new RoutingConfigurator($collection, $this, $path, $file, $this->env));
return $collection;
}
}
================================================
FILE: Loader/Psr4DirectoryLoader.php
================================================
<?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\Exception\InvalidArgumentException;
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
{
$excluded = $resource['_excluded'] ?? [];
$path = $this->locator->locate($resource['path'], $this->currentDirectory);
if (!is_dir($path)) {
return new RouteCollection();
}
if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\)++$/', trim($resource['namespace'], '\\').'\\')) {
throw new InvalidArgumentException(\sprintf('Namespace "%s" is not a valid PSR-4 prefix.', $resource['namespace']));
}
return $this->loadFromDirectory($path, trim($resource['namespace'], '\\'), $excluded);
}
public function supports(mixed $resource, ?string $type = null): bool
{
return 'attribute' === $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, array $excluded = []): 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),
static fn (\SplFileInfo $current) => !str_starts_with($current->getBasename(), '.')
),
\RecursiveIteratorIterator::SELF_FIRST
));
usort($files, static fn (\SplFileInfo $a, \SplFileInfo $b) => (string) $a > (string) $b ? 1 : -1);
/** @var \SplFileInfo $file */
foreach ($files as $file) {
$normalizedPath = rtrim(str_replace('\\', '/', $file->getPathname()), '/');
if (isset($excluded[$normalizedPath])) {
continue;
}
if ($file->isDir()) {
$collection->addCollection($this->loadFromDirectory($file->getPathname(), $psr4Prefix.'\\'.$file->getFilename(), $excluded));
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;
}
}
================================================
FILE: Loader/YamlFileLoader.php
================================================
<?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\Loader\FileLoader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\Loader\Configurator\Traits\HostTrait;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser as YamlParser;
use Symfony\Component\Yaml\Yaml;
/**
* YamlFileLoader loads Yaml routing files.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
*/
class YamlFileLoader extends FileLoader
{
use ContentLoaderTrait {
parseImport as doParseImport;
parseRoute as doParseRoute;
validate as doValidate;
}
use HostTrait;
private YamlParser $yamlParser;
/**
* @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
*/
public function load(mixed $file, ?string $type = null): RouteCollection
{
$path = $this->locator->locate($file);
if (!stream_is_local($path)) {
throw new \InvalidArgumentException(\sprintf('This is not a local file "%s".', $path));
}
if (!file_exists($path)) {
throw new \InvalidArgumentException(\sprintf('File "%s" not found.', $path));
}
$this->yamlParser ??= new YamlParser();
try {
$parsedConfig = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT);
} catch (ParseException $e) {
throw new \InvalidArgumentException(\sprintf('The file "%s" does not contain valid YAML: ', $path).$e->getMessage(), 0, $e);
}
$collection = new RouteCollection();
$collection->addResource(new FileResource($path));
// empty file
if (null === $parsedConfig) {
return $collection;
}
// not an array
if (!\is_array($parsedConfig)) {
throw new \InvalidArgumentException(\sprintf('The file "%s" must contain a YAML array.', $path));
}
$this->loadContent($collection, $parsedConfig, $path, $file);
return $collection;
}
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);
}
/**
* Parses a route and adds it to the RouteCollection.
*/
protected function parseRoute(RouteCollection $collection, string $name, array $config, string $path): void
{
$this->doParseRoute($collection, $name, $config, $path);
}
/**
* Parses an import and adds the routes in the resource to the RouteCollection.
*/
protected function parseImport(RouteCollection $collection, array $config, string $path, string $file): void
{
$this->doParseImport($collection, $config, $path, $file);
}
/**
* @throws \InvalidArgumentException If one of the provided config keys is not supported,
* something is missing or the combination is nonsense
*/
protected function validate(mixed $config, string $name, string $path): void
{
$this->doValidate($config, $name, $path);
}
}
================================================
FILE: Loader/schema/routing/routing-1.0.xsd
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://symfony.com/schema/routing"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://symfony.com/schema/routing"
elementFormDefault="qualified">
<xsd:annotation>
<xsd:documentation><![CDATA[
Symfony XML Routing Schema, version 1.0
Authors: Fabien Potencier, Tobias Schultze
This scheme defines the elements and attributes that can be used to define
routes. A route maps an HTTP request to a set of configuration variables.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="routes" type="routes" />
<xsd:complexType name="routes">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="import" type="import" />
<xsd:element name="route" type="route" />
<xsd:element name="when" type="when" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="when">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="import" type="import" />
<xsd:element name="route" type="route" />
</xsd:choice>
<xsd:attribute name="env" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="localized-path">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="locale" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:group name="configs">
<xsd:choice>
<xsd:element name="default" nillable="true" type="default" />
<xsd:element name="requirement" type="element" />
<xsd:element name="option" type="element" />
<xsd:element name="condition" type="xsd:string" />
</xsd:choice>
</xsd:group>
<xsd:complexType name="route">
<xsd:sequence>
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="path" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="host" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="deprecated" type="deprecated" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required" />
<xsd:attribute name="path" type="xsd:string" />
<xsd:attribute name="host" type="xsd:string" />
<xsd:attribute name="schemes" type="xsd:string" />
<xsd:attribute name="methods" type="xsd:string" />
<xsd:attribute name="controller" type="xsd:string" />
<xsd:attribute name="locale" type="xsd:string" />
<xsd:attribute name="format" type="xsd:string" />
<xsd:attribute name="utf8" type="xsd:boolean" />
<xsd:attribute name="stateless" type="xsd:boolean" />
<xsd:attribute name="alias" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="import">
<xsd:sequence maxOccurs="unbounded" minOccurs="0">
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<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" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="exclude" type="xsd:string" />
<xsd:attribute name="prefix" type="xsd:string" />
<xsd:attribute name="name-prefix" type="xsd:string" />
<xsd:attribute name="host" type="xsd:string" />
<xsd:attribute name="schemes" type="xsd:string" />
<xsd:attribute name="methods" type="xsd:string" />
<xsd:attribute name="controller" type="xsd:string" />
<xsd:attribute name="locale" type="xsd:string" />
<xsd:attribute name="format" type="xsd:string" />
<xsd:attribute name="trailing-slash-on-root" type="xsd:boolean" />
<xsd:attribute name="utf8" type="xsd:boolean" />
<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" />
<xsd:element name="int" type="xsd:integer" />
<xsd:element name="float" type="xsd:float" />
<xsd:element name="string" type="xsd:string" />
<xsd:element name="list" type="list" />
<xsd:element name="map" type="map" />
</xsd:choice>
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="element">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="list">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="bool" nillable="true" type="xsd:boolean" />
<xsd:element name="int" nillable="true" type="xsd:integer" />
<xsd:element name="float" nillable="true" type="xsd:float" />
<xsd:element name="string" nillable="true" type="xsd:string" />
<xsd:element name="list" nillable="true" type="list" />
<xsd:element name="map" nillable="true" type="map" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="map">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="bool" nillable="true" type="map-bool-entry" />
<xsd:element name="int" nillable="true" type="map-int-entry" />
<xsd:element name="float" nillable="true" type="map-float-entry" />
<xsd:element name="string" nillable="true" type="map-string-entry" />
<xsd:element name="list" nillable="true" type="map-list-entry" />
<xsd:element name="map" nillable="true" type="map-map-entry" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="map-bool-entry">
<xsd:simpleContent>
<xsd:extension base="xsd:boolean">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="map-int-entry">
<xsd:simpleContent>
<xsd:extension base="xsd:integer">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="map-float-entry">
<xsd:simpleContent>
<xsd:extension base="xsd:float">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="map-string-entry">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="map-list-entry">
<xsd:complexContent>
<xsd:extension base="list">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="map-map-entry">
<xsd:complexContent>
<xsd:extension base="map">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="deprecated">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="package" type="xsd:string" use="required" />
<xsd:attribute name="version" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:schema>
================================================
FILE: Loader/schema/routing.schema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Symfony Routing Configuration",
"description": "Defines the application's URL routes, including imports and environment-specific conditionals.",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9_.-]+$": {
"oneOf": [
{ "$ref": "#/$defs/routeDefinition" },
{ "$ref": "#/$defs/routeImport" },
{ "$ref": "#/$defs/routeAlias" }
]
},
"^when@.+$": {
"$ref": "#",
"description": "A container for routes that are only loaded in a specific environment (e.g., 'when@dev')."
}
},
"additionalProperties": false,
"$defs": {
"routeDefinition": {
"type": "object",
"properties": {
"path": {
"oneOf": [
{ "type": "string" },
{ "type": "object", "patternProperties": { "^.+$": { "type": "string" } }, "additionalProperties": false }
],
"description": "The URL path or a map of locale=>path for localized routes."
},
"controller": {
"type": "string",
"description": "The controller that handles the request, e.g., 'App\\Controller\\BlogController::show'."
},
"methods": {
"description": "The HTTP method(s) this route matches.",
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"requirements": {
"type": "object",
"description": "Regular expression constraints for path parameters.",
"additionalProperties": { "type": "string" }
},
"defaults": { "type": "object" },
"options": { "type": "object" },
"host": {
"oneOf": [
{ "type": "string" },
{ "type": "object", "patternProperties": { "^.+$": { "type": "string" } }, "additionalProperties": false }
]
},
"schemes": {
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"condition": { "type": "string" },
"locale": { "type": "string" },
"format": { "type": "string" },
"utf8": { "type": "boolean" },
"stateless": { "type": "boolean" },
"deprecated": {
"type": "object",
"properties": {
"package": { "type": "string" },
"version": { "type": "string" },
"message": { "type": "string" }
},
"required": ["package", "version"],
"additionalProperties": false
}
},
"required": ["path"],
"additionalProperties": false
},
"routeImport": {
"type": "object",
"properties": {
"resource": {
"description": "Path to the resource to import (commonly a string or {path, namespace}), array of paths, or custom value for loaders (additional properties allowed for extensions).",
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } },
{
"type": "object",
"properties": {
"path": { "type": "string", "description": "The directory path to the resource." },
"namespace": { "type": "string", "description": "The namespace of the controllers in the imported resource (e.g., 'App\\Availability\\UserInterface\\Api')." }
},
"required": ["path"],
"additionalProperties": true
}
]
},
"type": {
"type": "string",
"description": "The type of the resource (e.g., 'attribute', 'annotation', 'yaml')."
},
"prefix": {
"oneOf": [
{ "type": "string" },
{ "type": "object", "patternProperties": { "^.+$": { "type": "string" } }, "additionalProperties": false }
],
"description": "A URL prefix to apply to all routes from the imported resource."
},
"name_prefix": {
"type": "string",
"description": "A name prefix to apply to all routes from the imported resource."
},
"requirements": { "type": "object", "additionalProperties": { "type": "string" } },
"defaults": { "type": "object" },
"options": { "type": "object" },
"host": {
"oneOf": [
{ "type": "string" },
{ "type": "object", "patternProperties": { "^.+$": { "type": "string" } }, "additionalProperties": false }
]
},
"schemes": {
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"condition": { "type": "string" },
"trailing_slash_on_root": { "type": "boolean" },
"methods": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ] },
"locale": { "type": "string" },
"format": { "type": "string" },
"utf8": { "type": "boolean" },
"exclude": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ] },
"stateless": { "type": "boolean" },
"controller": { "type": "string" }
},
"required": ["resource"],
"additionalProperties": false
},
"routeAlias": {
"type": "object",
"properties": {
"alias": { "type": "string" },
"deprecated": {
"type": "object",
"properties": {
"package": { "type": "string" },
"version": { "type": "string" },
"message": { "type": "string" }
},
"required": ["package", "version"],
"additionalProperties": false
}
},
"required": ["alias"],
"additionalProperties": false
}
}
}
================================================
FILE: Matcher/CompiledUrlMatcher.php
================================================
<?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\Matcher;
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
use Symfony\Component\Routing\RequestContext;
/**
* Matches URLs based on rules dumped by CompiledUrlMatcherDumper.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class CompiledUrlMatcher extends UrlMatcher
{
use CompiledUrlMatcherTrait;
public function __construct(array $compiledRoutes, RequestContext $context)
{
$this->context = $context;
[$this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition] = $compiledRoutes;
}
}
================================================
FILE: Matcher/Dumper/CompiledUrlMatcherDumper.php
================================================
<?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\Matcher\Dumper;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* CompiledUrlMatcherDumper creates PHP arrays to be used with CompiledUrlMatcher.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
*/
class CompiledUrlMatcherDumper extends MatcherDumper
{
private ExpressionLanguage $expressionLanguage;
private ?\Exception $signalingException = null;
/**
* @var ExpressionFunctionProviderInterface[]
*/
private array $expressionLanguageProviders = [];
public function dump(array $options = []): string
{
return <<<EOF
<?php
/**
* This file has been auto-generated
* by the Symfony Routing Component.
*/
return [
{$this->generateCompiledRoutes()}];
EOF;
}
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider): void
{
$this->expressionLanguageProviders[] = $provider;
}
/**
* Generates the arrays for CompiledUrlMatcher's constructor.
*/
public function getCompiledRoutes(bool $forDump = false): array
{
// Group hosts by same-suffix, re-order when possible
$matchHost = false;
$routes = new StaticPrefixCollection();
foreach ($this->getRoutes()->all() as $name => $route) {
if ($host = $route->getHost()) {
$matchHost = true;
$host = '/'.strtr(strrev($host), '}.{', '(/)');
}
$routes->addRoute($host ?: '/(.*)', [$name, $route]);
}
if ($matchHost) {
$compiledRoutes = [true];
$routes = $routes->populateCollection(new RouteCollection());
} else {
$compiledRoutes = [false];
$routes = $this->getRoutes();
}
[$staticRoutes, $dynamicRoutes] = $this->groupStaticRoutes($routes);
$conditions = [null];
$compiledRoutes[] = $this->compileStaticRoutes($staticRoutes, $conditions);
$chunkLimit = \count($dynamicRoutes);
while (true) {
try {
$this->signalingException = new \RuntimeException('Compilation failed: regular expression is too large');
$compiledRoutes = array_merge($compiledRoutes, $this->compileDynamicRoutes($dynamicRoutes, $matchHost, $chunkLimit, $conditions));
break;
} catch (\Exception $e) {
if (1 < $chunkLimit && $this->signalingException === $e) {
$chunkLimit = 1 + ($chunkLimit >> 1);
continue;
}
throw $e;
}
}
if ($forDump) {
$compiledRoutes[2] = $compiledRoutes[4];
}
unset($conditions[0]);
if ($conditions) {
foreach ($conditions as $expression => $condition) {
$conditions[$expression] = "case {$condition}: return {$expression};";
}
$checkConditionCode = <<<EOF
static function (\$condition, \$context, \$request, \$params) { // \$checkCondition
switch (\$condition) {
{$this->indent(implode("\n", $conditions), 3)}
}
}
EOF;
$compiledRoutes[4] = $forDump ? $checkConditionCode.",\n" : eval('return '.$checkConditionCode.';');
} else {
$compiledRoutes[4] = $forDump ? " null, // \$checkCondition\n" : null;
}
return $compiledRoutes;
}
private function generateCompiledRoutes(): string
{
[$matchHost, $staticRoutes, $regexpCode, $dynamicRoutes, $checkConditionCode] = $this->getCompiledRoutes(true);
$code = self::export($matchHost).', // $matchHost'."\n";
$code .= '[ // $staticRoutes'."\n";
foreach ($staticRoutes as $path => $routes) {
$code .= \sprintf(" %s => [\n", self::export($path));
foreach ($routes as $route) {
$code .= vsprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", array_map([__CLASS__, 'export'], $route));
}
$code .= " ],\n";
}
$code .= "],\n";
$code .= \sprintf("[ // \$regexpList%s\n],\n", $regexpCode);
$code .= '[ // $dynamicRoutes'."\n";
foreach ($dynamicRoutes as $path => $routes) {
$code .= \sprintf(" %s => [\n", self::export($path));
foreach ($routes as $route) {
$code .= vsprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", array_map([__CLASS__, 'export'], $route));
}
$code .= " ],\n";
}
$code .= "],\n";
$code = preg_replace('/ => \[\n (\[.+?),\n \],/', ' => [$1],', $code);
return $this->indent($code, 1).$checkConditionCode;
}
/**
* Splits static routes from dynamic routes, so that they can be matched first, using a simple switch.
*/
private function groupStaticRoutes(RouteCollection $collection): array
{
$staticRoutes = $dynamicRegex = [];
$dynamicRoutes = new RouteCollection();
foreach ($collection->all() as $name => $route) {
$compiledRoute = $route->compile();
$staticPrefix = rtrim($compiledRoute->getStaticPrefix(), '/');
$hostRegex = $compiledRoute->getHostRegex();
$regex = $compiledRoute->getRegex();
if ($hasTrailingSlash = '/' !== $route->getPath()) {
$pos = strrpos($regex, '$');
$hasTrailingSlash = '/' === $regex[$pos - 1];
$regex = substr_replace($regex, '/?$', $pos - $hasTrailingSlash, 1 + $hasTrailingSlash);
}
if (!$compiledRoute->getPathVariables()) {
$host = !$compiledRoute->getHostVariables() ? $route->getHost() : '';
$url = $route->getPath();
if ($hasTrailingSlash) {
$url = substr($url, 0, -1);
}
foreach ($dynamicRegex as [$hostRx, $rx, $prefix]) {
if (('' === $prefix || str_starts_with($url, $prefix)) && (preg_match($rx, $url) || preg_match($rx, $url.'/')) && (!$host || !$hostRx || preg_match($hostRx, $host))) {
$dynamicRegex[] = [$hostRegex, $regex, $staticPrefix];
$dynamicRoutes->add($name, $route);
continue 2;
}
}
$staticRoutes[$url][$name] = [$route, $hasTrailingSlash];
} else {
$dynamicRegex[] = [$hostRegex, $regex, $staticPrefix];
$dynamicRoutes->add($name, $route);
}
}
return [$staticRoutes, $dynamicRoutes];
}
/**
* Compiles static routes in a switch statement.
*
* Condition-less paths are put in a static array in the switch's default, with generic matching logic.
* Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.
*
* @throws \LogicException
*/
private function compileStaticRoutes(array $staticRoutes, array &$conditions): array
{
if (!$staticRoutes) {
return [];
}
$compiledRoutes = [];
foreach ($staticRoutes as $url => $routes) {
$compiledRoutes[$url] = [];
foreach ($routes as $name => [$route, $hasTrailingSlash]) {
if ($route->compile()->getHostVariables()) {
$host = $route->compile()->getHostRegex();
} elseif ($host = $route->getHost()) {
$host = strtolower($host);
}
$compiledRoutes[$url][] = $this->compileRoute($route, $name, $host ?: null, $hasTrailingSlash, false, $conditions);
}
}
return $compiledRoutes;
}
/**
* Compiles a regular expression followed by a switch statement to match dynamic routes.
*
* The regular expression matches both the host and the pathinfo at the same time. For stellar performance,
* it is built as a tree of patterns, with re-ordering logic to group same-prefix routes together when possible.
*
* Patterns are named so that we know which one matched (https://pcre.org/current/doc/html/pcre2syntax.html#SEC23).
* This name is used to "switch" to the additional logic required to match the final route.
*
* Condition-less paths are put in a static array in the switch's default, with generic matching logic.
* Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.
*
* Last but not least:
* - Because it is not possible to mix unicode/non-unicode patterns in a single regexp, several of them can be generated.
* - The same regexp can be used several times when the logic in the switch rejects the match. When this happens, the
* matching-but-failing subpattern is excluded by replacing its name by "(*F)", which forces a failure-to-match.
* To ease this backlisting operation, the name of subpatterns is also the string offset where the replacement should occur.
*/
private function compileDynamicRoutes(RouteCollection $collection, bool $matchHost, int $chunkLimit, array &$conditions): array
{
if (!$collection->all()) {
return [[], [], ''];
}
$regexpList = [];
$code = '';
$state = (object) [
'regexMark' => 0,
'regex' => [],
'routes' => [],
'mark' => 0,
'markTail' => 0,
'hostVars' => [],
'vars' => [],
];
$state->getVars = static function ($m) use ($state) {
if ('_route' === $m[1]) {
return '?:';
}
$state->vars[] = $m[1];
return '';
};
$chunkSize = 0;
$prev = null;
$perModifiers = [];
foreach ($collection->all() as $name => $route) {
preg_match('#[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);
if ($chunkLimit < ++$chunkSize || $prev !== $rx[0] && $route->compile()->getPathVariables()) {
$chunkSize = 1;
$routes = new RouteCollection();
$perModifiers[] = [$rx[0], $routes];
$prev = $rx[0];
}
$routes->add($name, $route);
}
foreach ($perModifiers as [$modifiers, $routes]) {
$prev = false;
$perHost = [];
foreach ($routes->all() as $name => $route) {
$regex = $route->compile()->getHostRegex();
if ($prev !== $regex) {
$routes = new RouteCollection();
$perHost[] = [$regex, $routes];
$prev = $regex;
}
$routes->add($name, $route);
}
$prev = false;
$rx = '{^(?';
$code .= "\n {$state->mark} => ".self::export($rx);
$startingMark = $state->mark;
$state->mark += \strlen($rx);
$state->regex = $rx;
foreach ($perHost as [$hostRegex, $routes]) {
if ($matchHost) {
if ($hostRegex) {
preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $hostRegex, $rx);
$state->vars = [];
$hostRegex = '(?i:'.preg_replace_callback('#\?P<([^>]++)>#', $state->getVars, $rx[1]).')\.';
$state->hostVars = $state->vars;
} else {
$hostRegex = '(?:(?:[^./]*+\.)++)';
$state->hostVars = [];
}
$state->mark += \strlen($rx = ($prev ? ')' : '')."|{$hostRegex}(?");
$code .= "\n .".self::export($rx);
$state->regex .= $rx;
$prev = true;
}
$tree = new StaticPrefixCollection();
foreach ($routes->all() as $name => $route) {
preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);
$state->vars = [];
$regex = preg_replace_callback('#\?P<([^>]++)>#', $state->getVars, $rx[1]);
if ($hasTrailingSlash = '/' !== $regex && '/' === $regex[-1]) {
$regex = substr($regex, 0, -1);
}
$hasTrailingVar = (bool) preg_match('#\{[\w\x80-\xFF]+\}/?$#', $route->getPath());
$tree->addRoute($regex, [$name, $regex, $state->vars, $route, $hasTrailingSlash, $hasTrailingVar]);
}
$code .= $this->compileStaticPrefixCollection($tree, $state, 0, $conditions);
}
if ($matchHost) {
$code .= "\n .')'";
$state->regex .= ')';
}
$rx = ")/?$}{$modifiers}";
$code .= "\n .'{$rx}',";
$state->regex .= $rx;
$state->markTail = 0;
// if the regex is too large, throw a signaling exception to recompute with smaller chunk size
set_error_handler(fn ($type, $message) => throw str_contains($message, $this->signalingException->getMessage()) ? $this->signalingException : new \ErrorException($message));
try {
preg_match($state->regex, '');
} finally {
restore_error_handler();
}
$regexpList[$startingMark] = $state->regex;
}
$state->routes[$state->mark][] = [null, null, null, null, false, false, 0];
unset($state->getVars);
return [$regexpList, $state->routes, $code];
}
/**
* Compiles a regexp tree of subpatterns that matches nested same-prefix routes.
*
* @param \stdClass $state A simple state object that keeps track of the progress of the compilation,
* and gathers the generated switch's "case" and "default" statements
*/
private function compileStaticPrefixCollection(StaticPrefixCollection $tree, \stdClass $state, int $prefixLen, array &$conditions): string
{
$code = '';
$prevRegex = null;
$routes = $tree->getRoutes();
foreach ($routes as $i => $route) {
if ($route instanceof StaticPrefixCollection) {
$prevRegex = null;
$prefix = substr($route->getPrefix(), $prefixLen);
$state->mark += \strlen($rx = "|{$prefix}(?");
$code .= "\n .".self::export($rx);
$state->regex .= $rx;
$code .= $this->indent($this->compileStaticPrefixCollection($route, $state, $prefixLen + \strlen($prefix), $conditions));
$code .= "\n .')'";
$state->regex .= ')';
++$state->markTail;
continue;
}
[$name, $regex, $vars, $route, $hasTrailingSlash, $hasTrailingVar] = $route;
$compiledRoute = $route->compile();
$vars = array_merge($state->hostVars, $vars);
if ($compiledRoute->getRegex() === $prevRegex) {
$state->routes[$state->mark][] = $this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions);
continue;
}
$state->mark += 3 + $state->markTail + \strlen($regex) - $prefixLen;
$state->markTail = 2 + \strlen($state->mark);
$rx = \sprintf('|%s(*:%s)', substr($regex, $prefixLen), $state->mark);
$code .= "\n .".self::export($rx);
$state->regex .= $rx;
$prevRegex = $compiledRoute->getRegex();
$state->routes[$state->mark] = [$this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions)];
}
return $code;
}
/**
* Compiles a single Route to PHP code used to match it against the path info.
*/
private function compileRoute(Route $route, string $name, string|array|null $vars, bool $hasTrailingSlash, bool $hasTrailingVar, array &$conditions): array
{
$defaults = $route->getDefaults();
if (isset($defaults['_canonical_route'])) {
$name = $defaults['_canonical_route'];
unset($defaults['_canonical_route']);
}
if ($condition = $route->getCondition()) {
$condition = $this->getExpressionLanguage()->compile($condition, ['context', 'request', 'params']);
$condition = $conditions[$condition] ??= (str_contains($condition, '$request') ? 1 : -1) * \count($conditions);
} else {
$condition = null;
}
return [
['_route' => $name] + $defaults,
$vars,
array_flip($route->getMethods()) ?: null,
array_flip($route->getSchemes()) ?: null,
$hasTrailingSlash,
$hasTrailingVar,
$condition,
];
}
private function getExpressionLanguage(): ExpressionLanguage
{
if (!isset($this->expressionLanguage)) {
if (!class_exists(ExpressionLanguage::class)) {
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
}
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
}
return $this->expressionLanguage;
}
private function indent(string $code, int $level = 1): string
{
return preg_replace('/^./m', str_repeat(' ', $level).'$0', $code);
}
/**
* @internal
*/
public static function export(mixed $value): string
{
if (null === $value) {
return 'null';
}
if (\is_object($value)) {
throw new \InvalidArgumentException(\sprintf('Symfony\Component\Routing\Route cannot contain objects, but "%s" given.', get_debug_type($value)));
}
if (!\is_array($value)) {
return str_replace("\n", '\'."\n".\'', var_export($value, true));
}
if (!$value) {
return '[]';
}
$i = 0;
$export = '[';
foreach ($value as $k => $v) {
if ($i === $k) {
++$i;
} else {
$export .= self::export($k).' => ';
if (\is_int($k) && $i < $k) {
$i = 1 + $k;
}
}
$export .= self::export($v).', ';
}
return substr_replace($export, ']', -2);
}
}
================================================
FILE: Matcher/Dumper/CompiledUrlMatcherTrait.php
================================================
<?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\Matcher\Dumper;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\NoConfigurationException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
use Symfony\Component\Routing\RequestContext;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*
* @property RequestContext $context
*/
trait CompiledUrlMatcherTrait
{
private bool $matchHost = false;
private array $staticRoutes = [];
private array $regexpList = [];
private array $dynamicRoutes = [];
private ?\Closure $checkCondition;
public function match(string $pathinfo): array
{
$allow = $allowSchemes = [];
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
return $ret;
}
if ($allow) {
throw new MethodNotAllowedException(array_keys($allow));
}
if (!$this instanceof RedirectableUrlMatcherInterface) {
throw new ResourceNotFoundException(\sprintf('No routes found for "%s".', $pathinfo));
}
if (!\in_array($this->context->getMethod(), ['HEAD', 'GET'], true)) {
// no-op
} elseif ($allowSchemes) {
redirect_scheme:
$scheme = $this->context->getScheme();
$this->context->setScheme(key($allowSchemes));
try {
if ($ret = $this->doMatch($pathinfo)) {
return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
}
} finally {
$this->context->setScheme($scheme);
}
} elseif ('' !== $trimmedPathinfo = rtrim($pathinfo, '/')) {
$pathinfo = $trimmedPathinfo === $pathinfo ? $pathinfo.'/' : $trimmedPathinfo;
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
return $this->redirect($pathinfo, $ret['_route']) + $ret;
}
if ($allowSchemes) {
goto redirect_scheme;
}
}
throw new ResourceNotFoundException(\sprintf('No routes found for "%s".', $pathinfo));
}
private function doMatch(string $pathinfo, array &$allow = [], array &$allowSchemes = []): array
{
$allow = $allowSchemes = [];
$pathinfo = '' === ($pathinfo = rawurldecode($pathinfo)) ? '/' : $pathinfo;
$trimmedPathinfo = '' === ($trimmedPathinfo = rtrim($pathinfo, '/')) ? '/' : $trimmedPathinfo;
$context = $this->context;
$requestMethod = $canonicalMethod = $context->getMethod();
if ($this->matchHost) {
$host = strtolower($context->getHost());
}
if ('HEAD' === $requestMethod) {
$canonicalMethod = 'GET';
}
$supportsRedirections = 'GET' === $canonicalMethod && $this instanceof RedirectableUrlMatcherInterface;
foreach ($this->staticRoutes[$trimmedPathinfo] ?? [] as [$ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash, , $condition]) {
if ($requiredHost) {
if ('{' !== $requiredHost[0] ? $requiredHost !== $host : !preg_match($requiredHost, $host, $hostMatches)) {
continue;
}
if ('{' === $requiredHost[0] && $hostMatches) {
$hostMatches['_route'] = $ret['_route'];
$ret = $this->mergeDefaults($hostMatches, $ret);
}
}
if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ??= $this->request ?: $this->createRequest($pathinfo) : null, $ret)) {
continue;
}
if ('/' !== $pathinfo && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
return $allow = $allowSchemes = [];
}
continue;
}
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
if ($hasRequiredScheme && $requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
$allow += $requiredMethods;
continue;
}
if (!$hasRequiredScheme) {
$allowSchemes += $requiredSchemes;
continue;
}
return $ret;
}
$matchedPathinfo = $this->matchHost ? $host.'.'.$pathinfo : $pathinfo;
foreach ($this->regexpList as $offset => $regex) {
while (preg_match($regex, $matchedPathinfo, $matches)) {
foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as [$ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition]) {
if (0 === $condition) { // marks the last route in the regexp
continue 3;
}
$hasTrailingVar = $trimmedPathinfo !== $pathinfo && $hasTrailingVar;
if ($hasTrailingVar && ($hasTrailingSlash || (null === $n = $matches[\count($vars)] ?? null) || '/' !== ($n[-1] ?? '/')) && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) {
if ($hasTrailingSlash) {
$matches = $n;
} else {
$hasTrailingVar = false;
}
}
foreach ($vars as $i => $v) {
if (isset($matches[1 + $i])) {
$ret[$v] = $matches[1 + $i];
}
}
if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ??= $this->request ?: $this->createRequest($pathinfo) : null, $ret)) {
continue;
}
if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {
if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {
return $allow = $allowSchemes = [];
}
continue;
}
if ($requiredSchemes && !isset($requiredSchemes[$context->getScheme()])) {
$allowSchemes += $requiredSchemes;
continue;
}
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
$allow += $requiredMethods;
continue;
}
return $ret;
}
$regex = substr_replace($regex, 'F', $m - $offset, 1 + \strlen($m));
$offset += \strlen($m);
}
}
if ('/' === $pathinfo && !$allow && !$allowSchemes) {
throw new NoConfigurationException();
}
return [];
}
}
================================================
FILE: Matcher/Dumper/MatcherDumper.php
================================================
<?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\Matcher\Dumper;
use Symfony\Component\Routing\RouteCollection;
/**
* MatcherDumper is the abstract class for all built-in matcher dumpers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class MatcherDumper implements MatcherDumperInterface
{
public function __construct(
private RouteCollection $routes,
) {
}
public function getRoutes(): RouteCollection
{
return $this->routes;
}
}
================================================
FILE: Matcher/Dumper/MatcherDumperInterface.php
================================================
<?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\Matcher\Dumper;
use Symfony\Component\Routing\RouteCollection;
/**
* MatcherDumperInterface is the interface that all matcher dumper classes must implement.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface MatcherDumperInterface
{
/**
* Dumps a set of routes to a string representation of executable code
* that can then be used to match a request against these routes.
*/
public function dump(array $options = []): string;
/**
* Gets the routes to dump.
*/
public function getRoutes(): RouteCollection;
}
================================================
FILE: Matcher/Dumper/StaticPrefixCollection.php
================================================
<?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\Matcher\Dumper;
use Symfony\Component\Routing\RouteCollection;
/**
* Prefix tree of routes preserving routes order.
*
* @author Frank de Jonge <info@frankdejonge.nl>
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class StaticPrefixCollection
{
/**
* @var string[]
*/
private array $staticPrefixes = [];
/**
* @var string[]
*/
private array $prefixes = [];
/**
* @var array[]|self[]
*/
private array $items = [];
public function __construct(
private string $prefix = '/',
) {
}
public function getPrefix(): string
{
return $this->prefix;
}
/**
* @return array[]|self[]
*/
public function getRoutes(): array
{
return $this->items;
}
/**
* Adds a route to a group.
*/
public function addRoute(string $prefix, array|self $route): void
{
[$prefix, $staticPrefix] = $this->getCommonPrefix($prefix, $prefix);
for ($i = \count($this->items) - 1; 0 <= $i; --$i) {
$item = $this->items[$i];
[$commonPrefix, $commonStaticPrefix] = $this->getCommonPrefix($prefix, $this->prefixes[$i]);
if ($this->prefix === $commonPrefix) {
// the new route and a previous one have no common prefix, let's see if they are exclusive to each others
if ($this->prefix !== $staticPrefix && $this->prefix !== $this->staticPrefixes[$i]) {
// the new route and the previous one have exclusive static prefixes
continue;
}
if ($this->prefix === $staticPrefix && $this->prefix === $this->staticPrefixes[$i]) {
// the new route and the previous one have no static prefix
break;
}
if ($this->prefixes[$i] !== $this->staticPrefixes[$i] && $this->prefix === $this->staticPrefixes[$i]) {
// the previous route is non-static and has no static prefix
break;
}
if ($prefix !== $staticPrefix && $this->prefix === $staticPrefix) {
// the new route is non-static and has no static prefix
break;
}
continue;
}
if ($item instanceof self && $this->prefixes[$i] === $commonPrefix) {
// the new route is a child of a previous one, let's nest it
$item->addRoute($prefix, $route);
} else {
// the new route and a previous one have a common prefix, let's merge them
$child = new self($commonPrefix);
[$child->prefixes[0], $child->staticPrefixes[0]] = $child->getCommonPrefix($this->prefixes[$i], $this->prefixes[$i]);
[$child->prefixes[1], $child->staticPrefixes[1]] = $child->getCommonPrefix($prefix, $prefix);
$child->items = [$this->items[$i], $route];
$this->staticPrefixes[$i] = $commonS
gitextract_lyoz_2vn/ ├── .gitattributes ├── .github/ │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ └── close-pull-request.yml ├── .gitignore ├── Alias.php ├── Attribute/ │ ├── DeprecatedAlias.php │ └── Route.php ├── CHANGELOG.md ├── CompiledRoute.php ├── DependencyInjection/ │ ├── AddExpressionLanguageProvidersPass.php │ ├── RoutingControllerPass.php │ └── RoutingResolverPass.php ├── Exception/ │ ├── ExceptionInterface.php │ ├── InvalidArgumentException.php │ ├── InvalidParameterException.php │ ├── LogicException.php │ ├── MethodNotAllowedException.php │ ├── MissingMandatoryParametersException.php │ ├── NoConfigurationException.php │ ├── ResourceNotFoundException.php │ ├── RouteCircularReferenceException.php │ ├── RouteNotFoundException.php │ └── RuntimeException.php ├── Generator/ │ ├── CompiledUrlGenerator.php │ ├── ConfigurableRequirementsInterface.php │ ├── Dumper/ │ │ ├── CompiledUrlGeneratorDumper.php │ │ ├── GeneratorDumper.php │ │ └── GeneratorDumperInterface.php │ ├── UrlGenerator.php │ └── UrlGeneratorInterface.php ├── LICENSE ├── Loader/ │ ├── AttributeClassLoader.php │ ├── AttributeDirectoryLoader.php │ ├── AttributeFileLoader.php │ ├── AttributeServicesLoader.php │ ├── ClosureLoader.php │ ├── Configurator/ │ │ ├── AliasConfigurator.php │ │ ├── CollectionConfigurator.php │ │ ├── ImportConfigurator.php │ │ ├── RouteConfigurator.php │ │ ├── RoutesReference.php │ │ ├── RoutingConfigurator.php │ │ └── Traits/ │ │ ├── AddTrait.php │ │ ├── HostTrait.php │ │ ├── LocalizedRouteTrait.php │ │ ├── PrefixTrait.php │ │ └── RouteTrait.php │ ├── ContainerLoader.php │ ├── ContentLoaderTrait.php │ ├── DirectoryLoader.php │ ├── GlobFileLoader.php │ ├── ObjectLoader.php │ ├── PhpFileLoader.php │ ├── Psr4DirectoryLoader.php │ ├── YamlFileLoader.php │ └── schema/ │ ├── routing/ │ │ └── routing-1.0.xsd │ └── routing.schema.json ├── Matcher/ │ ├── CompiledUrlMatcher.php │ ├── Dumper/ │ │ ├── CompiledUrlMatcherDumper.php │ │ ├── CompiledUrlMatcherTrait.php │ │ ├── MatcherDumper.php │ │ ├── MatcherDumperInterface.php │ │ └── StaticPrefixCollection.php │ ├── ExpressionLanguageProvider.php │ ├── RedirectableUrlMatcher.php │ ├── RedirectableUrlMatcherInterface.php │ ├── RequestMatcherInterface.php │ ├── TraceableUrlMatcher.php │ ├── UrlMatcher.php │ └── UrlMatcherInterface.php ├── README.md ├── RequestContext.php ├── RequestContextAwareInterface.php ├── Requirement/ │ ├── EnumRequirement.php │ └── Requirement.php ├── Route.php ├── RouteCollection.php ├── RouteCompiler.php ├── RouteCompilerInterface.php ├── Router.php ├── RouterInterface.php ├── Tests/ │ ├── Attribute/ │ │ └── RouteTest.php │ ├── CompiledRouteTest.php │ ├── DependencyInjection/ │ │ ├── AddExpressionLanguageProvidersPassTest.php │ │ ├── RoutingControllerPassTest.php │ │ └── RoutingResolverPassTest.php │ ├── Fixtures/ │ │ ├── AttributeFixtures/ │ │ │ ├── AbstractClassController.php │ │ │ ├── ActionPathController.php │ │ │ ├── AliasClassController.php │ │ │ ├── AliasInvokableController.php │ │ │ ├── AliasLocalizedRouteController.php │ │ │ ├── AliasRouteController.php │ │ │ ├── BazClass.php │ │ │ ├── DefaultValueController.php │ │ │ ├── DeprecatedAliasCustomMessageRouteController.php │ │ │ ├── DeprecatedAliasRouteController.php │ │ │ ├── EncodingClass.php │ │ │ ├── ExplicitLocalizedActionPathController.php │ │ │ ├── ExtendedRoute.php │ │ │ ├── ExtendedRouteOnClassController.php │ │ │ ├── ExtendedRouteOnMethodController.php │ │ │ ├── FooController.php │ │ │ ├── GlobalDefaultsClass.php │ │ │ ├── InvokableController.php │ │ │ ├── InvokableFQCNAliasConflictController.php │ │ │ ├── InvokableLocalizedController.php │ │ │ ├── InvokableMethodController.php │ │ │ ├── LocalizedActionPathController.php │ │ │ ├── LocalizedMethodActionControllers.php │ │ │ ├── LocalizedPrefixLocalizedActionController.php │ │ │ ├── LocalizedPrefixMissingLocaleActionController.php │ │ │ ├── LocalizedPrefixMissingRouteLocaleActionController.php │ │ │ ├── LocalizedPrefixWithRouteWithoutLocale.php │ │ │ ├── MethodActionControllers.php │ │ │ ├── MethodsAndSchemes.php │ │ │ ├── MissingRouteNameController.php │ │ │ ├── MultipleDeprecatedAliasRouteController.php │ │ │ ├── NothingButNameController.php │ │ │ ├── PrefixedActionLocalizedRouteController.php │ │ │ ├── PrefixedActionPathController.php │ │ │ ├── RequirementsWithoutPlaceholderNameController.php │ │ │ ├── RouteWithEnv.php │ │ │ ├── RouteWithPrefixController.php │ │ │ ├── RouteWithPriorityController.php │ │ │ └── Utf8ActionControllers.php │ │ ├── AttributedClasses/ │ │ │ ├── AbstractClass.php │ │ │ ├── BarClass.php │ │ │ ├── BazClass.php │ │ │ ├── EncodingClass.php │ │ │ ├── FooClass.php │ │ │ └── FooTrait.php │ │ ├── Attributes/ │ │ │ └── FooAttributes.php │ │ ├── AttributesFixtures/ │ │ │ ├── AttributesClassParamAfterCommaController.php │ │ │ ├── AttributesClassParamAfterParenthesisController.php │ │ │ ├── AttributesClassParamInlineAfterCommaController.php │ │ │ ├── AttributesClassParamInlineAfterParenthesisController.php │ │ │ ├── AttributesClassParamInlineQuotedAfterCommaController.php │ │ │ ├── AttributesClassParamInlineQuotedAfterParenthesisController.php │ │ │ ├── AttributesClassParamQuotedAfterCommaController.php │ │ │ └── AttributesClassParamQuotedAfterParenthesisController.php │ │ ├── CustomCompiledRoute.php │ │ ├── CustomRouteCompiler.php │ │ ├── Enum/ │ │ │ ├── TestIntBackedEnum.php │ │ │ ├── TestStringBackedEnum.php │ │ │ ├── TestStringBackedEnum2.php │ │ │ └── TestUnitEnum.php │ │ ├── OtherAnnotatedClasses/ │ │ │ ├── NoStartTagClass.php │ │ │ └── VariadicClass.php │ │ ├── Psr4Controllers/ │ │ │ ├── MyController.php │ │ │ ├── MyUnannotatedController.php │ │ │ └── SubNamespace/ │ │ │ ├── EvenDeeperNamespace/ │ │ │ │ └── MyOtherController.php │ │ │ ├── IrrelevantClass.php │ │ │ ├── IrrelevantEnum.php │ │ │ ├── IrrelevantInterface.php │ │ │ ├── MyAbstractController.php │ │ │ ├── MyChildController.php │ │ │ ├── MyControllerWithATrait.php │ │ │ └── SomeSharedImplementation.php │ │ ├── RedirectableUrlMatcher.php │ │ ├── TraceableAttributeClassLoader.php │ │ ├── alias/ │ │ │ ├── alias.php │ │ │ ├── alias.yaml │ │ │ ├── expected.php │ │ │ ├── invalid-alias.yaml │ │ │ ├── invalid-deprecated-no-package.yaml │ │ │ ├── invalid-deprecated-no-version.yaml │ │ │ └── override.yaml │ │ ├── annotated.php │ │ ├── array_routes.php │ │ ├── array_when_env.php │ │ ├── bad_format.yml │ │ ├── class-attributes.php │ │ ├── class-attributes.yaml │ │ ├── collection-defaults.php │ │ ├── controller/ │ │ │ ├── empty_wildcard/ │ │ │ │ └── .gitignore │ │ │ ├── import__controller.yml │ │ │ ├── import_controller.yml │ │ │ ├── import_override_defaults.yml │ │ │ ├── override_defaults.yml │ │ │ └── routing.yml │ │ ├── defaults.php │ │ ├── defaults.yml │ │ ├── directory/ │ │ │ ├── recurse/ │ │ │ │ ├── routes1.yml │ │ │ │ └── routes2.yml │ │ │ └── routes3.yml │ │ ├── directory_import/ │ │ │ └── import.yml │ │ ├── dumper/ │ │ │ ├── compiled_url_matcher0.php │ │ │ ├── compiled_url_matcher1.php │ │ │ ├── compiled_url_matcher10.php │ │ │ ├── compiled_url_matcher11.php │ │ │ ├── compiled_url_matcher12.php │ │ │ ├── compiled_url_matcher13.php │ │ │ ├── compiled_url_matcher14.php │ │ │ ├── compiled_url_matcher2.php │ │ │ ├── compiled_url_matcher3.php │ │ │ ├── compiled_url_matcher4.php │ │ │ ├── compiled_url_matcher5.php │ │ │ ├── compiled_url_matcher6.php │ │ │ ├── compiled_url_matcher7.php │ │ │ ├── compiled_url_matcher8.php │ │ │ └── compiled_url_matcher9.php │ │ ├── empty.yml │ │ ├── file_resource.yml │ │ ├── glob/ │ │ │ ├── bar.yml │ │ │ ├── baz.yml │ │ │ ├── import_multiple.yml │ │ │ ├── import_single.yml │ │ │ ├── php_dsl.php │ │ │ ├── php_dsl_bar.php │ │ │ └── php_dsl_baz.php │ │ ├── import_with_name_prefix/ │ │ │ └── routing.yml │ │ ├── import_with_no_trailing_slash/ │ │ │ └── routing.yml │ │ ├── imported-with-defaults.php │ │ ├── imported-with-defaults.yml │ │ ├── importer-php-returns-array-with-import.yml │ │ ├── importer-php-returns-array.php │ │ ├── importer-with-defaults.php │ │ ├── importer-with-defaults.yml │ │ ├── incomplete.yml │ │ ├── legacy_internal_scope.php │ │ ├── locale_and_host/ │ │ │ ├── import-with-host-expected-collection.php │ │ │ ├── import-with-locale-and-host-expected-collection.php │ │ │ ├── import-with-single-host-expected-collection.php │ │ │ ├── import-without-host-expected-collection.php │ │ │ ├── imported.php │ │ │ ├── imported.yml │ │ │ ├── importer-with-host.php │ │ │ ├── importer-with-host.yml │ │ │ ├── importer-with-locale-and-host.php │ │ │ ├── importer-with-locale-and-host.yml │ │ │ ├── importer-with-single-host.php │ │ │ ├── importer-with-single-host.yml │ │ │ ├── importer-without-host.php │ │ │ ├── importer-without-host.yml │ │ │ ├── priorized-host.yml │ │ │ ├── route-with-hosts-expected-collection.php │ │ │ ├── route-with-hosts.php │ │ │ └── route-with-hosts.yml │ │ ├── localized/ │ │ │ ├── imported-with-locale-but-not-localized.yml │ │ │ ├── imported-with-locale.yml │ │ │ ├── imported-with-utf8.php │ │ │ ├── imported-with-utf8.yml │ │ │ ├── importer-with-controller-default.yml │ │ │ ├── importer-with-locale-imports-non-localized-route.yml │ │ │ ├── importer-with-locale.yml │ │ │ ├── importer-with-utf8.php │ │ │ ├── importer-with-utf8.yml │ │ │ ├── importing-localized-route.yml │ │ │ ├── localized-prefix.yml │ │ │ ├── localized-route.yml │ │ │ ├── missing-locale-in-importer.yml │ │ │ ├── not-localized.yml │ │ │ ├── officially_formatted_locales.yml │ │ │ ├── route-without-path-or-locales.yml │ │ │ ├── utf8.php │ │ │ └── utf8.yml │ │ ├── nonesense_resource_plus_path.yml │ │ ├── nonesense_type_without_resource.yml │ │ ├── nonvalid.yml │ │ ├── nonvalid2.yml │ │ ├── nonvalidkeys.yml │ │ ├── php_dsl.php │ │ ├── php_dsl_i18n.php │ │ ├── php_dsl_sub.php │ │ ├── php_dsl_sub_i18n.php │ │ ├── php_dsl_sub_root.php │ │ ├── php_object_dsl.php │ │ ├── psr4-attributes.php │ │ ├── psr4-attributes.yaml │ │ ├── psr4-controllers-redirection/ │ │ │ ├── psr4-attributes.php │ │ │ └── psr4-attributes.yaml │ │ ├── psr4-controllers-redirection.php │ │ ├── psr4-controllers-redirection.yaml │ │ ├── requirements_without_placeholder_name.yml │ │ ├── special_route_name.yml │ │ ├── validpattern.php │ │ ├── validpattern.yml │ │ ├── validresource.php │ │ ├── validresource.yml │ │ ├── when-env.php │ │ ├── when-env.yml │ │ └── with_define_path_variable.php │ ├── Generator/ │ │ ├── Dumper/ │ │ │ └── CompiledUrlGeneratorDumperTest.php │ │ └── UrlGeneratorTest.php │ ├── Loader/ │ │ ├── AttributeClassLoaderTest.php │ │ ├── AttributeDirectoryLoaderTest.php │ │ ├── AttributeFileLoaderTest.php │ │ ├── AttributeServicesLoaderTest.php │ │ ├── ClosureLoaderTest.php │ │ ├── Configurator/ │ │ │ └── Traits/ │ │ │ └── PrefixTraitTest.php │ │ ├── ContainerLoaderTest.php │ │ ├── DirectoryLoaderTest.php │ │ ├── FileLocatorStub.php │ │ ├── GlobFileLoaderTest.php │ │ ├── ObjectLoaderTest.php │ │ ├── PhpFileLoaderTest.php │ │ ├── Psr4DirectoryLoaderTest.php │ │ └── YamlFileLoaderTest.php │ ├── Matcher/ │ │ ├── CompiledRedirectableUrlMatcherTest.php │ │ ├── CompiledUrlMatcherTest.php │ │ ├── Dumper/ │ │ │ ├── CompiledUrlMatcherDumperTest.php │ │ │ └── StaticPrefixCollectionTest.php │ │ ├── ExpressionLanguageProviderTest.php │ │ ├── RedirectableUrlMatcherTest.php │ │ ├── TraceableUrlMatcherTest.php │ │ └── UrlMatcherTest.php │ ├── RequestContextTest.php │ ├── Requirement/ │ │ ├── EnumRequirementTest.php │ │ └── RequirementTest.php │ ├── RouteCollectionTest.php │ ├── RouteCompilerTest.php │ ├── RouteTest.php │ └── RouterTest.php ├── composer.json └── phpunit.xml.dist
SYMBOL INDEX (1150 symbols across 176 files)
FILE: Alias.php
class Alias (line 16) | class Alias
method __construct (line 20) | public function __construct(
method withId (line 25) | public function withId(string $id): static
method getId (line 39) | public function getId(): string
method setDeprecated (line 55) | public function setDeprecated(string $package, string $version, string...
method isDeprecated (line 76) | public function isDeprecated(): bool
method getDeprecation (line 84) | public function getDeprecation(string $name): array
FILE: Attribute/DeprecatedAlias.php
class DeprecatedAlias (line 17) | class DeprecatedAlias
method __construct (line 19) | public function __construct(
FILE: Attribute/Route.php
class Route (line 18) | #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Att...
method __construct (line 51) | public function __construct(
FILE: CompiledRoute.php
class CompiledRoute (line 19) | class CompiledRoute implements \Serializable
method __construct (line 31) | public function __construct(
method __serialize (line 43) | public function __serialize(): array
method serialize (line 60) | final public function serialize(): string
method __unserialize (line 65) | public function __unserialize(array $data): void
method unserialize (line 80) | final public function unserialize(string $serialized): void
method getStaticPrefix (line 88) | public function getStaticPrefix(): string
method getRegex (line 96) | public function getRegex(): string
method getHostRegex (line 104) | public function getHostRegex(): ?string
method getTokens (line 112) | public function getTokens(): array
method getHostTokens (line 120) | public function getHostTokens(): array
method getVariables (line 128) | public function getVariables(): array
method getPathVariables (line 136) | public function getPathVariables(): array
method getHostVariables (line 144) | public function getHostVariables(): array
FILE: DependencyInjection/AddExpressionLanguageProvidersPass.php
class AddExpressionLanguageProvidersPass (line 23) | class AddExpressionLanguageProvidersPass implements CompilerPassInterface
method process (line 25) | public function process(ContainerBuilder $container): void
FILE: DependencyInjection/RoutingControllerPass.php
class RoutingControllerPass (line 21) | final class RoutingControllerPass implements CompilerPassInterface
method process (line 25) | public function process(ContainerBuilder $container): void
FILE: DependencyInjection/RoutingResolverPass.php
class RoutingResolverPass (line 24) | class RoutingResolverPass implements CompilerPassInterface
method process (line 28) | public function process(ContainerBuilder $container): void
FILE: Exception/ExceptionInterface.php
type ExceptionInterface (line 19) | interface ExceptionInterface extends \Throwable
FILE: Exception/InvalidArgumentException.php
class InvalidArgumentException (line 14) | class InvalidArgumentException extends \InvalidArgumentException impleme...
FILE: Exception/InvalidParameterException.php
class InvalidParameterException (line 19) | class InvalidParameterException extends \InvalidArgumentException implem...
FILE: Exception/LogicException.php
class LogicException (line 14) | class LogicException extends \LogicException
FILE: Exception/MethodNotAllowedException.php
class MethodNotAllowedException (line 21) | class MethodNotAllowedException extends \RuntimeException implements Exc...
method __construct (line 28) | public function __construct(array $allowedMethods, string $message = '...
method getAllowedMethods (line 40) | public function getAllowedMethods(): array
FILE: Exception/MissingMandatoryParametersException.php
class MissingMandatoryParametersException (line 20) | class MissingMandatoryParametersException extends \InvalidArgumentExcept...
method __construct (line 28) | public function __construct(string $routeName = '', array $missingPara...
method getMissingParameters (line 40) | public function getMissingParameters(): array
method getRouteName (line 45) | public function getRouteName(): string
FILE: Exception/NoConfigurationException.php
class NoConfigurationException (line 19) | class NoConfigurationException extends ResourceNotFoundException
FILE: Exception/ResourceNotFoundException.php
class ResourceNotFoundException (line 21) | class ResourceNotFoundException extends \RuntimeException implements Exc...
FILE: Exception/RouteCircularReferenceException.php
class RouteCircularReferenceException (line 14) | class RouteCircularReferenceException extends RuntimeException
method __construct (line 16) | public function __construct(string $routeId, array $path)
FILE: Exception/RouteNotFoundException.php
class RouteNotFoundException (line 19) | class RouteNotFoundException extends \InvalidArgumentException implement...
FILE: Exception/RuntimeException.php
class RuntimeException (line 14) | class RuntimeException extends \RuntimeException implements ExceptionInt...
FILE: Generator/CompiledUrlGenerator.php
class CompiledUrlGenerator (line 21) | class CompiledUrlGenerator extends UrlGenerator
method __construct (line 25) | public function __construct(
method generate (line 36) | public function generate(string $name, array $parameters = [], int $re...
FILE: Generator/ConfigurableRequirementsInterface.php
type ConfigurableRequirementsInterface (line 38) | interface ConfigurableRequirementsInterface
method setStrictRequirements (line 44) | public function setStrictRequirements(?bool $enabled): void;
method isStrictRequirements (line 50) | public function isStrictRequirements(): ?bool;
FILE: Generator/Dumper/CompiledUrlGeneratorDumper.php
class CompiledUrlGeneratorDumper (line 25) | class CompiledUrlGeneratorDumper extends GeneratorDumper
method getCompiledRoutes (line 27) | public function getCompiledRoutes(): array
method getCompiledAliases (line 47) | public function getCompiledAliases(): array
method dump (line 96) | public function dump(array $options = []): string
method generateDeclaredRoutes (line 113) | private function generateDeclaredRoutes(): string
FILE: Generator/Dumper/GeneratorDumper.php
class GeneratorDumper (line 21) | abstract class GeneratorDumper implements GeneratorDumperInterface
method __construct (line 23) | public function __construct(
method getRoutes (line 28) | public function getRoutes(): RouteCollection
FILE: Generator/Dumper/GeneratorDumperInterface.php
type GeneratorDumperInterface (line 21) | interface GeneratorDumperInterface
method dump (line 27) | public function dump(array $options = []): string;
method getRoutes (line 32) | public function getRoutes(): RouteCollection;
FILE: Generator/UrlGenerator.php
class UrlGenerator (line 28) | class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequire...
method __construct (line 76) | public function __construct(
method setContext (line 84) | public function setContext(RequestContext $context): void
method getContext (line 89) | public function getContext(): RequestContext
method setStrictRequirements (line 94) | public function setStrictRequirements(?bool $enabled): void
method isStrictRequirements (line 99) | public function isStrictRequirements(): ?bool
method generate (line 104) | public function generate(string $name, array $parameters = [], int $re...
method doGenerate (line 144) | protected function doGenerate(array $variables, array $defaults, array...
method getRelativePath (line 325) | public static function getRelativePath(string $basePath, string $targe...
FILE: Generator/UrlGeneratorInterface.php
type UrlGeneratorInterface (line 32) | interface UrlGeneratorInterface extends RequestContextAwareInterface
method generate (line 79) | public function generate(string $name, array $parameters = [], int $re...
FILE: Loader/AttributeClassLoader.php
class AttributeClassLoader (line 56) | abstract class AttributeClassLoader implements LoaderInterface
method __construct (line 61) | public function __construct(
method setRouteAttributeClass (line 69) | public function setRouteAttributeClass(string $class): void
method load (line 77) | public function load(mixed $class, ?string $type = null): RouteCollection
method addRoute (line 145) | protected function addRoute(RouteCollection $collection, object $attr,...
method supports (line 247) | public function supports(mixed $resource, ?string $type = null): bool
method setResolver (line 252) | public function setResolver(LoaderResolverInterface $resolver): void
method getResolver (line 256) | public function getResolver(): LoaderResolverInterface
method getDefaultRouteName (line 264) | protected function getDefaultRouteName(\ReflectionClass $class, \Refle...
method getGlobals (line 279) | protected function getGlobals(\ReflectionClass $class): array
method resetGlobals (line 338) | private function resetGlobals(): array
method createRoute (line 356) | protected function createRoute(string $path, array $defaults, array $r...
method configureRoute (line 364) | abstract protected function configureRoute(Route $route, \ReflectionCl...
method getAttributes (line 369) | private function getAttributes(\ReflectionClass|\ReflectionMethod $ref...
FILE: Loader/AttributeDirectoryLoader.php
class AttributeDirectoryLoader (line 24) | class AttributeDirectoryLoader extends AttributeFileLoader
method load (line 29) | public function load(mixed $path, ?string $type = null): ?RouteCollection
method supports (line 64) | public function supports(mixed $resource, ?string $type = null): bool
FILE: Loader/AttributeFileLoader.php
class AttributeFileLoader (line 26) | class AttributeFileLoader extends FileLoader
method __construct (line 28) | public function __construct(
method load (line 44) | public function load(mixed $file, ?string $type = null): ?RouteCollection
method supports (line 64) | public function supports(mixed $resource, ?string $type = null): bool
method findClass (line 72) | protected function findClass(string $file): string|false
FILE: Loader/AttributeServicesLoader.php
class AttributeServicesLoader (line 22) | final class AttributeServicesLoader extends Loader
method __construct (line 27) | public function __construct(
method load (line 32) | public function load(mixed $resource, ?string $type = null): RouteColl...
method supports (line 43) | public function supports(mixed $resource, ?string $type = null): bool
FILE: Loader/ClosureLoader.php
class ClosureLoader (line 24) | class ClosureLoader extends Loader
method load (line 29) | public function load(mixed $closure, ?string $type = null): RouteColle...
method supports (line 34) | public function supports(mixed $resource, ?string $type = null): bool
FILE: Loader/Configurator/AliasConfigurator.php
class AliasConfigurator (line 17) | class AliasConfigurator
method __construct (line 19) | public function __construct(
method deprecate (line 35) | public function deprecate(string $package, string $version, string $me...
FILE: Loader/Configurator/CollectionConfigurator.php
class CollectionConfigurator (line 20) | class CollectionConfigurator
method __construct (line 28) | public function __construct(
method __serialize (line 39) | public function __serialize(): array
method __unserialize (line 44) | public function __unserialize(array $data): void
method __destruct (line 49) | public function __destruct()
method collection (line 64) | final public function collection(string $name = ''): self
method prefix (line 76) | final public function prefix(string|array $prefix): static
method host (line 109) | final public function host(string|array $host): static
method createRoute (line 119) | private function createRoute(string $path): Route
FILE: Loader/Configurator/ImportConfigurator.php
class ImportConfigurator (line 19) | class ImportConfigurator
method __construct (line 25) | public function __construct(
method __serialize (line 32) | public function __serialize(): array
method __unserialize (line 37) | public function __unserialize(array $data): void
method __destruct (line 42) | public function __destruct()
method prefix (line 54) | final public function prefix(string|array $prefix, bool $trailingSlash...
method namePrefix (line 66) | final public function namePrefix(string $namePrefix): static
method host (line 80) | final public function host(string|array $host): static
FILE: Loader/Configurator/RouteConfigurator.php
class RouteConfigurator (line 19) | class RouteConfigurator
method __construct (line 25) | public function __construct(
method host (line 45) | final public function host(string|array $host): static
FILE: Loader/Configurator/RoutesReference.php
class RoutesReference (line 75) | class RoutesReference
method config (line 82) | public static function config(array $config): array
FILE: Loader/Configurator/RoutingConfigurator.php
class RoutingConfigurator (line 20) | class RoutingConfigurator
method __construct (line 24) | public function __construct(
method import (line 37) | final public function import(string|array $resource, ?string $type = n...
method collection (line 54) | final public function collection(string $name = ''): CollectionConfigu...
method env (line 62) | final public function env(): ?string
method withPath (line 67) | final public function withPath(string $path): static
FILE: Loader/Configurator/Traits/AddTrait.php
type AddTrait (line 22) | trait AddTrait
method add (line 35) | public function add(string $name, string|array $path): RouteConfigurator
method alias (line 43) | public function alias(string $name, string $alias): AliasConfigurator
method __invoke (line 53) | public function __invoke(string $name, string|array $path): RouteConfi...
FILE: Loader/Configurator/Traits/HostTrait.php
type HostTrait (line 19) | trait HostTrait
method addHost (line 21) | final protected function addHost(RouteCollection $routes, string|array...
FILE: Loader/Configurator/Traits/LocalizedRouteTrait.php
type LocalizedRouteTrait (line 23) | trait LocalizedRouteTrait
method createLocalizedRoute (line 30) | final protected function createLocalizedRoute(RouteCollection $collect...
method createRoute (line 72) | private function createRoute(string $path): Route
FILE: Loader/Configurator/Traits/PrefixTrait.php
type PrefixTrait (line 22) | trait PrefixTrait
method addPrefix (line 24) | final protected function addPrefix(RouteCollection $routes, string|arr...
FILE: Loader/Configurator/Traits/RouteTrait.php
type RouteTrait (line 17) | trait RouteTrait
method defaults (line 26) | final public function defaults(array $defaults): static
method requirements (line 38) | final public function requirements(array $requirements): static
method options (line 50) | final public function options(array $options): static
method utf8 (line 62) | final public function utf8(bool $utf8 = true): static
method condition (line 74) | final public function condition(string $condition): static
method host (line 86) | final public function host(string $pattern): static
method schemes (line 101) | final public function schemes(array $schemes): static
method methods (line 116) | final public function methods(array $methods): static
method controller (line 130) | final public function controller(callable|string|array $controller): s...
method locale (line 142) | final public function locale(string $locale): static
method format (line 154) | final public function format(string $format): static
method stateless (line 166) | final public function stateless(bool $stateless = true): static
FILE: Loader/ContainerLoader.php
class ContainerLoader (line 21) | class ContainerLoader extends ObjectLoader
method __construct (line 23) | public function __construct(
method supports (line 30) | public function supports(mixed $resource, ?string $type = null): bool
method getObject (line 35) | protected function getObject(string $id): object
FILE: Loader/ContentLoaderTrait.php
type ContentLoaderTrait (line 21) | trait ContentLoaderTrait
method loadContent (line 30) | private function loadContent(RouteCollection $collection, array $confi...
method parseRoute (line 56) | private function parseRoute(RouteCollection $collection, string $name,...
method parseImport (line 116) | private function parseImport(RouteCollection $collection, array $confi...
method validate (line 186) | private function validate(mixed $config, string $name, string $path): ...
method validateAlias (line 220) | private function validateAlias(array $config, string $name, string $pa...
FILE: Loader/DirectoryLoader.php
class DirectoryLoader (line 18) | class DirectoryLoader extends FileLoader
method load (line 20) | public function load(mixed $file, ?string $type = null): mixed
method supports (line 46) | public function supports(mixed $resource, ?string $type = null): bool
FILE: Loader/GlobFileLoader.php
class GlobFileLoader (line 22) | class GlobFileLoader extends FileLoader
method load (line 24) | public function load(mixed $resource, ?string $type = null): mixed
method supports (line 37) | public function supports(mixed $resource, ?string $type = null): bool
FILE: Loader/ObjectLoader.php
class ObjectLoader (line 23) | abstract class ObjectLoader extends Loader
method getObject (line 31) | abstract protected function getObject(string $id): object;
method load (line 36) | public function load(mixed $resource, ?string $type = null): RouteColl...
method addClassResource (line 65) | private function addClassResource(\ReflectionClass $class, RouteCollec...
FILE: Loader/PhpFileLoader.php
class PhpFileLoader (line 31) | class PhpFileLoader extends FileLoader
method load (line 38) | public function load(mixed $file, ?string $type = null): RouteCollection
method supports (line 72) | public function supports(mixed $resource, ?string $type = null): bool
method callConfigurator (line 77) | protected function callConfigurator(callable $callback, string $path, ...
FILE: Loader/Psr4DirectoryLoader.php
class Psr4DirectoryLoader (line 26) | final class Psr4DirectoryLoader extends Loader implements DirectoryAware...
method __construct (line 30) | public function __construct(
method load (line 40) | public function load(mixed $resource, ?string $type = null): ?RouteCol...
method supports (line 55) | public function supports(mixed $resource, ?string $type = null): bool
method forDirectory (line 60) | public function forDirectory(string $currentDirectory): static
method loadFromDirectory (line 68) | private function loadFromDirectory(string $directory, string $psr4Pref...
FILE: Loader/YamlFileLoader.php
class YamlFileLoader (line 28) | class YamlFileLoader extends FileLoader
method load (line 42) | public function load(mixed $file, ?string $type = null): RouteCollection
method supports (line 80) | public function supports(mixed $resource, ?string $type = null): bool
method parseRoute (line 88) | protected function parseRoute(RouteCollection $collection, string $nam...
method parseImport (line 96) | protected function parseImport(RouteCollection $collection, array $con...
method validate (line 105) | protected function validate(mixed $config, string $name, string $path)...
FILE: Matcher/CompiledUrlMatcher.php
class CompiledUrlMatcher (line 22) | class CompiledUrlMatcher extends UrlMatcher
method __construct (line 26) | public function __construct(array $compiledRoutes, RequestContext $con...
FILE: Matcher/Dumper/CompiledUrlMatcherDumper.php
class CompiledUrlMatcherDumper (line 27) | class CompiledUrlMatcherDumper extends MatcherDumper
method dump (line 37) | public function dump(array $options = []): string
method addExpressionLanguageProvider (line 53) | public function addExpressionLanguageProvider(ExpressionFunctionProvid...
method getCompiledRoutes (line 61) | public function getCompiledRoutes(bool $forDump = false): array
method generateCompiledRoutes (line 129) | private function generateCompiledRoutes(): string
method groupStaticRoutes (line 164) | private function groupStaticRoutes(RouteCollection $collection): array
method compileStaticRoutes (line 212) | private function compileStaticRoutes(array $staticRoutes, array &$cond...
method compileDynamicRoutes (line 252) | private function compileDynamicRoutes(RouteCollection $collection, boo...
method compileStaticPrefixCollection (line 376) | private function compileStaticPrefixCollection(StaticPrefixCollection ...
method compileRoute (line 421) | private function compileRoute(Route $route, string $name, string|array...
method getExpressionLanguage (line 448) | private function getExpressionLanguage(): ExpressionLanguage
method indent (line 460) | private function indent(string $code, int $level = 1): string
method export (line 468) | public static function export(mixed $value): string
FILE: Matcher/Dumper/CompiledUrlMatcherTrait.php
type CompiledUrlMatcherTrait (line 27) | trait CompiledUrlMatcherTrait
method match (line 35) | public function match(string $pathinfo): array
method doMatch (line 73) | private function doMatch(string $pathinfo, array &$allow = [], array &...
FILE: Matcher/Dumper/MatcherDumper.php
class MatcherDumper (line 21) | abstract class MatcherDumper implements MatcherDumperInterface
method __construct (line 23) | public function __construct(
method getRoutes (line 28) | public function getRoutes(): RouteCollection
FILE: Matcher/Dumper/MatcherDumperInterface.php
type MatcherDumperInterface (line 21) | interface MatcherDumperInterface
method dump (line 27) | public function dump(array $options = []): string;
method getRoutes (line 32) | public function getRoutes(): RouteCollection;
FILE: Matcher/Dumper/StaticPrefixCollection.php
class StaticPrefixCollection (line 24) | class StaticPrefixCollection
method __construct (line 41) | public function __construct(
method getPrefix (line 46) | public function getPrefix(): string
method getRoutes (line 54) | public function getRoutes(): array
method addRoute (line 62) | public function addRoute(string $prefix, array|self $route): void
method populateCollection (line 125) | public function populateCollection(RouteCollection $routes): RouteColl...
method getCommonPrefix (line 143) | private function getCommonPrefix(string $prefix, string $anotherPrefix...
method handleError (line 197) | public static function handleError(int $type, string $msg): bool
FILE: Matcher/ExpressionLanguageProvider.php
class ExpressionLanguageProvider (line 23) | class ExpressionLanguageProvider implements ExpressionFunctionProviderIn...
method __construct (line 25) | public function __construct(
method getFunctions (line 30) | public function getFunctions(): array
method get (line 45) | public function get(string $function): callable
FILE: Matcher/RedirectableUrlMatcher.php
class RedirectableUrlMatcher (line 20) | abstract class RedirectableUrlMatcher extends UrlMatcher implements Redi...
method match (line 22) | public function match(string $pathinfo): array
FILE: Matcher/RedirectableUrlMatcherInterface.php
type RedirectableUrlMatcherInterface (line 19) | interface RedirectableUrlMatcherInterface
method redirect (line 28) | public function redirect(string $path, string $route, ?string $scheme ...
FILE: Matcher/RequestMatcherInterface.php
type RequestMatcherInterface (line 24) | interface RequestMatcherInterface
method matchRequest (line 36) | public function matchRequest(Request $request): array;
FILE: Matcher/TraceableUrlMatcher.php
class TraceableUrlMatcher (line 24) | class TraceableUrlMatcher extends UrlMatcher
method getTraces (line 32) | public function getTraces(string $pathinfo): array
method getTracesForRequest (line 44) | public function getTracesForRequest(Request $request): array
method matchCollection (line 53) | protected function matchCollection(string $pathinfo, RouteCollection $...
method addTrace (line 157) | private function addTrace(string $log, int $level = self::ROUTE_DOES_N...
FILE: Matcher/UrlMatcher.php
class UrlMatcher (line 29) | class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
method __construct (line 54) | public function __construct(
method setContext (line 60) | public function setContext(RequestContext $context): void
method getContext (line 65) | public function getContext(): RequestContext
method match (line 70) | public function match(string $pathinfo): array
method matchRequest (line 86) | public function matchRequest(Request $request): array
method addExpressionLanguageProvider (line 97) | public function addExpressionLanguageProvider(ExpressionFunctionProvid...
method matchCollection (line 111) | protected function matchCollection(string $pathinfo, RouteCollection $...
method getAttributes (line 192) | protected function getAttributes(Route $route, string $name, array $at...
method handleRouteRequirements (line 213) | protected function handleRouteRequirements(string $pathinfo, string $n...
method mergeDefaults (line 230) | protected function mergeDefaults(array $params, array $defaults): array
method getExpressionLanguage (line 241) | protected function getExpressionLanguage(): ExpressionLanguage
method createRequest (line 256) | protected function createRequest(string $pathinfo): ?Request
FILE: Matcher/UrlMatcherInterface.php
type UrlMatcherInterface (line 24) | interface UrlMatcherInterface extends RequestContextAwareInterface
method match (line 38) | public function match(string $pathinfo): array;
FILE: RequestContext.php
class RequestContext (line 24) | class RequestContext
method __construct (line 36) | public function __construct(string $baseUrl = '', string $method = 'GE...
method fromUri (line 49) | public static function fromUri(string $uri, string $host = 'localhost'...
method fromRequest (line 78) | public function fromRequest(Request $request): static
method getBaseUrl (line 95) | public function getBaseUrl(): string
method setBaseUrl (line 105) | public function setBaseUrl(string $baseUrl): static
method getPathInfo (line 115) | public function getPathInfo(): string
method setPathInfo (line 125) | public function setPathInfo(string $pathInfo): static
method getMethod (line 137) | public function getMethod(): string
method setMethod (line 147) | public function setMethod(string $method): static
method getHost (line 159) | public function getHost(): string
method setHost (line 169) | public function setHost(string $host): static
method getScheme (line 179) | public function getScheme(): string
method setScheme (line 189) | public function setScheme(string $scheme): static
method getHttpPort (line 199) | public function getHttpPort(): int
method setHttpPort (line 209) | public function setHttpPort(int $httpPort): static
method getHttpsPort (line 219) | public function getHttpsPort(): int
method setHttpsPort (line 229) | public function setHttpsPort(int $httpsPort): static
method getQueryString (line 239) | public function getQueryString(): string
method setQueryString (line 249) | public function setQueryString(?string $queryString): static
method getParameters (line 260) | public function getParameters(): array
method setParameters (line 272) | public function setParameters(array $parameters): static
method getParameter (line 282) | public function getParameter(string $name): mixed
method hasParameter (line 290) | public function hasParameter(string $name): bool
method setParameter (line 300) | public function setParameter(string $name, mixed $parameter): static
method isSecure (line 307) | public function isSecure(): bool
FILE: RequestContextAwareInterface.php
type RequestContextAwareInterface (line 14) | interface RequestContextAwareInterface
method setContext (line 19) | public function setContext(RequestContext $context): void;
method getContext (line 24) | public function getContext(): RequestContext;
FILE: Requirement/EnumRequirement.php
class EnumRequirement (line 16) | final class EnumRequirement implements \Stringable
method __construct (line 25) | public function __construct(string|array $cases = [])
method __toString (line 52) | public function __toString(): string
FILE: Route.php
class Route (line 20) | class Route implements \Serializable
method __construct (line 49) | public function __construct(string $path, array $defaults = [], array ...
method __serialize (line 61) | public function __serialize(): array
method serialize (line 79) | final public function serialize(): string
method __unserialize (line 84) | public function __unserialize(array $data): void
method unserialize (line 105) | final public function unserialize(string $serialized): void
method getPath (line 110) | public function getPath(): string
method setPath (line 118) | public function setPath(string $pattern): static
method getHost (line 130) | public function getHost(): string
method setHost (line 138) | public function setHost(?string $pattern): static
method getSchemes (line 152) | public function getSchemes(): array
method setSchemes (line 165) | public function setSchemes(string|array $schemes): static
method hasScheme (line 176) | public function hasScheme(string $scheme): bool
method getMethods (line 187) | public function getMethods(): array
method setMethods (line 200) | public function setMethods(string|array $methods): static
method getOptions (line 208) | public function getOptions(): array
method setOptions (line 216) | public function setOptions(array $options): static
method addOptions (line 228) | public function addOptions(array $options): static
method setOption (line 243) | public function setOption(string $name, mixed $value): static
method getOption (line 254) | public function getOption(string $name): mixed
method hasOption (line 259) | public function hasOption(string $name): bool
method getDefaults (line 264) | public function getDefaults(): array
method setDefaults (line 272) | public function setDefaults(array $defaults): static
method addDefaults (line 282) | public function addDefaults(array $defaults): static
method getDefault (line 296) | public function getDefault(string $name): mixed
method hasDefault (line 301) | public function hasDefault(string $name): bool
method setDefault (line 309) | public function setDefault(string $name, mixed $default): static
method getRequirements (line 321) | public function getRequirements(): array
method setRequirements (line 329) | public function setRequirements(array $requirements): static
method addRequirements (line 339) | public function addRequirements(array $requirements): static
method getRequirement (line 353) | public function getRequirement(string $key): ?string
method hasRequirement (line 358) | public function hasRequirement(string $key): bool
method setRequirement (line 366) | public function setRequirement(string $key, string $regex): static
method getCondition (line 378) | public function getCondition(): string
method setCondition (line 386) | public function setCondition(?string $condition): static
method compile (line 402) | public function compile(): CompiledRoute
method extractInlineDefaultsAndRequirements (line 413) | private function extractInlineDefaultsAndRequirements(string $pattern)...
method sanitizeRequirement (line 442) | private function sanitizeRequirement(string $key, string $regex): string
method isLocalized (line 465) | private function isLocalized(): bool
FILE: RouteCollection.php
class RouteCollection (line 30) | class RouteCollection implements \IteratorAggregate, \Countable
method __clone (line 52) | public function __clone()
method getIterator (line 72) | public function getIterator(): \ArrayIterator
method count (line 80) | public function count(): int
method add (line 85) | public function add(string $name, Route $route, int $priority = 0): void
method all (line 101) | public function all(): array
method get (line 115) | public function get(string $name): ?Route
method remove (line 143) | public function remove(string|array $name): void
method addCollection (line 169) | public function addCollection(self $collection): void
method addPrefix (line 196) | public function addPrefix(string $prefix, array $defaults = [], array ...
method addNamePrefix (line 214) | public function addNamePrefix(string $prefix): void
method setHost (line 248) | public function setHost(?string $pattern, array $defaults = [], array ...
method setCondition (line 262) | public function setCondition(?string $condition): void
method addDefaults (line 274) | public function addDefaults(array $defaults): void
method addRequirements (line 288) | public function addRequirements(array $requirements): void
method addOptions (line 302) | public function addOptions(array $options): void
method setSchemes (line 316) | public function setSchemes(string|array $schemes): void
method setMethods (line 328) | public function setMethods(string|array $methods): void
method getResources (line 340) | public function getResources(): array
method addResource (line 349) | public function addResource(ResourceInterface $resource): void
method addAlias (line 366) | public function addAlias(string $name, string $alias): Alias
method getAliases (line 380) | public function getAliases(): array
method getAlias (line 385) | public function getAlias(string $name): ?Alias
method getPriority (line 390) | public function getPriority(string $name): ?int
FILE: RouteCompiler.php
class RouteCompiler (line 20) | class RouteCompiler implements RouteCompilerInterface
method compile (line 43) | public static function compile(Route $route): CompiledRoute
method compilePattern (line 99) | private static function compilePattern(Route $route, string $pattern, ...
method determineStaticPrefix (line 247) | private static function determineStaticPrefix(Route $route, array $tok...
method findNextSeparator (line 265) | private static function findNextSeparator(string $pattern, bool $useUt...
method computeRegexp (line 289) | private static function computeRegexp(array $tokens, int $index, int $...
method transformCapturingGroupsToNonCapturings (line 319) | private static function transformCapturingGroupsToNonCapturings(string...
FILE: RouteCompilerInterface.php
type RouteCompilerInterface (line 19) | interface RouteCompilerInterface
method compile (line 27) | public static function compile(Route $route): CompiledRoute;
FILE: Router.php
class Router (line 38) | class Router implements RouterInterface, RequestMatcherInterface
method __construct (line 55) | public function __construct(
method setOptions (line 84) | public function setOptions(array $options): void
method setOption (line 117) | public function setOption(string $key, mixed $value): void
method getOption (line 131) | public function getOption(string $key): mixed
method getRouteCollection (line 140) | public function getRouteCollection(): RouteCollection
method setContext (line 145) | public function setContext(RequestContext $context): void
method getContext (line 157) | public function getContext(): RequestContext
method setConfigCacheFactory (line 165) | public function setConfigCacheFactory(ConfigCacheFactoryInterface $con...
method generate (line 170) | public function generate(string $name, array $parameters = [], int $re...
method match (line 175) | public function match(string $pathinfo): array
method matchRequest (line 180) | public function matchRequest(Request $request): array
method getMatcher (line 194) | public function getMatcher(): UrlMatcherInterface|RequestMatcherInterface
method getGenerator (line 236) | public function getGenerator(): UrlGeneratorInterface
method addExpressionLanguageProvider (line 270) | public function addExpressionLanguageProvider(ExpressionFunctionProvid...
method getGeneratorDumperInstance (line 275) | protected function getGeneratorDumperInstance(): GeneratorDumperInterface
method getMatcherDumperInstance (line 280) | protected function getMatcherDumperInstance(): MatcherDumperInterface
method getConfigCacheFactory (line 289) | private function getConfigCacheFactory(): ConfigCacheFactoryInterface
method getCompiledRoutes (line 294) | private static function getCompiledRoutes(string $path): array
FILE: RouterInterface.php
type RouterInterface (line 24) | interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInter...
method getRouteCollection (line 32) | public function getRouteCollection(): RouteCollection;
FILE: Tests/Attribute/RouteTest.php
class RouteTest (line 19) | class RouteTest extends TestCase
method testLoadFromAttribute (line 21) | #[DataProvider('getValidParameters')]
method getValidParameters (line 29) | public static function getValidParameters(): iterable
FILE: Tests/CompiledRouteTest.php
class CompiledRouteTest (line 17) | class CompiledRouteTest extends TestCase
method testAccessors (line 19) | public function testAccessors()
FILE: Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php
class AddExpressionLanguageProvidersPassTest (line 20) | class AddExpressionLanguageProvidersPassTest extends TestCase
method testProcessForRouter (line 22) | public function testProcessForRouter()
method testProcessForRouterAlias (line 41) | public function testProcessForRouterAlias()
FILE: Tests/DependencyInjection/RoutingControllerPassTest.php
class RoutingControllerPassTest (line 19) | class RoutingControllerPassTest extends TestCase
method testProcessInjectsTaggedControllerClassesOrderedAndUnique (line 21) | public function testProcessInjectsTaggedControllerClassesOrderedAndUni...
method testProcessWithNoTaggedControllersSetsEmptyList (line 42) | public function testProcessWithNoTaggedControllersSetsEmptyList()
FILE: Tests/DependencyInjection/RoutingResolverPassTest.php
class RoutingResolverPassTest (line 20) | class RoutingResolverPassTest extends TestCase
method testProcess (line 22) | public function testProcess()
FILE: Tests/Fixtures/AttributeFixtures/AbstractClassController.php
class AbstractClassController (line 5) | abstract class AbstractClassController
FILE: Tests/Fixtures/AttributeFixtures/ActionPathController.php
class ActionPathController (line 7) | class ActionPathController
method action (line 9) | #[Route('/path', name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/AliasClassController.php
class AliasClassController (line 17) | #[Route('/hello', alias: ['alias', 'completely_different_name'])]
method actionWorld (line 20) | #[Route('/world')]
method actionSymfony (line 25) | #[Route('/symfony')]
FILE: Tests/Fixtures/AttributeFixtures/AliasInvokableController.php
class AliasInvokableController (line 17) | #[Route('/path', name:'invokable_path', alias: ['alias', 'completely_dif...
method __invoke (line 20) | public function __invoke()
FILE: Tests/Fixtures/AttributeFixtures/AliasLocalizedRouteController.php
class AliasLocalizedRouteController (line 16) | class AliasLocalizedRouteController
method localized (line 18) | #[Route(['nl_NL' => '/nl/localized', 'fr_FR' => '/fr/localized'], name...
FILE: Tests/Fixtures/AttributeFixtures/AliasRouteController.php
class AliasRouteController (line 16) | class AliasRouteController
method action (line 18) | #[Route('/path', name: 'action_with_alias', alias: ['alias', 'complete...
FILE: Tests/Fixtures/AttributeFixtures/BazClass.php
class BazClass (line 16) | #[
method __invoke (line 22) | public function __invoke()
FILE: Tests/Fixtures/AttributeFixtures/DefaultValueController.php
class DefaultValueController (line 10) | class DefaultValueController
method action (line 12) | #[Route(path: '/{default}/path', name: 'action')]
method hello (line 17) | #[
method stringEnumAction (line 25) | #[Route(path: '/enum/{default}', name: 'string_enum_action')]
method intEnumAction (line 30) | #[Route(path: '/enum/{default<\d+>}', name: 'int_enum_action')]
method defaultMappedParam (line 35) | #[Route(path: '/defaultMappedParam/{libelle:bar}', name: 'defaultMappe...
method defaultAdvancedMappedParam (line 40) | #[Route(path: '/defaultAdvancedMappedParam/{barLibelle:bar.libelle}', ...
FILE: Tests/Fixtures/AttributeFixtures/DeprecatedAliasCustomMessageRouteController.php
class DeprecatedAliasCustomMessageRouteController (line 17) | class DeprecatedAliasCustomMessageRouteController
method action (line 20) | #[Route('/path', name: 'action_with_deprecated_alias', alias: new Depr...
FILE: Tests/Fixtures/AttributeFixtures/DeprecatedAliasRouteController.php
class DeprecatedAliasRouteController (line 17) | class DeprecatedAliasRouteController
method action (line 19) | #[Route('/path', name: 'action_with_deprecated_alias', alias: new Depr...
FILE: Tests/Fixtures/AttributeFixtures/EncodingClass.php
class EncodingClass (line 7) | class EncodingClass
method routeÀction (line 9) | #[Route]
FILE: Tests/Fixtures/AttributeFixtures/ExplicitLocalizedActionPathController.php
class ExplicitLocalizedActionPathController (line 7) | class ExplicitLocalizedActionPathController
method action (line 9) | #[Route(path: ['en' => '/path', 'nl' => '/pad'], name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/ExtendedRoute.php
class ExtendedRoute (line 7) | #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Att...
method __construct (line 10) | public function __construct(array|string|null $path = null, ?string $n...
FILE: Tests/Fixtures/AttributeFixtures/ExtendedRouteOnClassController.php
class ExtendedRouteOnClassController (line 7) | #[ExtendedRoute('/class-level')]
method action (line 10) | #[Route(path: '/method-level', name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/ExtendedRouteOnMethodController.php
class ExtendedRouteOnMethodController (line 5) | class ExtendedRouteOnMethodController
method action (line 7) | #[ExtendedRoute(path: '/method-level', name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/FooController.php
class FooController (line 7) | class FooController
method simplePath (line 9) | #[Route('/Blog')]
method localized (line 14) | #[Route(['nl' => '/hier', 'en' => '/here'])]
method requirements (line 19) | #[Route(requirements: ['locale' => 'en'])]
method options (line 24) | #[Route(options: ['compiler_class' => 'RouteCompiler'])]
method name (line 29) | #[Route(name: 'blog_index')]
method defaults (line 34) | #[Route(defaults: ['_controller' => 'MyBlogBundle:Blog:index'])]
method schemes (line 39) | #[Route(schemes: ['https'])]
method methods (line 44) | #[Route(methods: ['GET', 'POST'])]
method host (line 49) | #[Route(host: '{locale}.example.com')]
method condition (line 54) | #[Route(condition: 'context.getMethod() == \'GET\'')]
method alias (line 59) | #[Route(alias: ['alias', 'completely_different_name'])]
FILE: Tests/Fixtures/AttributeFixtures/GlobalDefaultsClass.php
class GlobalDefaultsClass (line 16) | #[Route(path: '/defaults', methods: ['GET'], schemes: ['https'], locale:...
method locale (line 19) | #[Route(path: '/specific-locale', name: 'specific_locale', locale: 's_...
method format (line 24) | #[Route(path: '/specific-format', name: 'specific_format', format: 's_...
method redundantMethod (line 29) | #[Route(path: '/redundant-method', name: 'redundant_method', methods:...
method redundantScheme (line 34) | #[Route(path: '/redundant-scheme', name: 'redundant_scheme', schemes: ...
FILE: Tests/Fixtures/AttributeFixtures/InvokableController.php
class InvokableController (line 7) | #[Route(path: '/here', name: 'lol', methods: ["GET", "POST"], schemes: [...
method __invoke (line 10) | public function __invoke()
FILE: Tests/Fixtures/AttributeFixtures/InvokableFQCNAliasConflictController.php
class InvokableFQCNAliasConflictController (line 7) | #[Route(path: '/foobarccc', name: self::class)]
method __invoke (line 10) | public function __invoke()
FILE: Tests/Fixtures/AttributeFixtures/InvokableLocalizedController.php
class InvokableLocalizedController (line 7) | #[Route(path: ["nl" => "/hier", "en" => "/here"], name: 'action')]
method __invoke (line 10) | public function __invoke()
FILE: Tests/Fixtures/AttributeFixtures/InvokableMethodController.php
class InvokableMethodController (line 7) | class InvokableMethodController
method __invoke (line 9) | #[Route(path: '/here', name: 'lol', methods: ["GET", "POST"], schemes:...
FILE: Tests/Fixtures/AttributeFixtures/LocalizedActionPathController.php
class LocalizedActionPathController (line 7) | class LocalizedActionPathController
method action (line 9) | #[Route(path: ['en' => '/path', 'nl' => '/pad'], name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/LocalizedMethodActionControllers.php
class LocalizedMethodActionControllers (line 7) | #[Route(path: ['en' => '/the/path', 'nl' => '/het/pad'])]
method post (line 10) | #[Route(name: 'post', methods: ['POST'])]
method put (line 15) | #[Route(name: 'put', methods: ['PUT'])]
FILE: Tests/Fixtures/AttributeFixtures/LocalizedPrefixLocalizedActionController.php
class LocalizedPrefixLocalizedActionController (line 7) | #[Route(path: ['nl' => '/nl', 'en' => '/en'])]
method action (line 10) | #[Route(path: ['nl' => '/actie', 'en' => '/action'], name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/LocalizedPrefixMissingLocaleActionController.php
class LocalizedPrefixMissingLocaleActionController (line 7) | #[Route(path: ['nl' => '/nl'])]
method action (line 10) | #[Route(path: ['nl' => '/actie', 'en' => '/action'], name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/LocalizedPrefixMissingRouteLocaleActionController.php
class LocalizedPrefixMissingRouteLocaleActionController (line 7) | #[Route(path: ['nl' => '/nl', 'en' => '/en'])]
method action (line 10) | #[Route(path: ['nl' => '/actie'], name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/LocalizedPrefixWithRouteWithoutLocale.php
class LocalizedPrefixWithRouteWithoutLocale (line 7) | #[Route(path: ['en' => '/en', 'nl' => '/nl'])]
method action (line 10) | #[Route(path: '/suffix', name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/MethodActionControllers.php
class MethodActionControllers (line 7) | #[Route('/the/path')]
method post (line 10) | #[Route(name: 'post', methods: ['POST'])]
method put (line 15) | #[Route(name: 'put', methods: ['PUT'], priority: 10)]
FILE: Tests/Fixtures/AttributeFixtures/MethodsAndSchemes.php
class MethodsAndSchemes (line 7) | final class MethodsAndSchemes
method arrayMany (line 9) | #[Route(path: '/array-many', name: 'array_many', methods: ['GET', 'POS...
method arrayOne (line 14) | #[Route(path: '/array-one', name: 'array_one', methods: ['GET'], schem...
method string (line 19) | #[Route(path: '/string', name: 'string', methods: 'POST', schemes: 'ht...
FILE: Tests/Fixtures/AttributeFixtures/MissingRouteNameController.php
class MissingRouteNameController (line 7) | class MissingRouteNameController
method action (line 9) | #[Route('/path')]
FILE: Tests/Fixtures/AttributeFixtures/MultipleDeprecatedAliasRouteController.php
class MultipleDeprecatedAliasRouteController (line 17) | class MultipleDeprecatedAliasRouteController
method action (line 19) | #[Route('/path', name: 'action_with_multiple_deprecated_alias', alias: [
FILE: Tests/Fixtures/AttributeFixtures/NothingButNameController.php
class NothingButNameController (line 7) | class NothingButNameController
method action (line 9) | #[Route(name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/PrefixedActionLocalizedRouteController.php
class PrefixedActionLocalizedRouteController (line 7) | #[Route('/prefix')]
method action (line 10) | #[Route(path: ['en' => '/path', 'nl' => '/pad'], name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/PrefixedActionPathController.php
class PrefixedActionPathController (line 7) | #[Route(path: '/prefix', host: 'frankdejonge.nl', condition: 'lol=fun')]
method action (line 10) | #[Route(path: '/path', name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/RequirementsWithoutPlaceholderNameController.php
class RequirementsWithoutPlaceholderNameController (line 16) | #[Route(path: '/', requirements: ['foo', '\d+'])]
method foo (line 19) | #[Route(path: '/{foo}', name: 'foo', requirements: ['foo', '\d+'])]
FILE: Tests/Fixtures/AttributeFixtures/RouteWithEnv.php
class RouteWithEnv (line 7) | #[Route(env: 'some-env')]
method action (line 10) | #[Route(path: '/path', name: 'action')]
method action2 (line 15) | #[Route(path: '/path2', name: 'action2', env: 'some-other-env')]
method action3 (line 20) | #[Route(path: '/path3', name: 'action3', env: ['some-other-env', 'some...
method action4 (line 25) | #[Route(path: '/path4', name: 'action4', env: null)]
method action5 (line 30) | #[Route(path: '/path5', name: 'action5', env: ['some-other-env', 'some...
FILE: Tests/Fixtures/AttributeFixtures/RouteWithPrefixController.php
class RouteWithPrefixController (line 7) | #[Route('/prefix')]
method action (line 10) | #[Route(path: '/path', name: 'action')]
FILE: Tests/Fixtures/AttributeFixtures/RouteWithPriorityController.php
class RouteWithPriorityController (line 7) | class RouteWithPriorityController
method important (line 9) | #[Route('/important', name: 'important', priority: 2)]
method alsoImportant (line 14) | #[Route('/also-important', name: 'also_important', priority: 1, defaul...
FILE: Tests/Fixtures/AttributeFixtures/Utf8ActionControllers.php
class Utf8ActionControllers (line 7) | #[Route('/test', utf8: true)]
method one (line 10) | #[Route(name: 'one')]
method two (line 15) | #[Route(name: 'two', utf8: false)]
FILE: Tests/Fixtures/AttributedClasses/AbstractClass.php
class AbstractClass (line 16) | abstract class AbstractClass
method abstractRouteAction (line 18) | abstract public function abstractRouteAction();
method routeAction (line 20) | #[Route('/path/to/route/{arg1}')]
FILE: Tests/Fixtures/AttributedClasses/BarClass.php
class BarClass (line 14) | class BarClass
method routeAction (line 16) | public function routeAction($arg1, $arg2 = 'defaultValue2', $arg3 = 'd...
FILE: Tests/Fixtures/AttributedClasses/BazClass.php
class BazClass (line 14) | class BazClass
method __invoke (line 16) | public function __invoke()
FILE: Tests/Fixtures/AttributedClasses/EncodingClass.php
class EncodingClass (line 5) | class EncodingClass
method routeÀction (line 7) | public function routeÀction()
FILE: Tests/Fixtures/AttributedClasses/FooClass.php
class FooClass (line 14) | class FooClass
FILE: Tests/Fixtures/AttributedClasses/FooTrait.php
type FooTrait (line 5) | trait FooTrait
method doBar (line 7) | public function doBar()
FILE: Tests/Fixtures/Attributes/FooAttributes.php
class FooAttributes (line 5) | #[\Attribute(\Attribute::TARGET_CLASS)]
method __construct (line 11) | public function __construct(string $class, array $foo)
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php
class AttributesClassParamAfterCommaController (line 7) | #[FooAttributes(
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php
class AttributesClassParamAfterParenthesisController (line 7) | #[FooAttributes(
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php
class AttributesClassParamInlineAfterCommaController (line 7) | #[FooAttributes(foo: ['bar' => ['foo','bar'],'foo'],class: \stdClass::cl...
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php
class AttributesClassParamInlineAfterParenthesisController (line 7) | #[FooAttributes(class: \stdClass::class,foo: ['bar' => ['foo','bar'],'fo...
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php
class AttributesClassParamInlineQuotedAfterCommaController (line 7) | #[FooAttributes(foo: ['bar' => ['foo','bar'],'foo'],class: 'Symfony\Comp...
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php
class AttributesClassParamInlineQuotedAfterParenthesisController (line 7) | #[FooAttributes(class: \stdClass::class,foo: ['bar' => ['foo','bar'],'fo...
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php
class AttributesClassParamQuotedAfterCommaController (line 7) | #[FooAttributes(
FILE: Tests/Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php
class AttributesClassParamQuotedAfterParenthesisController (line 7) | #[FooAttributes(
FILE: Tests/Fixtures/CustomCompiledRoute.php
class CustomCompiledRoute (line 16) | class CustomCompiledRoute extends CompiledRoute
FILE: Tests/Fixtures/CustomRouteCompiler.php
class CustomRouteCompiler (line 18) | class CustomRouteCompiler extends RouteCompiler
method compile (line 20) | public static function compile(Route $route): CompiledRoute
FILE: Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php
class VariadicClass (line 16) | class VariadicClass
method routeAction (line 18) | #[Route('/path/to/{id}')]
FILE: Tests/Fixtures/Psr4Controllers/MyController.php
class MyController (line 17) | #[Route('/my/route', name: 'my_route')]
method __invoke (line 20) | public function __invoke(): Response
FILE: Tests/Fixtures/Psr4Controllers/MyUnannotatedController.php
class MyUnannotatedController (line 16) | final class MyUnannotatedController
method myAction (line 18) | public function myAction(): Response
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/EvenDeeperNamespace/MyOtherController.php
class MyOtherController (line 17) | #[Route('/my/other/route', name: 'my_other_controller_', methods: ['PUT'])]
method firstAction (line 20) | #[Route('/first', name: 'one')]
method secondAction (line 26) | #[Route('/second', name: 'two')]
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantClass.php
class IrrelevantClass (line 22) | final class IrrelevantClass
method irrelevantAction (line 24) | public function irrelevantAction(): Response
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantInterface.php
type IrrelevantInterface (line 14) | interface IrrelevantInterface
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/MyAbstractController.php
class MyAbstractController (line 17) | abstract class MyAbstractController
method someAction (line 19) | #[Route('/a/route/from/an/abstract/controller', name: 'from_abstract')]
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/MyChildController.php
class MyChildController (line 16) | #[Route('/my/child/controller', name: 'my_child_controller_')]
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/MyControllerWithATrait.php
class MyControllerWithATrait (line 16) | #[Route('/my/controller/with/a/trait', name: 'my_controller_')]
FILE: Tests/Fixtures/Psr4Controllers/SubNamespace/SomeSharedImplementation.php
type SomeSharedImplementation (line 17) | trait SomeSharedImplementation
method someAction (line 19) | #[Route('/a/route/from/a/trait', name: 'with_a_trait')]
FILE: Tests/Fixtures/RedirectableUrlMatcher.php
class RedirectableUrlMatcher (line 20) | class RedirectableUrlMatcher extends UrlMatcher implements RedirectableU...
method redirect (line 22) | public function redirect(string $path, string $route, ?string $scheme ...
FILE: Tests/Fixtures/TraceableAttributeClassLoader.php
class TraceableAttributeClassLoader (line 18) | final class TraceableAttributeClassLoader extends AttributeClassLoader
method load (line 23) | public function load(mixed $class, ?string $type = null): RouteCollection
method configureRoute (line 34) | protected function configureRoute(Route $route, \ReflectionClass $clas...
FILE: Tests/Fixtures/php_object_dsl.php
method __invoke (line 6) | public function __invoke(RoutingConfigurator $routes)
FILE: Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php
class CompiledUrlGeneratorDumperTest (line 25) | class CompiledUrlGeneratorDumperTest extends TestCase
method setUp (line 32) | protected function setUp(): void
method tearDown (line 42) | protected function tearDown(): void
method testDumpWithRoutes (line 48) | public function testDumpWithRoutes()
method testDumpWithSimpleLocalizedRoutes (line 68) | public function testDumpWithSimpleLocalizedRoutes()
method testDumpWithRouteNotFoundLocalizedRoutes (line 100) | public function testDumpWithRouteNotFoundLocalizedRoutes()
method testDumpWithFallbackLocaleLocalizedRoutes (line 115) | public function testDumpWithFallbackLocaleLocalizedRoutes()
method testDumpWithTooManyRoutes (line 138) | public function testDumpWithTooManyRoutes()
method testDumpWithoutRoutes (line 161) | public function testDumpWithoutRoutes()
method testGenerateNonExistingRoute (line 172) | public function testGenerateNonExistingRoute()
method testDumpForRouteWithDefaults (line 185) | public function testDumpForRouteWithDefaults()
method testDumpWithSchemeRequirement (line 197) | public function testDumpWithSchemeRequirement()
method testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl (line 220) | public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheU...
method testLocalizedAliasRouteGeneratesCorrectUrlPerLocale (line 245) | public function testLocalizedAliasRouteGeneratesCorrectUrlPerLocale()
method testAliases (line 264) | public function testAliases()
method testTargetAliasNotExisting (line 287) | public function testTargetAliasNotExisting()
method testTargetAliasWithNamePrefixNotExisting (line 303) | public function testTargetAliasWithNamePrefixNotExisting()
method testCircularReferenceShouldThrowAnException (line 323) | public function testCircularReferenceShouldThrowAnException()
method testDeepCircularReferenceShouldThrowAnException (line 334) | public function testDeepCircularReferenceShouldThrowAnException()
method testIndirectCircularReferenceShouldThrowAnException (line 346) | public function testIndirectCircularReferenceShouldThrowAnException()
method testDeprecatedAlias (line 358) | #[IgnoreDeprecations]
method testDeprecatedAliasWithCustomMessage (line 374) | #[IgnoreDeprecations]
method testTargettingADeprecatedAliasShouldTriggerDeprecation (line 390) | #[IgnoreDeprecations]
FILE: Tests/Generator/UrlGeneratorTest.php
class UrlGeneratorTest (line 28) | class UrlGeneratorTest extends TestCase
method testAbsoluteUrlWithPort80 (line 30) | public function testAbsoluteUrlWithPort80()
method testAbsoluteSecureUrlWithPort443 (line 38) | public function testAbsoluteSecureUrlWithPort443()
method testAbsoluteUrlWithNonStandardPort (line 46) | public function testAbsoluteUrlWithNonStandardPort()
method testAbsoluteSecureUrlWithNonStandardPort (line 54) | public function testAbsoluteSecureUrlWithNonStandardPort()
method testRelativeUrlWithoutParameters (line 62) | public function testRelativeUrlWithoutParameters()
method testRelativeUrlWithParameter (line 70) | public function testRelativeUrlWithParameter()
method testRelativeUrlWithNullParameter (line 78) | public function testRelativeUrlWithNullParameter()
method testRelativeUrlWithNullParameterButNotOptional (line 86) | public function testRelativeUrlWithNullParameterButNotOptional()
method testRelativeUrlWithOptionalZeroParameter (line 97) | public function testRelativeUrlWithOptionalZeroParameter()
method testNotPassedOptionalParameterInBetween (line 105) | public function testNotPassedOptionalParameterInBetween()
method testRelativeUrlWithExtraParameters (line 112) | #[DataProvider('valuesProvider')]
method testAbsoluteUrlWithExtraParameters (line 121) | #[DataProvider('valuesProvider')]
method valuesProvider (line 130) | public static function valuesProvider(): array
method testUrlWithExtraParametersFromGlobals (line 155) | public function testUrlWithExtraParametersFromGlobals()
method testUrlWithGlobalParameter (line 167) | public function testUrlWithGlobalParameter()
method testGlobalParameterHasHigherPriorityThanDefault (line 179) | public function testGlobalParameterHasHigherPriorityThanDefault()
method testGenerateWithDefaultLocale (line 191) | public function testGenerateWithDefaultLocale()
method testGenerateWithOverriddenParameterLocale (line 216) | public function testGenerateWithOverriddenParameterLocale()
method testGenerateWithOverriddenParameterLocaleFromRequestContext (line 241) | public function testGenerateWithOverriddenParameterLocaleFromRequestCo...
method testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl (line 270) | public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheU...
method testLocalizedAliasRouteGeneratesCorrectUrlPerLocale (line 293) | public function testLocalizedAliasRouteGeneratesCorrectUrlPerLocale()
method testGenerateWithoutRoutes (line 310) | public function testGenerateWithoutRoutes()
method testGenerateWithInvalidLocale (line 319) | public function testGenerateWithInvalidLocale()
method testGenerateForRouteWithoutMandatoryParameter (line 341) | public function testGenerateForRouteWithoutMandatoryParameter()
method testGenerateForRouteWithInvalidOptionalParameter (line 351) | public function testGenerateForRouteWithInvalidOptionalParameter()
method testGenerateForRouteWithInvalidParameter (line 360) | public function testGenerateForRouteWithInvalidParameter()
method testGenerateForRouteWithInvalidOptionalParameterNonStrict (line 369) | public function testGenerateForRouteWithInvalidOptionalParameterNonStr...
method testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger (line 377) | public function testGenerateForRouteWithInvalidOptionalParameterNonStr...
method testGenerateForRouteWithInvalidParameterButDisabledRequirementsCheck (line 388) | public function testGenerateForRouteWithInvalidParameterButDisabledReq...
method testGenerateForRouteWithInvalidMandatoryParameter (line 396) | public function testGenerateForRouteWithInvalidMandatoryParameter()
method testGenerateForRouteWithInvalidUtf8Parameter (line 405) | public function testGenerateForRouteWithInvalidUtf8Parameter()
method testRequiredParamAndEmptyPassed (line 414) | public function testRequiredParamAndEmptyPassed()
method testSchemeRequirementDoesNothingIfSameCurrentScheme (line 423) | public function testSchemeRequirementDoesNothingIfSameCurrentScheme()
method testSchemeRequirementForcesAbsoluteUrl (line 432) | public function testSchemeRequirementForcesAbsoluteUrl()
method testSchemeRequirementCreatesUrlForFirstRequiredScheme (line 441) | public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()
method testPathWithTwoStartingSlashes (line 447) | public function testPathWithTwoStartingSlashes()
method testNoTrailingSlashForMultipleOptionalParameters (line 455) | public function testNoTrailingSlashForMultipleOptionalParameters()
method testWithAnIntegerAsADefaultValue (line 462) | public function testWithAnIntegerAsADefaultValue()
method testNullForOptionalParameterIsIgnored (line 469) | public function testNullForOptionalParameterIsIgnored()
method testQueryParamSameAsDefault (line 476) | public function testQueryParamSameAsDefault()
method testArrayQueryParamSameAsDefault (line 486) | public function testArrayQueryParamSameAsDefault()
method testGenerateWithSpecialRouteName (line 497) | public function testGenerateWithSpecialRouteName()
method testUrlEncoding (line 504) | public function testUrlEncoding()
method testEncodingOfRelativePathSegments (line 520) | public function testEncodingOfRelativePathSegments()
method testEncodingOfSlashInPath (line 530) | public function testEncodingOfSlashInPath()
method testEncodingOfSlashInQueryParameters (line 536) | public function testEncodingOfSlashInQueryParameters()
method testAdjacentVariables (line 543) | public function testAdjacentVariables()
method testOptionalVariableWithNoRealSeparator (line 556) | public function testOptionalVariableWithNoRealSeparator()
method testRequiredVariableWithNoRealSeparator (line 565) | public function testRequiredVariableWithNoRealSeparator()
method testDefaultRequirementOfVariable (line 573) | public function testDefaultRequirementOfVariable()
method testImportantVariable (line 581) | public function testImportantVariable()
method testImportantVariableWithNoDefault (line 591) | public function testImportantVariableWithNoDefault()
method testDefaultRequirementOfVariableDisallowsSlash (line 602) | public function testDefaultRequirementOfVariableDisallowsSlash()
method testDefaultRequirementOfVariableDisallowsNextSeparator (line 611) | public function testDefaultRequirementOfVariableDisallowsNextSeparator()
method testWithHostDifferentFromContext (line 620) | public function testWithHostDifferentFromContext()
method testWithHostSameAsContext (line 627) | public function testWithHostSameAsContext()
method testWithHostSameAsContextAndAbsolute (line 634) | public function testWithHostSameAsContextAndAbsolute()
method testUrlWithInvalidParameterInHost (line 641) | public function testUrlWithInvalidParameterInHost()
method testUrlWithInvalidParameterInHostWhenParamHasADefaultValue (line 650) | public function testUrlWithInvalidParameterInHostWhenParamHasADefaultV...
method testUrlWithInvalidParameterEqualsDefaultValueInHost (line 659) | public function testUrlWithInvalidParameterEqualsDefaultValueInHost()
method testUrlWithInvalidParameterInHostInNonStrictMode (line 668) | public function testUrlWithInvalidParameterInHostInNonStrictMode()
method testHostIsCaseInsensitive (line 676) | public function testHostIsCaseInsensitive()
method testDefaultHostIsUsedWhenContextHostIsEmpty (line 683) | public function testDefaultHostIsUsedWhenContextHostIsEmpty()
method testDefaultHostIsUsedWhenContextHostIsEmptyAndPathReferenceType (line 693) | public function testDefaultHostIsUsedWhenContextHostIsEmptyAndPathRefe...
method testAbsoluteUrlFallbackToPathIfHostIsEmptyAndSchemeIsHttp (line 703) | public function testAbsoluteUrlFallbackToPathIfHostIsEmptyAndSchemeIsH...
method testAbsoluteUrlFallbackToNetworkIfSchemeIsEmptyAndHostIsNot (line 714) | public function testAbsoluteUrlFallbackToNetworkIfSchemeIsEmptyAndHost...
method testAbsoluteUrlFallbackToPathIfSchemeAndHostAreEmpty (line 725) | public function testAbsoluteUrlFallbackToPathIfSchemeAndHostAreEmpty()
method testAbsoluteUrlWithNonHttpSchemeAndEmptyHost (line 736) | public function testAbsoluteUrlWithNonHttpSchemeAndEmptyHost()
method testGenerateNetworkPath (line 747) | public function testGenerateNetworkPath()
method testGenerateRelativePath (line 765) | public function testGenerateRelativePath()
method testAliases (line 799) | public function testAliases()
method testAliasWhichTargetRouteDoesntExist (line 812) | public function testAliasWhichTargetRouteDoesntExist()
method testDeprecatedAlias (line 822) | #[IgnoreDeprecations]
method testDeprecatedAliasWithCustomMessage (line 835) | #[IgnoreDeprecations]
method testTargettingADeprecatedAliasShouldTriggerDeprecation (line 848) | #[IgnoreDeprecations]
method testCircularReferenceShouldThrowAnException (line 862) | public function testCircularReferenceShouldThrowAnException()
method testDeepCircularReferenceShouldThrowAnException (line 874) | public function testDeepCircularReferenceShouldThrowAnException()
method testIndirectCircularReferenceShouldThrowAnException (line 887) | public function testIndirectCircularReferenceShouldThrowAnException()
method testGetRelativePath (line 900) | #[DataProvider('provideRelativePaths')]
method provideRelativePaths (line 906) | public static function provideRelativePaths()
method testFragmentsCanBeAppendedToUrls (line 1012) | public function testFragmentsCanBeAppendedToUrls()
method testFragmentsDoNotEscapeValidCharacters (line 1023) | public function testFragmentsDoNotEscapeValidCharacters()
method testFragmentsCanBeDefinedAsDefaults (line 1031) | public function testFragmentsCanBeDefinedAsDefaults()
method testLookRoundRequirementsInPath (line 1039) | #[DataProvider('provideLookAroundRequirementsInPath')]
method provideLookAroundRequirementsInPath (line 1046) | public static function provideLookAroundRequirementsInPath()
method testUtf8VarName (line 1054) | public function testUtf8VarName()
method testQueryParameters (line 1060) | public function testQueryParameters()
method testRouteHostParameterAndQueryParameterWithSameName (line 1076) | public function testRouteHostParameterAndQueryParameterWithSameName()
method testRoutePathParameterAndQueryParameterWithSameName (line 1089) | public function testRoutePathParameterAndQueryParameterWithSameName()
method testQueryParameterCannotSubstituteRouteParameter (line 1101) | public function testQueryParameterCannotSubstituteRouteParameter()
method testQueryParametersWithScalarValue (line 1115) | public function testQueryParametersWithScalarValue()
method getGenerator (line 1127) | protected function getGenerator(RouteCollection $routes, array $parame...
method getRoutes (line 1138) | protected function getRoutes($name, Route $route)
class StringableObject (line 1147) | class StringableObject
method __toString (line 1149) | public function __toString(): string
class StringableObjectWithPublicProperty (line 1155) | class StringableObjectWithPublicProperty
method __toString (line 1159) | public function __toString(): string
class NonStringableObject (line 1165) | class NonStringableObject
class NonStringableObjectWithPublicProperty (line 1169) | class NonStringableObjectWithPublicProperty
FILE: Tests/Loader/AttributeClassLoaderTest.php
class AttributeClassLoaderTest (line 55) | class AttributeClassLoaderTest extends TestCase
method setUp (line 59) | protected function setUp(?string $env = null): void
method testGetResolver (line 64) | public function testGetResolver()
method testSupportsChecksResource (line 72) | #[DataProvider('provideTestSupportsChecksResource')]
method provideTestSupportsChecksResource (line 78) | public static function provideTestSupportsChecksResource(): array
method testSupportsChecksTypeIfSpecified (line 91) | public function testSupportsChecksTypeIfSpecified()
method testSimplePathRoute (line 97) | public function testSimplePathRoute()
method testRequirementsWithoutPlaceholderName (line 105) | public function testRequirementsWithoutPlaceholderName()
method testInvokableControllerLoader (line 113) | public function testInvokableControllerLoader()
method testInvokableFQCNAliasConflictController (line 124) | public function testInvokableFQCNAliasConflictController()
method testInvokableMethodControllerLoader (line 133) | public function testInvokableMethodControllerLoader()
method testInvokableLocalizedControllerLoading (line 144) | public function testInvokableLocalizedControllerLoading()
method testLocalizedPathRoutes (line 152) | public function testLocalizedPathRoutes()
method testLocalizedPathRoutesWithExplicitPathPropety (line 163) | public function testLocalizedPathRoutesWithExplicitPathPropety()
method testDefaultValuesForMethods (line 171) | public function testDefaultValuesForMethods()
method testMethodActionControllers (line 187) | public function testMethodActionControllers()
method testInvokableClassRouteLoadWithMethodAttribute (line 197) | public function testInvokableClassRouteLoadWithMethodAttribute()
method testGlobalDefaultsRoutesLoadWithAttribute (line 205) | public function testGlobalDefaultsRoutesLoadWithAttribute()
method testUtf8RoutesLoadWithAttribute (line 226) | public function testUtf8RoutesLoadWithAttribute()
method testRouteWithPathWithPrefix (line 234) | public function testRouteWithPathWithPrefix()
method testLocalizedRouteWithPathWithPrefix (line 244) | public function testLocalizedRouteWithPathWithPrefix()
method testLocalizedPrefixLocalizedRoute (line 252) | public function testLocalizedPrefixLocalizedRoute()
method testInvokableClassMultipleRouteLoad (line 260) | public function testInvokableClassMultipleRouteLoad()
method testMissingPrefixLocale (line 276) | public function testMissingPrefixLocale()
method testMissingRouteLocale (line 283) | public function testMissingRouteLocale()
method testRouteWithoutName (line 290) | public function testRouteWithoutName()
method testNothingButName (line 297) | public function testNothingButName()
method testNonExistingClass (line 304) | public function testNonExistingClass()
method testLoadingAbstractClass (line 310) | public function testLoadingAbstractClass()
method testLocalizedPrefixWithoutRouteLocale (line 316) | public function testLocalizedPrefixWithoutRouteLocale()
method testLoadingRouteWithPrefix (line 324) | public function testLoadingRouteWithPrefix()
method testWhenEnv (line 331) | public function testWhenEnv()
method testMethodsAndSchemes (line 344) | public function testMethodsAndSchemes()
method testLoadingExtendedRouteOnClass (line 356) | public function testLoadingExtendedRouteOnClass()
method testLoadingExtendedRouteOnMethod (line 364) | public function testLoadingExtendedRouteOnMethod()
method testDefaultRouteName (line 372) | public function testDefaultRouteName()
method testAliasesOnMethod (line 380) | public function testAliasesOnMethod()
method testLocalizedRouteWithAliases (line 390) | public function testLocalizedRouteWithAliases()
method testThrowsWithAliasesOnClass (line 406) | public function testThrowsWithAliasesOnClass()
method testAliasesOnInvokableClass (line 414) | public function testAliasesOnInvokableClass()
method testDeprecatedAlias (line 424) | public function testDeprecatedAlias()
method testDeprecatedAliasWithCustomMessage (line 440) | public function testDeprecatedAliasWithCustomMessage()
method testMultipleDeprecatedAlias (line 456) | public function testMultipleDeprecatedAlias()
FILE: Tests/Loader/AttributeDirectoryLoaderTest.php
class AttributeDirectoryLoaderTest (line 23) | class AttributeDirectoryLoaderTest extends TestCase
method setUp (line 28) | protected function setUp(): void
method testLoad (line 34) | public function testLoad()
method testSupports (line 46) | public function testSupports()
method testItSupportsAnyAttribute (line 57) | public function testItSupportsAnyAttribute()
method testLoadFileIfLocatedResourceIsFile (line 62) | public function testLoadFileIfLocatedResourceIsFile()
method testLoadAbstractClass (line 68) | public function testLoadAbstractClass()
FILE: Tests/Loader/AttributeFileLoaderTest.php
class AttributeFileLoaderTest (line 29) | class AttributeFileLoaderTest extends TestCase
method setUp (line 34) | protected function setUp(): void
method testLoad (line 40) | public function testLoad()
method testLoadTraitWithClassConstant (line 46) | public function testLoadTraitWithClassConstant()
method testLoadFileWithoutStartTag (line 52) | public function testLoadFileWithoutStartTag()
method testLoadVariadic (line 59) | public function testLoadVariadic()
method testLoadAbstractClass (line 65) | public function testLoadAbstractClass()
method testSupports (line 71) | public function testSupports()
method testLoadAttributesClassAfterComma (line 82) | public function testLoadAttributesClassAfterComma()
method testLoadAttributesInlineClassAfterComma (line 88) | public function testLoadAttributesInlineClassAfterComma()
method testLoadAttributesQuotedClassAfterComma (line 94) | public function testLoadAttributesQuotedClassAfterComma()
method testLoadAttributesInlineQuotedClassAfterComma (line 100) | public function testLoadAttributesInlineQuotedClassAfterComma()
method testLoadAttributesClassAfterParenthesis (line 106) | public function testLoadAttributesClassAfterParenthesis()
method testLoadAttributesInlineClassAfterParenthesis (line 112) | public function testLoadAttributesInlineClassAfterParenthesis()
method testLoadAttributesQuotedClassAfterParenthesis (line 118) | public function testLoadAttributesQuotedClassAfterParenthesis()
method testLoadAttributesInlineQuotedClassAfterParenthesis (line 124) | public function testLoadAttributesInlineQuotedClassAfterParenthesis()
FILE: Tests/Loader/AttributeServicesLoaderTest.php
class AttributeServicesLoaderTest (line 21) | class AttributeServicesLoaderTest extends TestCase
method testSupports (line 23) | public function testSupports()
method testDelegatesToAttributeLoaderAndMergesCollections (line 33) | public function testDelegatesToAttributeLoaderAndMergesCollections()
FILE: Tests/Loader/ClosureLoaderTest.php
class ClosureLoaderTest (line 19) | class ClosureLoaderTest extends TestCase
method testSupports (line 21) | public function testSupports()
method testLoad (line 34) | public function testLoad()
FILE: Tests/Loader/Configurator/Traits/PrefixTraitTest.php
class PrefixTraitTest (line 19) | class PrefixTraitTest extends TestCase
method testAddLocalizedPrefixUpdatesAliases (line 21) | public function testAddLocalizedPrefixUpdatesAliases()
FILE: Tests/Loader/ContainerLoaderTest.php
class ContainerLoaderTest (line 19) | class ContainerLoaderTest extends TestCase
method testSupports (line 21) | #[DataProvider('supportsProvider')]
method supportsProvider (line 27) | public static function supportsProvider()
FILE: Tests/Loader/DirectoryLoaderTest.php
class DirectoryLoaderTest (line 24) | class DirectoryLoaderTest extends TestCase
method setUp (line 28) | protected function setUp(): void
method testLoadDirectory (line 40) | public function testLoadDirectory()
method testImportDirectory (line 46) | public function testImportDirectory()
method verifyCollection (line 52) | private function verifyCollection(RouteCollection $collection)
method testSupports (line 64) | public function testSupports()
FILE: Tests/Loader/FileLocatorStub.php
class FileLocatorStub (line 16) | class FileLocatorStub implements FileLocatorInterface
method locate (line 18) | public function locate(string $name, ?string $currentPath = null, bool...
FILE: Tests/Loader/GlobFileLoaderTest.php
class GlobFileLoaderTest (line 20) | class GlobFileLoaderTest extends TestCase
method testSupports (line 22) | public function testSupports()
method testLoadAddsTheGlobResourceToTheContainer (line 30) | public function testLoadAddsTheGlobResourceToTheContainer()
class GlobFileLoaderWithoutImport (line 39) | class GlobFileLoaderWithoutImport extends GlobFileLoader
method import (line 41) | public function import(mixed $resource, ?string $type = null, bool $ig...
FILE: Tests/Loader/ObjectLoaderTest.php
class ObjectLoaderTest (line 20) | class ObjectLoaderTest extends TestCase
method testLoadCallsServiceAndReturnsCollection (line 22) | public function testLoadCallsServiceAndReturnsCollection()
method testExceptionWithoutSyntax (line 44) | #[DataProvider('getBadResourceStrings')]
method getBadResourceStrings (line 54) | public static function getBadResourceStrings()
method testExceptionOnNoObjectReturned (line 66) | public function testExceptionOnNoObjectReturned()
method testExceptionOnBadMethod (line 76) | public function testExceptionOnBadMethod()
method testExceptionOnMethodNotReturningCollection (line 86) | public function testExceptionOnMethodNotReturningCollection()
class TestObjectLoader (line 103) | class TestObjectLoader extends ObjectLoader
method supports (line 107) | public function supports(mixed $resource, ?string $type = null): bool
method getObject (line 112) | protected function getObject(string $id): object
type CustomRouteLoader (line 118) | interface CustomRouteLoader
method loadRoutes (line 120) | public function loadRoutes();
class TestObjectLoaderRouteService (line 123) | class TestObjectLoaderRouteService
method __construct (line 128) | public function __construct($collection, ?string $env = null)
method loadRoutes (line 134) | public function loadRoutes(TestObjectLoader $loader, ?string $env = null)
FILE: Tests/Loader/PhpFileLoaderTest.php
class PhpFileLoaderTest (line 29) | class PhpFileLoaderTest extends TestCase
method testSupports (line 31) | public function testSupports()
method testLoadWithRoute (line 42) | public function testLoadWithRoute()
method testLoadWithImport (line 62) | public function testLoadWithImport()
method testThatDefiningVariableInConfigFileHasNoSideEffects (line 81) | public function testThatDefiningVariableInConfigFileHasNoSideEffects()
method testLoadingRouteWithDefaults (line 96) | public function testLoadingRouteWithDefaults()
method testLoadingRouteWithCollectionDefaults (line 110) | public function testLoadingRouteWithCollectionDefaults()
method testLoadingImportedRoutesWithDefaults (line 135) | public function testLoadingImportedRoutesWithDefaults()
method testLoadingUtf8Route (line 159) | public function testLoadingUtf8Route()
method testLoadingUtf8ImportedRoutes (line 177) | public function testLoadingUtf8ImportedRoutes()
method testRoutingConfigurator (line 197) | public function testRoutingConfigurator()
method testRoutingConfiguratorCanImportGlobPatterns (line 250) | public function testRoutingConfiguratorCanImportGlobPatterns()
method testRoutingI18nConfigurator (line 263) | public function testRoutingI18nConfigurator()
method testImportingRoutesWithHostsInImporter (line 284) | public function testImportingRoutesWithHostsInImporter()
method testImportingRoutesWithLocalesAndHostInImporter (line 294) | public function testImportingRoutesWithLocalesAndHostInImporter()
method testImportingRoutesWithoutHostInImporter (line 304) | public function testImportingRoutesWithoutHostInImporter()
method testImportingRoutesWithSingleHostInImporter (line 314) | public function testImportingRoutesWithSingleHostInImporter()
method testAddingRouteWithHosts (line 324) | public function testAddingRouteWithHosts()
method testImportingAliases (line 334) | public function testImportingAliases()
method testWhenEnv (line 344) | public function testWhenEnv()
method testLoadsArrayRoutes (line 354) | public function testLoadsArrayRoutes()
method testWhenEnvWithArray (line 363) | public function testWhenEnvWithArray()
method testYamlImportsAreResolvedWhenProcessingPhpReturnedArrays (line 372) | public function testYamlImportsAreResolvedWhenProcessingPhpReturnedArr...
method testImportAttributesWithPsr4Prefix (line 387) | #[DataProvider('providePsr4ConfigFiles')]
method providePsr4ConfigFiles (line 407) | public static function providePsr4ConfigFiles(): array
method testImportAttributesFromClass (line 415) | public function testImportAttributesFromClass()
FILE: Tests/Loader/Psr4DirectoryLoaderTest.php
class Psr4DirectoryLoaderTest (line 29) | class Psr4DirectoryLoaderTest extends TestCase
method testTopLevelController (line 31) | public function testTopLevelController()
method testNestedController (line 39) | public function testNestedController()
method testTraitController (line 54) | public function testTraitController()
method testAbstractController (line 62) | public function testAbstractController()
method testExcludeSubNamespace (line 70) | public function testExcludeSubNamespace()
method testExcludeSingleFile (line 87) | public function testExcludeSingleFile()
method testPsr4NamespaceTrim (line 102) | #[DataProvider('provideNamespacesThatNeedTrimming')]
method provideNamespacesThatNeedTrimming (line 116) | public static function provideNamespacesThatNeedTrimming(): array
method testInvalidPsr4Namespace (line 125) | #[DataProvider('provideInvalidPsr4Namespaces')]
method provideInvalidPsr4Namespaces (line 137) | public static function provideInvalidPsr4Namespaces(): array
method loadPsr4Controllers (line 151) | private function loadPsr4Controllers(): RouteCollection
method getLoader (line 159) | private function getLoader(): DelegatingLoader
FILE: Tests/Loader/YamlFileLoaderTest.php
class YamlFileLoaderTest (line 27) | class YamlFileLoaderTest extends TestCase
method testSupports (line 29) | public function testSupports()
method testLoadDoesNothingIfEmpty (line 42) | public function testLoadDoesNothingIfEmpty()
method testLoadThrowsExceptionWithInvalidFile (line 51) | #[DataProvider('getPathsToInvalidFiles')]
method getPathsToInvalidFiles (line 61) | public static function getPathsToInvalidFiles()
method testLoadSpecialRouteName (line 77) | public function testLoadSpecialRouteName()
method testLoadWithRoute (line 87) | public function testLoadWithRoute()
method testLoadWithResource (line 105) | public function testLoadWithResource()
method testLoadRouteWithControllerAttribute (line 124) | public function testLoadRouteWithControllerAttribute()
method testLoadRouteWithoutControllerAttribute (line 134) | public function testLoadRouteWithoutControllerAttribute()
method testLoadRouteWithControllerSetInDefaults (line 144) | public function testLoadRouteWithControllerSetInDefaults()
method testOverrideControllerInDefaults (line 154) | public function testOverrideControllerInDefaults()
method testImportRouteWithController (line 164) | #[DataProvider('provideFilesImportingRoutesWithControllers')]
method provideFilesImportingRoutesWithControllers (line 180) | public static function provideFilesImportingRoutesWithControllers()
method testImportWithOverriddenController (line 186) | public function testImportWithOverriddenController()
method testImportRouteWithGlobMatchingSingleFile (line 196) | public function testImportRouteWithGlobMatchingSingleFile()
method testImportRouteWithGlobMatchingMultipleFiles (line 205) | public function testImportRouteWithGlobMatchingMultipleFiles()
method testImportRouteWithNamePrefix (line 217) | public function testImportRouteWithNamePrefix()
method testRemoteSourcesAreNotAccepted (line 228) | public function testRemoteSourcesAreNotAccepted()
method testLoadingRouteWithDefaults (line 235) | public function testLoadingRouteWithDefaults()
method testLoadingImportedRoutesWithDefaults (line 250) | public function testLoadingImportedRoutesWithDefaults()
method testLoadingUtf8Route (line 274) | public function testLoadingUtf8Route()
method testLoadingUtf8ImportedRoutes (line 292) | public function testLoadingUtf8ImportedRoutes()
method testLoadingLocalizedRoute (line 312) | public function testLoadingLocalizedRoute()
method testImportingRoutesFromDefinition (line 320) | public function testImportingRoutesFromDefinition()
method testImportingRoutesWithLocales (line 331) | public function testImportingRoutesWithLocales()
method testImportingNonLocalizedRoutesWithLocales (line 344) | public function testImportingNonLocalizedRoutesWithLocales()
method testImportingRoutesWithOfficialLocales (line 357) | public function testImportingRoutesWithOfficialLocales()
method testImportingRoutesFromDefinitionMissingLocalePrefix (line 368) | public function testImportingRoutesFromDefinitionMissingLocalePrefix()
method testImportingRouteWithoutPathOrLocales (line 375) | public function testImportingRouteWithoutPathOrLocales()
method testImportingWithControllerDefault (line 382) | public function testImportingWithControllerDefault()
method testImportRouteWithNoTrailingSlash (line 392) | public function testImportRouteWithNoTrailingSlash()
method testRequirementsWithoutPlaceholderName (line 401) | public function testRequirementsWithoutPlaceholderName()
method testImportingRoutesWithHostsInImporter (line 411) | public function testImportingRoutesWithHostsInImporter()
method testImportingRoutesWithLocalesAndHostInImporter (line 421) | public function testImportingRoutesWithLocalesAndHostInImporter()
method testImportingRoutesWithoutHostInImporter (line 431) | public function testImportingRoutesWithoutHostInImporter()
method testImportingRoutesWithSingleHostInImporter (line 441) | public function testImportingRoutesWithSingleHostInImporter()
method testAddingRouteWithHosts (line 451) | public function testAddingRouteWithHosts()
method testWhenEnv (line 461) | public function testWhenEnv()
method testImportingAliases (line 471) | public function testImportingAliases()
method testPriorityWithPrefix (line 481) | public function testPriorityWithPrefix()
method testPriorityWithHost (line 500) | public function testPriorityWithHost()
method testImportAttributesWithPsr4Prefix (line 523) | #[DataProvider('providePsr4ConfigFiles')]
method providePsr4ConfigFiles (line 543) | public static function providePsr4ConfigFiles(): array
method testImportAttributesFromClass (line 551) | public function testImportAttributesFromClass()
FILE: Tests/Matcher/CompiledRedirectableUrlMatcherTest.php
class CompiledRedirectableUrlMatcherTest (line 20) | class CompiledRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
method getUrlMatcher (line 22) | protected function getUrlMatcher(RouteCollection $routes, ?RequestCont...
class TestCompiledRedirectableUrlMatcher (line 38) | class TestCompiledRedirectableUrlMatcher extends CompiledUrlMatcher impl...
method redirect (line 40) | public function redirect(string $path, string $route, ?string $scheme ...
FILE: Tests/Matcher/CompiledUrlMatcherTest.php
class CompiledUrlMatcherTest (line 21) | class CompiledUrlMatcherTest extends UrlMatcherTest
method testStaticHostIsCaseInsensitive (line 23) | public function testStaticHostIsCaseInsensitive()
method getUrlMatcher (line 43) | protected function getUrlMatcher(RouteCollection $routes, ?RequestCont...
FILE: Tests/Matcher/Dumper/CompiledUrlMatcherDumperTest.php
class CompiledUrlMatcherDumperTest (line 26) | class CompiledUrlMatcherDumperTest extends TestCase
method setUp (line 30) | protected function setUp(): void
method tearDown (line 35) | protected function tearDown(): void
method testRedirectPreservesUrlEncoding (line 40) | public function testRedirectPreservesUrlEncoding()
method testDump (line 51) | #[DataProvider('getRouteCollections')]
method getRouteCollections (line 60) | public static function getRouteCollections()
method generateDumpedMatcher (line 475) | private function generateDumpedMatcher(RouteCollection $collection)
method testGenerateDumperMatcherWithObject (line 489) | public function testGenerateDumperMatcherWithObject()
class TestCompiledUrlMatcher (line 502) | class TestCompiledUrlMatcher extends CompiledUrlMatcher implements Redir...
method redirect (line 504) | public function redirect(string $path, string $route, ?string $scheme ...
FILE: Tests/Matcher/Dumper/StaticPrefixCollectionTest.php
class StaticPrefixCollectionTest (line 19) | class StaticPrefixCollectionTest extends TestCase
method testGrouping (line 21) | #[DataProvider('routeProvider')]
method routeProvider (line 36) | public static function routeProvider()
method dumpCollection (line 170) | private function dumpCollection(StaticPrefixCollection $collection, $p...
FILE: Tests/Matcher/ExpressionLanguageProviderTest.php
class ExpressionLanguageProviderTest (line 21) | class ExpressionLanguageProviderTest extends TestCase
method setUp (line 26) | protected function setUp(): void
method testCompile (line 44) | #[DataProvider('compileProvider')]
method compileProvider (line 50) | public static function compileProvider(): iterable
method testEvaluate (line 59) | #[DataProvider('evaluateProvider')]
method evaluateProvider (line 65) | public static function evaluateProvider(): iterable
FILE: Tests/Matcher/RedirectableUrlMatcherTest.php
class RedirectableUrlMatcherTest (line 20) | class RedirectableUrlMatcherTest extends UrlMatcherTest
method testMissingTrailingSlash (line 22) | public function testMissingTrailingSlash()
method testExtraTrailingSlash (line 32) | public function testExtraTrailingSlash()
method testRedirectWhenNoSlashForNonSafeMethod (line 42) | public function testRedirectWhenNoSlashForNonSafeMethod()
method testSchemeRedirectRedirectsToFirstScheme (line 56) | public function testSchemeRedirectRedirectsToFirstScheme()
method testNoSchemaRedirectIfOneOfMultipleSchemesMatches (line 71) | public function testNoSchemaRedirectIfOneOfMultipleSchemesMatches()
method testSchemeRedirectWithParams (line 83) | public function testSchemeRedirectWithParams()
method testSchemeRedirectForRoot (line 98) | public function testSchemeRedirectForRoot()
method testSlashRedirectWithParams (line 112) | public function testSlashRedirectWithParams()
method testRedirectPreservesUrlEncoding (line 127) | public function testRedirectPreservesUrlEncoding()
method testSchemeRequirement (line 137) | public function testSchemeRequirement()
method testFallbackPage (line 146) | public function testFallbackPage()
method testMissingTrailingSlashAndScheme (line 165) | public function testMissingTrailingSlashAndScheme()
method testSlashAndVerbPrecedenceWithRedirection (line 175) | public function testSlashAndVerbPrecedenceWithRedirection()
method testNonGreedyTrailingRequirement (line 192) | public function testNonGreedyTrailingRequirement()
method testTrailingRequirementWithDefaultA (line 203) | public function testTrailingRequirementWithDefaultA()
method getUrlMatcher (line 214) | protected function getUrlMatcher(RouteCollection $routes, ?RequestCont...
FILE: Tests/Matcher/TraceableUrlMatcherTest.php
class TraceableUrlMatcherTest (line 20) | class TraceableUrlMatcherTest extends UrlMatcherTest
method test (line 22) | public function test()
method testMatchRouteOnMultipleHosts (line 62) | public function testMatchRouteOnMultipleHosts()
method getLevels (line 93) | public function getLevels($traces)
method testRoutesWithConditions (line 103) | public function testRoutesWithConditions()
method getUrlMatcher (line 131) | protected function getUrlMatcher(RouteCollection $routes, ?RequestCont...
FILE: Tests/Matcher/UrlMatcherTest.php
class UrlMatcherTest (line 23) | class UrlMatcherTest extends TestCase
method testZero (line 25) | public function testZero()
method testNoMethodSoAllowed (line 36) | public function testNoMethodSoAllowed()
method testMethodNotAllowed (line 45) | public function testMethodNotAllowed()
method testMethodNotAllowedOnRoot (line 60) | public function testMethodNotAllowedOnRoot()
method testHeadAllowedWhenRequirementContainsGet (line 75) | public function testHeadAllowedWhenRequirementContainsGet()
method testMethodNotAllowedAggregatesAllowedMethods (line 84) | public function testMethodNotAllowedAggregatesAllowedMethods()
method testPatternMatchAndParameterReturn (line 100) | public function testPatternMatchAndParameterReturn()
method testDefaultsAreMerged (line 114) | public function testDefaultsAreMerged()
method testMethodIsIgnoredIfNoMethodGiven (line 123) | public function testMethodIsIgnoredIfNoMethodGiven()
method testRouteWithOptionalVariableAsFirstSegment (line 146) | public function testRouteWithOptionalVariableAsFirstSegment()
method testRouteWithOnlyOptionalVariables (line 161) | public function testRouteWithOnlyOptionalVariables()
method testMatchWithPrefixes (line 171) | public function testMatchWithPrefixes()
method testMatchWithDynamicPrefix (line 182) | public function testMatchWithDynamicPrefix()
method testMatchSpecialRouteName (line 193) | public function testMatchSpecialRouteName()
method testMatchImportantVariable (line 202) | public function testMatchImportantVariable()
method testShortPathDoesNotMatchImportantVariable (line 211) | public function testShortPathDoesNotMatchImportantVariable()
method testTrailingEncodedNewlineIsNotOverlooked (line 223) | public function testTrailingEncodedNewlineIsNotOverlooked()
method testMatchNonAlpha (line 235) | public function testMatchNonAlpha()
method testMatchWithDotMetacharacterInRequirements (line 246) | public function testMatchWithDotMetacharacterInRequirements()
method testMatchOverriddenRoute (line 255) | public function testMatchOverriddenRoute()
method testMatchRegression (line 272) | public function testMatchRegression()
method testMultipleParams (line 291) | public function testMultipleParams()
method testDefaultRequirementForOptionalVariables (line 303) | public function testDefaultRequirementForOptionalVariables()
method testMatchingIsEager (line 312) | public function testMatchingIsEager()
method testAdjacentVariables (line 321) | public function testAdjacentVariables()
method testOptionalVariableWithNoRealSeparator (line 341) | public function testOptionalVariableWithNoRealSeparator()
method testRequiredVariableWithNoRealSeparator (line 356) | public function testRequiredVariableWithNoRealSeparator()
method testDefaultRequirementOfVariable (line 365) | public function testDefaultRequirementOfVariable()
method testDefaultRequirementOfVariableDisallowsSlash (line 374) | public function testDefaultRequirementOfVariableDisallowsSlash()
method testDefaultRequirementOfVariableDisallowsNextSeparator (line 385) | public function testDefaultRequirementOfVariableDisallowsNextSeparator()
method testMissingTrailingSlash (line 396) | public function testMissingTrailingSlash()
method testExtraTrailingSlash (line 408) | public function testExtraTrailingSlash()
method testMissingTrailingSlashForNonSafeMethod (line 418) | public function testMissingTrailingSlashForNonSafeMethod()
method testExtraTrailingSlashForNonSafeMethod (line 430) | public function testExtraTrailingSlashForNonSafeMethod()
method testSchemeRequirement (line 442) | public function testSchemeRequirement()
method testSchemeRequirementForNonSafeMethod (line 451) | public function testSchemeRequirementForNonSafeMethod()
method testSamePathWithDifferentScheme (line 463) | public function testSamePathWithDifferentScheme()
method testCondition (line 472) | public function testCondition()
method testRequestCondition (line 485) | public function testRequestCondition()
method testRouteParametersCondition (line 498) | public function testRouteParametersCondition()
method testDecodeOnce (line 529) | public function testDecodeOnce()
method testCannotRelyOnPrefix (line 538) | public function testCannotRelyOnPrefix()
method testWithHost (line 554) | public function testWithHost()
method testWithHostOnRouteCollection (line 563) | public function testWithHostOnRouteCollection()
method testVariationInTrailingSlashWithHosts (line 577) | public function testVariationInTrailingSlashWithHosts()
method testVariationInTrailingSlashWithHostsInReverse (line 590) | public function testVariationInTrailingSlashWithHostsInReverse()
method testVariationInTrailingSlashWithHostsAndVariable (line 604) | public function testVariationInTrailingSlashWithHostsAndVariable()
method testVariationInTrailingSlashWithHostsAndVariableInReverse (line 617) | public function testVariationInTrailingSlashWithHostsAndVariableInReve...
method testVariationInTrailingSlashWithMethods (line 631) | public function testVariationInTrailingSlashWithMethods()
method testVariationInTrailingSlashWithMethodsInReverse (line 644) | public function testVariationInTrailingSlashWithMethodsInReverse()
method testVariableVariationInTrailingSlashWithMethods (line 658) | public function testVariableVariationInTrailingSlashWithMethods()
method testVariableVariationInTrailingSlashWithMethodsInReverse (line 671) | public function testVariableVariationInTrailingSlashWithMethodsInRever...
method testMixOfStaticAndVariableVariationInTrailingSlashWithHosts (line 685) | public function testMixOfStaticAndVariableVariationInTrailingSlashWith...
method testMixOfStaticAndVariableVariationInTrailingSlashWithMethods (line 698) | public function testMixOfStaticAndVariableVariationInTrailingSlashWith...
method testWithOutHostHostDoesNotMatch (line 712) | public function testWithOutHostHostDoesNotMatch()
method testPathIsCaseSensitive (line 724) | public function testPathIsCaseSensitive()
method testHostIsCaseInsensitive (line 736) | public function testHostIsCaseInsensitive()
method testNoConfiguration (line 745) | public function testNoConfiguration()
method testNestedCollections (line 756) | public function testNestedCollections()
method testSchemeAndMethodMismatch (line 780) | public function testSchemeAndMethodMismatch()
method testSiblingRoutes (line 793) | public function testSiblingRoutes()
method testUnicodeRoute (line 808) | public function testUnicodeRoute()
method testRequirementWithCapturingGroup (line 818) | public function testRequirementWithCapturingGroup()
method testDotAllWithCatchAll (line 827) | public function testDotAllWithCatchAll()
method testHostPattern (line 837) | public function testHostPattern()
method testUtf8Prefix (line 853) | public function testUtf8Prefix()
method testUtf8AndMethodMatching (line 863) | public function testUtf8AndMethodMatching()
method testHostWithDot (line 874) | public function testHostWithDot()
method testSlashVariant (line 884) | public function testSlashVariant()
method testSlashVariant2 (line 893) | public function testSlashVariant2()
method testSlashWithVerb (line 902) | public function testSlashWithVerb()
method testSlashAndVerbPrecedence (line 922) | public function testSlashAndVerbPrecedence()
method testGreedyTrailingRequirement (line 947) | public function testGreedyTrailingRequirement()
method testTrailingRequirementWithDefault (line 958) | public function testTrailingRequirementWithDefault()
method testTrailingRequirementWithDefaultA (line 972) | public function testTrailingRequirementWithDefaultA()
method testTrailingRequirementWithDefaultB (line 983) | public function testTrailingRequirementWithDefaultB()
method testRestrictiveTrailingRequirementWithStaticRouteAfter (line 993) | public function testRestrictiveTrailingRequirementWithStaticRouteAfter()
method testUtf8VarName (line 1004) | public function testUtf8VarName()
method testParameterWithRequirementWithDefault (line 1014) | public function testParameterWithRequirementWithDefault()
method testMapping (line 1038) | public function testMapping()
method testMappingwithAlias (line 1055) | public function testMappingwithAlias()
method getUrlMatcher (line 1075) | protected function getUrlMatcher(RouteCollection $routes, ?RequestCont...
FILE: Tests/RequestContextTest.php
class RequestContextTest (line 19) | class RequestContextTest extends TestCase
method testConstruct (line 21) | public function testConstruct()
method testConstructParametersBcLayer (line 48) | public function testConstructParametersBcLayer()
method testFromUriWithBaseUrl (line 61) | public function testFromUriWithBaseUrl()
method testFromUriWithTrailingSlash (line 74) | public function testFromUriWithTrailingSlash()
method testFromUriWithoutTrailingSlash (line 86) | public function testFromUriWithoutTrailingSlash()
method testFromUriBeingEmpty (line 96) | public function testFromUriBeingEmpty()
method testFromBadUri (line 106) | #[TestWith(['http://foo.com\\bar'])]
method testFromRequest (line 126) | public function testFromRequest()
method testGetParameters (line 151) | public function testGetParameters()
method testHasParameter (line 160) | public function testHasParameter()
method testGetParameter (line 169) | public function testGetParameter()
method testSetParameter (line 178) | public function testSetParameter()
method testMethod (line 186) | public function testMethod()
method testScheme (line 194) | public function testScheme()
method testHost (line 202) | public function testHost()
method testQueryString (line 210) | public function testQueryString()
method testPort (line 218) | public function testPort()
method testFluentInterface (line 228) | public function testFluentInterface()
FILE: Tests/Requirement/EnumRequirementTest.php
class EnumRequirementTest (line 24) | class EnumRequirementTest extends TestCase
method testNotABackedEnum (line 26) | public function testNotABackedEnum()
method testCaseNotABackedEnum (line 34) | public function testCaseNotABackedEnum()
method testCaseFromAnotherEnum (line 42) | public function testCaseFromAnotherEnum()
method testToString (line 50) | #[DataProvider('provideToString')]
method provideToString (line 56) | public static function provideToString()
method testInRoute (line 67) | public function testInRoute()
FILE: Tests/Requirement/RequirementTest.php
class RequirementTest (line 20) | class RequirementTest extends TestCase
method testAsciiSlugOK (line 22) | #[TestWith(['FOO'])]
method testAsciiSlugKO (line 37) | #[TestWith([''])]
method testCatchAllOK (line 53) | #[TestWith(['foo'])]
method testCatchAllKO (line 64) | #[TestWith([''])]
method testDateYmdOK (line 73) | #[TestWith(['0000-01-01'])]
method testDateYmdKO (line 86) | #[TestWith([''])]
method testDigitsOK (line 100) | #[TestWith(['0'])]
method testDigitsKO (line 114) | #[TestWith([''])]
method testMongoDbIdOK (line 126) | #[TestWith(['67c8b7d295c70befc3070bf2'])]
method testMongoDbIdKO (line 136) | #[TestWith(['67C8b7D295C70BEFC3070BF2'])]
method testPositiveIntOK (line 148) | #[TestWith(['1'])]
method testPositiveIntKO (line 160) | #[TestWith([''])]
method testUidBase32OK (line 174) | #[TestWith(['00000000000000000000000000'])]
method testUidBase32KO (line 186) | #[TestWith([''])]
method testUidBase58OK (line 198) | #[TestWith(['1111111111111111111111'])]
method testUidBase58KO (line 210) | #[TestWith([''])]
method testUidRfc4122OK (line 222) | #[DataProvider('provideUidRfc4122')]
method testUidRfc4122KO (line 231) | #[DataProvider('provideUidRfc4122KO')]
method testUidRfc9562OK (line 240) | #[DataProvider('provideUidRfc4122')]
method testUidRfc9562KO (line 249) | #[DataProvider('provideUidRfc4122KO')]
method provideUidRfc4122 (line 258) | public static function provideUidRfc4122(): iterable
method provideUidRfc4122KO (line 266) | public static function provideUidRfc4122KO(): iterable
method testUlidOK (line 275) | #[TestWith(['00000000000000000000000000'])]
method testUlidKO (line 286) | #[TestWith([''])]
method testUuidOK (line 298) | #[TestWith(['00000000-0000-1000-8000-000000000000'])]
method testUuidKO (line 313) | #[TestWith([''])]
method testUuidV1OK (line 328) | #[TestWith(['00000000-0000-1000-8000-000000000000'])]
method testUuidV1KO (line 341) | #[TestWith([''])]
method testUuidV3OK (line 355) | #[TestWith(['00000000-0000-3000-8000-000000000000'])]
method testUuidV3KO (line 367) | #[TestWith([''])]
method testUuidV4OK (line 381) | #[TestWith(['00000000-0000-4000-8000-000000000000'])]
method testUuidV4KO (line 393) | #[TestWith([''])]
method testUuidV5OK (line 407) | #[TestWith(['00000000-0000-5000-8000-000000000000'])]
method testUuidV5KO (line 419) | #[TestWith([''])]
method testUuidV6OK (line 433) | #[TestWith(['00000000-0000-6000-8000-000000000000'])]
method testUuidV6KO (line 446) | #[TestWith([''])]
method testUuidV7OK (line 460) | #[TestWith(['00000000-0000-7000-8000-000000000000'])]
method testUuidV7KO (line 471) | #[TestWith([''])]
method testUuidV8OK (line 485) | #[TestWith(['00000000-0000-8000-8000-000000000000'])]
method testUuidV8KO (line 496) | #[TestWith([''])]
FILE: Tests/RouteCollectionTest.php
class RouteCollectionTest (line 19) | class RouteCollectionTest extends TestCase
method testRoute (line 21) | public function testRoute()
method testOverriddenRoute (line 31) | public function testOverriddenRoute()
method testDeepOverriddenRoute (line 40) | public function testDeepOverriddenRoute()
method testIterator (line 58) | public function testIterator()
method testCount (line 73) | public function testCount()
method testAddCollection (line 85) | public function testAddCollection()
method testAddCollectionWithResources (line 105) | public function testAddCollectionWithResources()
method testAddDefaultsAndRequirementsAndOptions (line 115) | public function testAddDefaultsAndRequirementsAndOptions()
method testAddPrefix (line 142) | public function testAddPrefix()
method testAddPrefixOverridesDefaultsAndRequirements (line 165) | public function testAddPrefixOverridesDefaultsAndRequirements()
method testResource (line 176) | public function testResource()
method testUniqueRouteWithGivenName (line 187) | public function testUniqueRouteWithGivenName()
method testGet (line 203) | public function testGet()
method testRemove (line 219) | public function testRemove()
method testSetHost (line 240) | public function testSetHost()
method testSetCondition (line 254) | public function testSetCondition()
method testClone (line 268) | public function testClone()
method testSetSchemes (line 283) | public function testSetSchemes()
method testSetMethods (line 297) | public function testSetMethods()
method testAddNamePrefix (line 311) | public function testAddNamePrefix()
method testAddNamePrefixCanonicalRouteName (line 326) | public function testAddNamePrefixCanonicalRouteName()
method testAddWithPriority (line 339) | public function testAddWithPriority()
method testAddWithPriorityAndPrefix (line 372) | public function testAddWithPriorityAndPrefix()
method testAddNamePrefixDoesNotBreakExternalAliases (line 389) | public function testAddNamePrefixDoesNotBreakExternalAliases()
FILE: Tests/RouteCompilerTest.php
class RouteCompilerTest (line 19) | class RouteCompilerTest extends TestCase
method testCompile (line 21) | #[DataProvider('provideCompileData')]
method provideCompileData (line 34) | public static function provideCompileData()
method testCompileImplicitUtf8Data (line 185) | #[DataProvider('provideCompileImplicitUtf8Data')]
method provideCompileImplicitUtf8Data (line 199) | public static function provideCompileImplicitUtf8Data()
method testRouteWithSameVariableTwice (line 250) | public function testRouteWithSameVariableTwice()
method testRouteCharsetMismatch (line 258) | public function testRouteCharsetMismatch()
method testRequirementCharsetMismatch (line 267) | public function testRequirementCharsetMismatch()
method testRouteWithFragmentAsPathParameter (line 276) | public function testRouteWithFragmentAsPathParameter()
method testRouteWithVariableNameStartingWithADigit (line 285) | #[DataProvider('getVariableNamesStartingWithADigit')]
method getVariableNamesStartingWithADigit (line 293) | public static function getVariableNamesStartingWithADigit()
method testCompileWithHost (line 302) | #[DataProvider('provideCompileWithHostData')]
method provideCompileWithHostData (line 319) | public static function provideCompileWithHostData()
method testRouteWithTooLongVariableName (line 371) | public function testRouteWithTooLongVariableName()
method testRemoveCapturingGroup (line 380) | #[DataProvider('provideRemoveCapturingGroup')]
method provideRemoveCapturingGroup (line 388) | public static function provideRemoveCapturingGroup()
class Utf8RouteCompiler (line 399) | class Utf8RouteCompiler extends RouteCompiler
FILE: Tests/RouteTest.php
class RouteTest (line 21) | class RouteTest extends TestCase
method testConstructor (line 23) | public function testConstructor()
method testPath (line 42) | public function testPath()
method testOptions (line 64) | public function testOptions()
method testOption (line 79) | public function testOption()
method testDefaults (line 88) | public function testDefaults()
method testRequirements (line 111) | public function testRequirements()
method testRequirement (line 128) | public function testRequirement()
method testRequirementAlternativeStartAndEndRegexSyntax (line 137) | public function testRequirementAlternativeStartAndEndRegexSyntax()
method testSetInvalidRequirement (line 145) | #[DataProvider('getInvalidRequirements')]
method getInvalidRequirements (line 155) | public static function getInvalidRequirements()
method testHost (line 168) | public function testHost()
method testScheme (line 175) | public function testScheme()
method testMethod (line 190) | public function testMethod()
method testCondition (line 200) | public function testCondition()
method testCompile (line 208) | public function testCompile()
method testSerialize (line 217) | public function testSerialize()
method testInlineDefaultAndRequirement (line 228) | #[DataProvider('provideInlineDefaultAndRequirementCases')]
method provideInlineDefaultAndRequirementCases (line 237) | public static function provideInlineDefaultAndRequirementCases(): iter...
method testSerializeWhenCompiled (line 274) | public function testSerializeWhenCompiled()
method testSerializeWhenCompiledWithClass (line 291) | public function testSerializeWhenCompiledWithClass()
method testSerializedRepresentationKeepsWorking (line 310) | public function testSerializedRepresentationKeepsWorking()
method testLocaleDefaultWithNonLocalizedRoutes (line 323) | #[DataProvider('provideNonLocalizedRoutes')]
method testLocaleDefaultWithLocalizedRoutes (line 331) | #[DataProvider('provideLocalizedRoutes')]
method testLocaleRequirementWithNonLocalizedRoutes (line 341) | #[DataProvider('provideNonLocalizedRoutes')]
method testLocaleRequirementWithLocalizedRoutes (line 349) | #[DataProvider('provideLocalizedRoutes')]
method provideNonLocalizedRoutes (line 359) | public static function provideNonLocalizedRoutes()
method provideLocalizedRoutes (line 369) | public static function provideLocalizedRoutes()
FILE: Tests/RouterTest.php
class RouterTest (line 26) | class RouterTest extends TestCase
method setUp (line 30) | protected function setUp(): void
method tearDown (line 37) | protected function tearDown(): void
method testSetOptionsWithSupportedOptions (line 45) | public function testSetOptionsWithSupportedOptions()
method testSetOptionsWithUnsupportedOptions (line 59) | public function testSetOptionsWithUnsupportedOptions()
method testSetOptionWithSupportedOption (line 72) | public function testSetOptionWithSupportedOption()
method testSetOptionWithUnsupportedOption (line 80) | public function testSetOptionWithUnsupportedOption()
method testGetOptionWithUnsupportedOption (line 88) | public function testGetOptionWithUnsupportedOption()
method testThatRouteCollectionIsLoaded (line 96) | public function testThatRouteCollectionIsLoaded()
method testMatcherIsCreatedIfCacheIsNotConfigured (line 111) | public function testMatcherIsCreatedIfCacheIsNotConfigured()
method testGeneratorIsCreatedIfCacheIsNotConfigured (line 124) | public function testGeneratorIsCreatedIfCacheIsNotConfigured()
method testGeneratorIsCreatedIfCacheIsNotConfiguredNotCompiled (line 137) | public function testGeneratorIsCreatedIfCacheIsNotConfiguredNotCompiled()
method testMatchRequestWithUrlMatcherInterface (line 152) | public function testMatchRequestWithUrlMatcherInterface()
method testMatchRequestWithRequestMatcherInterface (line 164) | public function testMatchRequestWithRequestMatcherInterface()
method testDefaultLocaleIsPassedToGeneratorClass (line 176) | public function testDefaultLocaleIsPassedToGeneratorClass()
method testDefaultLocaleIsPassedToCompiledGeneratorCacheClass (line 196) | public function testDefaultLocaleIsPassedToCompiledGeneratorCacheClass()
method getRouter (line 216) | private function getRouter(?LoaderInterface $loader = null): Router
Condensed preview — 315 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (966K chars).
[
{
"path": ".gitattributes",
"chars": 74,
"preview": "/Tests export-ignore\n/phpunit.xml.dist export-ignore\n/.git* export-ignore\n"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 278,
"preview": "Please do not submit any Pull Requests here. They will be closed.\n---\n\nPlease submit your PR here instead:\nhttps://githu"
},
{
"path": ".github/workflows/close-pull-request.yml",
"chars": 544,
"preview": "name: Close Pull Request\n\non:\n pull_request_target:\n types: [opened]\n\njobs:\n run:\n runs-on: ubuntu-latest\n st"
},
{
"path": ".gitignore",
"chars": 34,
"preview": "vendor/\ncomposer.lock\nphpunit.xml\n"
},
{
"path": "Alias.php",
"chars": 2532,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Attribute/DeprecatedAlias.php",
"chars": 620,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Attribute/Route.php",
"chars": 4296,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "CHANGELOG.md",
"chars": 16166,
"preview": "CHANGELOG\n=========\n\n8.0\n---\n\n * Remove support for accessing the internal scope of the loader in PHP config files, use "
},
{
"path": "CompiledRoute.php",
"chars": 3799,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "DependencyInjection/AddExpressionLanguageProvidersPass.php",
"chars": 1120,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "DependencyInjection/RoutingControllerPass.php",
"chars": 1278,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "DependencyInjection/RoutingResolverPass.php",
"chars": 1213,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/ExceptionInterface.php",
"chars": 429,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/InvalidArgumentException.php",
"chars": 385,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/InvalidParameterException.php",
"chars": 505,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/LogicException.php",
"chars": 335,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/MethodNotAllowedException.php",
"chars": 1129,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/MissingMandatoryParametersException.php",
"chars": 1388,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/NoConfigurationException.php",
"chars": 465,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/ResourceNotFoundException.php",
"chars": 548,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/RouteCircularReferenceException.php",
"chars": 559,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/RouteNotFoundException.php",
"chars": 500,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Exception/RuntimeException.php",
"chars": 369,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/CompiledUrlGenerator.php",
"chars": 2508,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/ConfigurableRequirementsInterface.php",
"chars": 2218,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/Dumper/CompiledUrlGeneratorDumper.php",
"chars": 4267,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/Dumper/GeneratorDumper.php",
"chars": 725,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/Dumper/GeneratorDumperInterface.php",
"chars": 844,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/UrlGenerator.php",
"chars": 15413,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Generator/UrlGeneratorInterface.php",
"chars": 3468,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "LICENSE",
"chars": 1068,
"preview": "Copyright (c) 2004-present Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "Loader/AttributeClassLoader.php",
"chars": 14495,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/AttributeDirectoryLoader.php",
"chars": 2630,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/AttributeFileLoader.php",
"chars": 4345,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/AttributeServicesLoader.php",
"chars": 1169,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/ClosureLoader.php",
"chars": 919,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/AliasConfigurator.php",
"chars": 1177,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/CollectionConfigurator.php",
"chars": 3527,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/ImportConfigurator.php",
"chars": 1980,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/RouteConfigurator.php",
"chars": 1486,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/RoutesReference.php",
"chars": 2472,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/RoutingConfigurator.php",
"chars": 2086,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/Traits/AddTrait.php",
"chars": 1797,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/Traits/HostTrait.php",
"chars": 1790,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/Traits/LocalizedRouteTrait.php",
"chars": 2549,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/Traits/PrefixTrait.php",
"chars": 3019,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Configurator/Traits/RouteTrait.php",
"chars": 3580,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/ContainerLoader.php",
"chars": 929,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/ContentLoaderTrait.php",
"chars": 9913,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/DirectoryLoader.php",
"chars": 1466,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/GlobFileLoader.php",
"chars": 1010,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/ObjectLoader.php",
"chars": 2663,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/PhpFileLoader.php",
"chars": 2914,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/Psr4DirectoryLoader.php",
"chars": 3876,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/YamlFileLoader.php",
"chars": 3526,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Loader/schema/routing/routing-1.0.xsd",
"chars": 7993,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<xsd:schema xmlns=\"http://symfony.com/schema/routing\"\n xmlns:xsd=\"http://www"
},
{
"path": "Loader/schema/routing.schema.json",
"chars": 5884,
"preview": "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"Symfony Routing Configuration\",\n \"description\": \""
},
{
"path": "Matcher/CompiledUrlMatcher.php",
"chars": 861,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/Dumper/CompiledUrlMatcherDumper.php",
"chars": 19503,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/Dumper/CompiledUrlMatcherTrait.php",
"chars": 7590,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/Dumper/MatcherDumper.php",
"chars": 719,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/Dumper/MatcherDumperInterface.php",
"chars": 842,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/Dumper/StaticPrefixCollection.php",
"chars": 7092,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/ExpressionLanguageProvider.php",
"chars": 1495,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/RedirectableUrlMatcher.php",
"chars": 2052,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/RedirectableUrlMatcherInterface.php",
"chars": 864,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/RequestMatcherInterface.php",
"chars": 1249,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/TraceableUrlMatcher.php",
"chars": 6979,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/UrlMatcher.php",
"chars": 9483,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Matcher/UrlMatcherInterface.php",
"chars": 1370,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "README.md",
"chars": 1630,
"preview": "Routing Component\n=================\n\nThe Routing component maps an HTTP request to a set of configuration variables.\n\nGe"
},
{
"path": "RequestContext.php",
"chars": 7089,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "RequestContextAwareInterface.php",
"chars": 531,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Requirement/EnumRequirement.php",
"chars": 1648,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Requirement/Requirement.php",
"chars": 1886,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Route.php",
"chars": 12662,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "RouteCollection.php",
"chars": 10940,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "RouteCompiler.php",
"chars": 14596,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "RouteCompilerInterface.php",
"chars": 733,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Router.php",
"chars": 11487,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "RouterInterface.php",
"chars": 994,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Attribute/RouteTest.php",
"chars": 1667,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/CompiledRouteTest.php",
"chars": 1070,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php",
"chars": 2349,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/DependencyInjection/RoutingControllerPassTest.php",
"chars": 1968,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/DependencyInjection/RoutingResolverPassTest.php",
"chars": 1196,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/AbstractClassController.php",
"chars": 121,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nabstract class AbstractClassController\n{\n}"
},
{
"path": "Tests/Fixtures/AttributeFixtures/ActionPathController.php",
"chars": 236,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/AliasClassController.php",
"chars": 663,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/AliasInvokableController.php",
"chars": 589,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/AliasLocalizedRouteController.php",
"chars": 565,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/AliasRouteController.php",
"chars": 525,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/BazClass.php",
"chars": 578,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/DefaultValueController.php",
"chars": 1436,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/DeprecatedAliasCustomMessageRouteController.php",
"chars": 697,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/DeprecatedAliasRouteController.php",
"chars": 639,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/EncodingClass.php",
"chars": 209,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/ExplicitLocalizedActionPathController.php",
"chars": 285,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/ExtendedRoute.php",
"chars": 507,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/ExtendedRouteOnClassController.php",
"chars": 293,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/ExtendedRouteOnMethodController.php",
"chars": 221,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nclass ExtendedRouteOnMethodController\n{\n "
},
{
"path": "Tests/Fixtures/AttributeFixtures/FooController.php",
"chars": 1141,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/GlobalDefaultsClass.php",
"chars": 1017,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/InvokableController.php",
"chars": 282,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/InvokableFQCNAliasConflictController.php",
"chars": 264,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/InvokableLocalizedController.php",
"chars": 275,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/InvokableMethodController.php",
"chars": 292,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/LocalizedActionPathController.php",
"chars": 277,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/LocalizedMethodActionControllers.php",
"chars": 395,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixLocalizedActionController.php",
"chars": 339,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixMissingLocaleActionController.php",
"chars": 328,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixMissingRouteLocaleActionController.php",
"chars": 329,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixWithRouteWithoutLocale.php",
"chars": 308,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/MethodActionControllers.php",
"chars": 364,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/MethodsAndSchemes.php",
"chars": 586,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/MissingRouteNameController.php",
"chars": 226,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/MultipleDeprecatedAliasRouteController.php",
"chars": 865,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/NothingButNameController.php",
"chars": 231,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/PrefixedActionLocalizedRouteController.php",
"chars": 306,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/PrefixedActionPathController.php",
"chars": 323,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/RequirementsWithoutPlaceholderNameController.php",
"chars": 572,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributeFixtures/RouteWithEnv.php",
"chars": 734,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/RouteWithPrefixController.php",
"chars": 267,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/RouteWithPriorityController.php",
"chars": 416,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributeFixtures/Utf8ActionControllers.php",
"chars": 330,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Ro"
},
{
"path": "Tests/Fixtures/AttributedClasses/AbstractClass.php",
"chars": 582,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributedClasses/BarClass.php",
"chars": 429,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributedClasses/BazClass.php",
"chars": 371,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributedClasses/EncodingClass.php",
"chars": 148,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\nclass EncodingClass\n{\n public function "
},
{
"path": "Tests/Fixtures/AttributedClasses/FooClass.php",
"chars": 328,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/AttributedClasses/FooTrait.php",
"chars": 188,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\ntrait FooTrait\n{\n public function doBar"
},
{
"path": "Tests/Fixtures/Attributes/FooAttributes.php",
"chars": 319,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes;\n\n#[\\Attribute(\\Attribute::TARGET_CLASS)]\nclass Foo"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php",
"chars": 316,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php",
"chars": 322,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php",
"chars": 287,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php",
"chars": 293,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php",
"chars": 320,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php",
"chars": 299,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php",
"chars": 349,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php",
"chars": 355,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtu"
},
{
"path": "Tests/Fixtures/CustomCompiledRoute.php",
"chars": 389,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/CustomRouteCompiler.php",
"chars": 603,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Enum/TestIntBackedEnum.php",
"chars": 417,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Enum/TestStringBackedEnum.php",
"chars": 448,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Enum/TestStringBackedEnum2.php",
"chars": 450,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Enum/TestUnitEnum.php",
"chars": 387,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php",
"chars": 26,
"preview": "class NoStartTagClass\n{\n}\n"
},
{
"path": "Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php",
"chars": 471,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/MyController.php",
"chars": 588,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/MyUnannotatedController.php",
"chars": 512,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/EvenDeeperNamespace/MyOtherController.php",
"chars": 860,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantClass.php",
"chars": 718,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantEnum.php",
"chars": 543,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantInterface.php",
"chars": 354,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/MyAbstractController.php",
"chars": 650,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/MyChildController.php",
"chars": 494,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/MyControllerWithATrait.php",
"chars": 536,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/Psr4Controllers/SubNamespace/SomeSharedImplementation.php",
"chars": 629,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/RedirectableUrlMatcher.php",
"chars": 817,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/TraceableAttributeClassLoader.php",
"chars": 1045,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "Tests/Fixtures/alias/alias.php",
"chars": 542,
"preview": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RoutingConfigurator;\n\nreturn static function (RoutingConfigurat"
},
{
"path": "Tests/Fixtures/alias/alias.yaml",
"chars": 342,
"preview": "route:\n path: /hello\noverrided:\n path: /\nalias:\n alias: route\ndeprecated:\n alias: route\n deprecated:\n package: \""
},
{
"path": "Tests/Fixtures/alias/expected.php",
"chars": 909,
"preview": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Ro"
},
{
"path": "Tests/Fixtures/alias/invalid-alias.yaml",
"chars": 36,
"preview": "invalid:\n alias: route\n path: \"/\"\n"
},
{
"path": "Tests/Fixtures/alias/invalid-deprecated-no-package.yaml",
"chars": 59,
"preview": "invalid:\n alias: route\n deprecated:\n version: \"1.0.0\"\n"
},
{
"path": "Tests/Fixtures/alias/invalid-deprecated-no-version.yaml",
"chars": 61,
"preview": "invalid:\n alias: route\n deprecated:\n package: \"foo/bar\"\n"
},
{
"path": "Tests/Fixtures/alias/override.yaml",
"chars": 26,
"preview": "overrided:\n alias: route\n"
},
{
"path": "Tests/Fixtures/annotated.php",
"chars": 0,
"preview": ""
},
{
"path": "Tests/Fixtures/array_routes.php",
"chars": 174,
"preview": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Routes;\n\nreturn Routes::config([\n 'a' => ['path' => '/a'],\n "
},
{
"path": "Tests/Fixtures/array_when_env.php",
"chars": 188,
"preview": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Routes;\n\nreturn Routes::config([\n 'when@some-env' => [\n "
},
{
"path": "Tests/Fixtures/bad_format.yml",
"chars": 84,
"preview": "blog_show:\n\tpath: /blog/{slug}\n\tdefaults: { _controller: \"MyBundle:Blog:show\" }\n"
},
{
"path": "Tests/Fixtures/class-attributes.php",
"chars": 344,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Contro"
},
{
"path": "Tests/Fixtures/class-attributes.yaml",
"chars": 143,
"preview": "my_controllers:\n resource: Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\MyController\n type: attribute\n"
},
{
"path": "Tests/Fixtures/collection-defaults.php",
"chars": 516,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n $co"
},
{
"path": "Tests/Fixtures/controller/empty_wildcard/.gitignore",
"chars": 0,
"preview": ""
},
{
"path": "Tests/Fixtures/controller/import__controller.yml",
"chars": 104,
"preview": "_static:\n resource: routing.yml\n defaults:\n _controller: FrameworkBundle:Template:template\n"
},
{
"path": "Tests/Fixtures/controller/import_controller.yml",
"chars": 85,
"preview": "_static:\n resource: routing.yml\n controller: FrameworkBundle:Template:template\n"
},
{
"path": "Tests/Fixtures/controller/import_override_defaults.yml",
"chars": 144,
"preview": "_static:\n resource: routing.yml\n controller: FrameworkBundle:Template:template\n defaults:\n _controller: "
},
{
"path": "Tests/Fixtures/controller/override_defaults.yml",
"chars": 122,
"preview": "app_blog:\n path: /blog\n controller: AppBundle:Homepage:show\n defaults:\n _controller: AppBundle:Blog:inde"
},
{
"path": "Tests/Fixtures/controller/routing.yml",
"chars": 179,
"preview": "app_homepage:\n path: /\n controller: AppBundle:Homepage:show\n\napp_blog:\n path: /blog\n defaults:\n _cont"
},
{
"path": "Tests/Fixtures/defaults.php",
"chars": 238,
"preview": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n $ro"
},
{
"path": "Tests/Fixtures/defaults.yml",
"chars": 74,
"preview": "defaults:\n path: /defaults\n locale: en\n format: html\n stateless: true\n"
},
{
"path": "Tests/Fixtures/directory/recurse/routes1.yml",
"chars": 27,
"preview": "route1:\n path: /route/1\n"
},
{
"path": "Tests/Fixtures/directory/recurse/routes2.yml",
"chars": 27,
"preview": "route2:\n path: /route/2\n"
},
{
"path": "Tests/Fixtures/directory/routes3.yml",
"chars": 27,
"preview": "route3:\n path: /route/3\n"
},
{
"path": "Tests/Fixtures/directory_import/import.yml",
"chars": 61,
"preview": "_directory:\n resource: \"../directory\"\n type: directory\n"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher0.php",
"chars": 245,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher1.php",
"chars": 5627,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n true, // $matchHo"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher10.php",
"chars": 187630,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher11.php",
"chars": 2882,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher12.php",
"chars": 1360,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher13.php",
"chars": 689,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n true, // $matchHo"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher14.php",
"chars": 458,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher2.php",
"chars": 5826,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n true, // $matchHo"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher3.php",
"chars": 1054,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher4.php",
"chars": 976,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher5.php",
"chars": 1723,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher6.php",
"chars": 3017,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher7.php",
"chars": 3017,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
},
{
"path": "Tests/Fixtures/dumper/compiled_url_matcher8.php",
"chars": 776,
"preview": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n false, // $matchH"
}
]
// ... and 115 more files (download for full content)
About this extraction
This page contains the full source code of the symfony/routing GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 315 files (892.0 KB), approximately 247.8k tokens, and a symbol index with 1150 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.