hp

/*
 * 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\Scheduler\Trigger;

/**
 * @author Kevin Bond <kevinbond@gmail.com>
 */
final class JitterTrigger extends AbstractDecoratedTrigger
{
    /**
     * @param positive-int $maxSeconds
     */
    public function __construct(private readonly TriggerInter

>maxSeconds);
    }

    public function getNextRunDate(\DateTimeImmutable $run): ?\DateTimeImmutable
    {
        if (!$nextRun = $this->trigger->getNextRunDate($run)) {
            return null;
        }

        return $nextRun->add(new \DateInterval(\

face $trigger, private readonly int $maxSeconds = 60)
    {
        parent::__construct($trigger);
    }

    public function __toString(): string
    {
        return \sprintf('%s with 0-%d second jitter', $this->trigger, $this-


buted with this source code.
 */

namespace Symfony\Component\Scheduler\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Sche

ug:scheduler', description: 'List schedules and their recurring messages')]
final class DebugCommand extends Command
{
    private array $scheduleNames;

    public function __construct(private ServiceProviderInterface $schedules)
    {
        $this->sche

duler\Schedule;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Service\ServiceProviderInterface;

/**
 * Command to list/debug schedules.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
#[AsCommand(name: 'deb


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Scheduler\EventListener;

use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;

Symfony\Component\Scheduler\Event\PostRunEvent;
use Symfony\Component\Scheduler\Event\PreRunEvent;
use Symfony\Component\Scheduler\Messenger\ScheduledStamp;

class DispatchSchedulerEventListener implements EventSubscriberInterface
{
    public function __c

use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
use Symfony\Component\Messenger\Stamp\HandledStamp;
use Symfony\Component\Messenger\Stamp\StampInterface;
use Symfony\Component\Scheduler\Event\FailureEvent;
use


se Symfony\Component\Lock\Lock;
use Symfony\Component\Lock\LockInterface;
use Symfony\Component\Lock\NoLock;
use Symfony\Component\Lock\Store\InMemoryStore;
use Symfony\Component\Scheduler\Generator\Checkpoint;
use Symfony\Contracts\Cache\ItemInterface;

class CheckpointTest extends TestCase
{
    public function testWithoutLockAndWithoutState()
    {
        $now = new \DateTimeImmutable('2020-02-20 20:20:20Z');
        $later = $now->modify('1 hour');
        $checkpoint = new Checkpoint('dummy');

 $checkpoint->time());
        $this->assertSame(7, $checkpoint->index());

        $checkpoint->release($later, null);
    }

    public function testWithStateInitStateOnFirstAcquiring()
    {
        $checkpoint = new Checkpoint('cache', new NoLock(), $c

  $this->assertTrue($checkpoint->acquire($now));
        $this->assertSame($now, $checkpoint->time());
        $this->assertSame(-1, $checkpoint->index());

        $checkpoint->save($later, 7);

        $this->assertSame($later,


rayAdapter;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Scheduler\Command\DebugCommand;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;
use Symfony\Component\Scheduler\Trigger\CallbackTrigger;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Service\ServiceProviderInterface;

/**
 * @author Max Beckers <beckers.maximilian@gmail.com>
 */
class DebugCommandTest extends TestCase
{
    public function testExecuteWithoutSch

       $command = new DebugCommand($schedules);
        $tester = new CommandTester($command);

        $tester->execute([], ['decorated' => false]);

        $display = preg_replace('/ +$/m', '', $tester->getDisplay(true));
        $this->assertSame("\nSc

edules()
    {
        $schedules = $this->createMock(ServiceProviderInterface::class);
        $schedules
            ->expects($this->once())
            ->method('getProvidedServices')
            ->willReturn([])
        ;


 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\Scheduler\Tests\Trigger;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Scheduler\Trigger\CallbackTrigger;

class CallbackTriggerTest extends TestCase
{
    public function testToString()
    {
        $trigger = new CallbackTrigger(static fn () => null);

da-f]{32}$/', (string) $trigger);

        $trigger = new CallbackTrigger(static fn () => null, '');
        $this->assertSame('', (string) $trigger);

        $trigger = new CallbackTrigger(static fn () => null, 'foo');
        $this->assertSame('foo', (s


 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\Scheduler\Tests\Trigger;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Scheduler\Trigger\ExcludeTimeTrigger;
use Symfony\Component\Scheduler\Trigger\TriggerInterface;

class ExcludeTimeTriggerTest extends TestCase
{
    public function testGetNextRun()
    {

w ExcludeTimeTrigger(
            $inner,
            new \DateTimeImmutable('2020-02-20T02:02:02Z'),
            new \DateTimeImmutable('2020-02-20T20:20:20Z')
        );

        $this->assertEquals(new \DateTimeImmutable('2020-02-20T02:02:01Z'), $schedu

     $inner = $this->createStub(TriggerInterface::class);
        $inner
            ->method('getNextRunDate')
            ->willReturnCallback(static fn (\DateTimeImmutable $d) => $d->modify('+1 sec'));

        $scheduled = ne


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Scheduler\Tests\Messenger;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Message\RedispatchMessage;
use Symfony\Component\Scheduler\Exception\LogicException;
use Symfony\Component\Scheduler\Generator\MessageContext;
use Symfony\Component\Scheduler\Generator\MessageGeneratorInterface;
us

public function testGetFromIterator()
    {
        $messages = [
            (object) ['id' => 'first'],
            (object) ['id' => 'second'],
        ];
        $generator = $this->createStub(MessageGeneratorInterface::class);
        $generator->meth

e Symfony\Component\Scheduler\Messenger\ScheduledStamp;
use Symfony\Component\Scheduler\Messenger\SchedulerTransport;
use Symfony\Component\Scheduler\Trigger\TriggerInterface;

class SchedulerTransportTest extends TestCase
{


/*
 * 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\Scheduler\Event;

use Symfony\Component\Scheduler\Generator\MessageContext;
use Symfony\Component\Scheduler\ScheduleProviderInterface;

class PreRunEvent
{
    private bool $shouldCancel = false;

    public function __construct(
        private readon

n $this->messageContext;
    }

    public function getSchedule(): ScheduleProviderInterface
    {
        return $this->schedule;
    }

    public function getMessage(): object
    {
        return $this->message;
    }

    public function shouldCancel(

ly ScheduleProviderInterface $schedule,
        private readonly MessageContext $messageContext,
        private readonly object $message,
    ) {
    }

    public function getMessageContext(): MessageContext
    {
        retur


<?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\Scheduler\Trigger;

use Symfony\Component\Scheduler\Generator\MessageContext;

final class CallbackMessageProvider implements MessageProviderInterface, \Stringable
{
    private \Closure $callback;

    /**
     * @param callable(MessageContext):

ages(MessageContext $context): iterable
    {
        return ($this->callback)($context);
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function __toString(): string
    {
        return $this->description ?:

 iterable<object> $callback
     */
    public function __construct(callable $callback, private string $id = '', private string $description = '')
    {
        $this->callback = $callback(...);
    }

    public function getMess


/*
 * 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\Scheduler\Trigger;

final class ExcludeTimeTrigger extends AbstractDecoratedTrigger
{
    public function __construct(
        private readonly TriggerInterface $inner,
        private readonly \DateTimeImmutable $from,
        private readonly \DateTi

::ATOM), $this->until->format(\DateTimeInterface::ATOM));
    }

    public function getNextRunDate(\DateTimeImmutable $run): ?\DateTimeImmutable
    {
        $nextRun = $this->inner->getNextRunDate($run);
        if ($nextRun >= $this->from && $nextRun <

meImmutable $until,
    ) {
        parent::__construct($inner);
    }

    public function __toString(): string
    {
        return \sprintf('%s, excluding from %s until %s', $this->inner, $this->from->format(\DateTimeInterface


 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\Scheduler\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Scheduler\Exception\InvalidArgumentException;
use Symfony\Component\Scheduler\RecurringMessage;

class RecurringMessageTest extends TestCase
{
    public function testCanCreateHashedCronMessage()

cron('#weekly', $object)->getTrigger());
    }

    public function testHashedCronContextIsRequiredIfMessageIsNotStringable()
    {
        $this->expectException(InvalidArgumentException::class);

        RecurringMessage::cron('#midnight', new \stdClass(

 {
        $object = new DummyStringableMessage();

        $this->assertSame('30 0 * * *', (string) RecurringMessage::cron('#midnight', $object)->getTrigger());
        $this->assertSame('30 0 * * 3', (string) RecurringMessage::


 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\Scheduler\Tests\Trigger;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Scheduler\Trigger\ExcludeTimeTrigger;
use Symfony\Component\Scheduler\Trigger\JitterTrigger;
use Symfony\Component\Scheduler\Trigger\TriggerInterface;

class AbstractDecoratedTri

    $this->assertSame([$trigger], iterator_to_array($trigger->decorators()));
    }

    public function testCanGetNestedInnerTrigger()
    {
        $trigger = new ExcludeTimeTrigger(
            $jitter = new JitterTrigger($inner = $this->createStub(Trig

ggerTest extends TestCase
{
    public function testCanGetInnerTrigger()
    {
        $trigger = new JitterTrigger($inner = $this->createStub(TriggerInterface::class));

        $this->assertSame($inner, $trigger->inner());


buted with this source code.
 */

namespace Symfony\Component\Scheduler\Tests\DependencyInjection;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\Scheduler\DependencyInjection\AddScheduleMessengerPass;

class AddScheduleMessengerPassTest extends TestCase
{
    #[DataProvider('processSchedule

$definition = new Definition($commandClass);
        $definition->addTag('console.command');
        $definition->addTag('scheduler.task', $arguments);
        $container->setDefinition($commandClass, $definition);

        (new AddScheduleMessengerPass())

rTaskCommandProvider')]
    public function testProcessSchedulerTaskCommand(array $arguments, string $expectedCommand, string $commandClass = SchedulableCommand::class)
    {
        $container = new ContainerBuilder();


 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\Scheduler\Event;

use Symfony\Component\Scheduler\Generator\MessageContext;
use Symfony\Component\Scheduler\ScheduleProviderInterface;

class FailureEvent
{
    private bool $shouldIgnore = false;

    public function __construct(
        private readonly Sc

t(): MessageContext
    {
        return $this->messageContext;
    }

    public function getSchedule(): ScheduleProviderInterface
    {
        return $this->schedule;
    }

    public function getMessage(): object
    {
        return $this->message;

heduleProviderInterface $schedule,
        private readonly MessageContext $messageContext,
        private readonly object $message,
        private readonly \Throwable $error,
    ) {
    }

    public function getMessageContex


<?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\Scheduler\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Scheduler\Exception\LogicException;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;

class ScheduleTest extends TestCase
{
    pub

       $schedule = new Schedule();
        $schedule->add(RecurringMessage::cron('* * * * *', new \stdClass()));

        $this->expectException(LogicException::class);

        $schedule->add(RecurringMessage::cron('* * * * *', new \stdClass()));
    }
}

lic function testCannotAddDuplicateMessage()
    {


ion\InvalidArgumentException;
use Symfony\Component\Scheduler\Trigger\PeriodicalTrigger;
use Symfony\Component\Scheduler\Trigger\TriggerInterface;

class PeriodicalTriggerTest extends TestCase
{
    #[DataProvider('provideForConstructor')]
    public function testConstructor(PeriodicalTrigger $trigger, bool $optimizable = true)
    {
        $run = new \DateTimeImmutable('2922-02-22 12:34:00+00:00');

        $this->assertSame('2922-02-23 13:34:00+01:00', $trigger->getNextRunDate($run)->format('Y-m-d H:i:sP

getValue($trigger));
        }
    }

    public static function provideForConstructor(): iterable
    {
        $from = new \DateTimeImmutable($now = '2022-02-22 13:34:00+01:00');
        $until = new \DateTimeImmutable($farFuture = '3000-01-01');

'));

        if ($optimizable) {
            // test that we are using the fast algorithm for short period of time
            $p = new \ReflectionProperty($trigger, 'intervalInSeconds');
            $this->assertNotSame(0, $p->


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Scheduler\Trigger;

use Symfony\Component\Scheduler\Exception\InvalidArgumentException;

class PeriodicalTrigger implements StatefulTriggerInterface
{
    private float $intervalInSeconds = 0.0;
    private ?\DateTimeImmutable $from;
    private \DateTimeImmutable $until;
    private \DatePeriod $period;
    private string $description;
    priva

\DateTimeImmutable('3000-01-01'),
    ) {
        $this->from = \is_string($from) ? new \DateTimeImmutable($from) : $from;
        $this->until = \is_string($until) ? new \DateTimeImmutable($until) : $until;

        if (\is_int($interval) || \is_float($in

te string|int|float|\DateInterval $interval;

    public function __construct(
        string|int|float|\DateInterval $interval,
        string|\DateTimeImmutable|null $from = null,
        string|\DateTimeImmutable $until = new


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Scheduler\Trigger;

use Cron\CronExpression;
use Random\Engine\Xoshiro256StarStar;
use Random\Randomizer;
use Symfony\Component\Scheduler\Exception\LogicException;

/**
 * Use cron expressions to describe a periodical trigger.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class CronExpressionTrigger implements TriggerInterface
{


ng\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, ConfigurableRequirementsInte

  // 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' => '!',

rface
{
    private const QUERY_FRAGMENT_DECODED = [
        // RFC 3986 explicitly allows those in the query/fragment to reference other URIs unencoded
        '%2F' => '/',
        '%252F' => '%2F',
        '%3F' => '?',


ge.
 *
 * (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\Scheduler\Messenger;

use Psr\Clock\ClockInterface;
use Psr\Container\ContainerInterface;
use Symfony\Component\Clock\Clock;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
use Symfony\Component\Sche

/
class SchedulerTransportFactory implements TransportFactoryInterface
{
    public function __construct(
        private readonly ContainerInterface $scheduleProviders,
        private readonly ClockInterface $clock = new Clock(),
    ) {
    }

    publi

duler\Exception\InvalidArgumentException;
use Symfony\Component\Scheduler\Generator\MessageGenerator;
use Symfony\Component\Scheduler\ScheduleProviderInterface;

/**
 * @implements TransportFactoryInterface<SchedulerTransport>
 *


ge.
 *
 * (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\Scheduler\Messenger\Serializer\Normalizer;

use Symfony\Component\Messenger\Transport\Serialization\Serializer;
use Symfony\Component\Scheduler\Trigger\TriggerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterf

e,
        ];
    }

    /**
     * @param TriggerInterface $data
     */
    public function normalize(mixed $data, ?string $format = null, array $context = []): string
    {
        return (string) $data;
    }

    public function supportsNormalization(

ace;

final class SchedulerTriggerNormalizer implements DenormalizerInterface, NormalizerInterface
{
    public function getSupportedTypes(?string $format): array
    {
        return [
            TriggerInterface::class => fals


ge.
 *
 * (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;

        $n

/**
     * 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 t

ew->id = $id;

        return $new;
    }

    /**
     * Returns the target name of this alias.
     *
     * @return string The target name
     */
    public function getId(): string
    {
        return $this->id;
    }


 *
 * 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
{
    /**
     * @param string      $staticPrefix  The static prefix of the compiled route
     * @param string      $regex         The regular expression to use to match this route
     * @param arr

ostTokens    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(

ay       $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       $h


http://tobion.de>
 */
class Route
{
    private string $path = '/';
    private string $host = '';
    private array $schemes = [];
    private array $methods = [];
    private array $defaults = [];
    private array $requirements = [];
    private array $options = [];
    private string $condition = '';
    private ?CompiledRoute $compiled = null;

    /**
     * Constructor.
     *
     * Available options:
     *
     *  * compiler_class: A class name able to compile this route instance (RouteCompiler by

f default parameter values
     * @param array<string|\Stringable> $requirements An array of requirements for parameters (regexes)
     * @param array                     $options      An array of options
     * @param string|null               $host

 default)
     *  * utf8:           Whether UTF-8 matching is enforced or not
     *
     * @param string                    $path         The path pattern to match
     * @param array                     $defaults     An array o


e;
use Symfony\Component\Config\ConfigCacheInterface;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\CompiledUrlGenerator;
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
use Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper;
use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterfa

cher\Dumper\MatcherDumperInterface;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;

/**
 * The Router class is an example of the integration of all pieces of the
 * routing system f

ce;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
use Symfony\Component\Routing\Mat


/*
 * 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 MethodNotAllowedExcept

e = '', int $code = 0, ?\Throwable $previous = null)
    {
        $this->allowedMethods = array_map('strtoupper', $allowedMethods);

        parent::__construct($message, $code, $previous);
    }

    /**
     * Gets the allowed HTTP methods.
     *

ion extends \RuntimeException implements ExceptionInterface
{
    protected array $allowedMethods = [];

    /**
     * @param string[] $allowedMethods
     */
    public function __construct(array $allowedMethods, string $messag


 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 \InvalidArgumentExcepti

array $missingParameters = [], int $code = 0, ?\Throwable $previous = null)
    {
        $this->routeName = $routeName;
        $this->missingParameters = $missingParameters;
        $message = \sprintf('Some mandatory parameters are missing ("%s") to gen

on implements ExceptionInterface
{
    private string $routeName = '';
    private array $missingParameters = [];

    /**
     * @param string[] $missingParameters
     */
    public function __construct(string $routeName = '',


 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\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use Symfony\Contracts\Service\ServiceProviderInterface;

/**
 * Exposes functions defined in the requ

 ServiceProviderInterface $functions,
    ) {
    }

    public function getFunctions(): array
    {
        $functions = [];

        foreach ($this->functions->getProvidedServices() as $function => $type) {
            $functions[] = new ExpressionFuncti

est context to route conditions.
 *
 * @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
 */
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
{
    public function __construct(
        private


 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;

/**
 * RedirectableUrlMatcherInterface knows how to redirect the user.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface RedirectableUrlMatcherInterface
{
    /**
     * Redirects the user to another URL and returns the parameter

    $path   The path info to redirect to
     * @param string      $route  The route name that matched
     * @param string|null $scheme The URL scheme (null to keep the current one)
     */
    public function redirect(string $path, string $route, ?string

s for the redirection.
     *
     * @param string


/*
 * 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\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\NoConfigurationException;
use Symfony\Component\Routing\Exception\ResourceNotFoun

ch a request with a set of routes.
     *
     * If the matcher cannot find information, it must throw one of the exceptions documented
     * below.
     *
     * @throws NoConfigurationException  If no routing configuration could be found
     * @throws

dException;

/**
 * RequestMatcherInterface is the interface that all request matcher classes must implement.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface RequestMatcherInterface
{
    /**
     * Tries to mat


sionLanguage;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\NoConfigurationException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * UrlMatcher matches URL based on a set of routes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Url

ld be allowed for the request.
     */
    protected array $allow = [];

    /**
     * Collects URI schemes that would be allowed for the request.
     *
     * @internal
     */
    protected array $allowSchemes = [];
    protected ?Request $request = nu

Matcher implements UrlMatcherInterface, RequestMatcherInterface
{
    public const REQUIREMENT_MATCH = 0;
    public const REQUIREMENT_MISMATCH = 1;
    public const ROUTE_MATCH = 2;

    /**
     * Collects HTTP methods that wou


buted 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
 */
t

ic function match(string $pathinfo): array
    {
        $allow = $allowSchemes = [];
        if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
            return $ret;
        }
        if ($allow) {
            throw new MethodNotAllowedExce

rait CompiledUrlMatcherTrait
{
    private bool $matchHost = false;
    private array $staticRoutes = [];
    private array $regexpList = [];
    private array $dynamicRoutes = [];
    private ?\Closure $checkCondition;

    publ


buted 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[]|

* @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,

self[]
     */
    private array $items = [];

    public function __construct(
        private string $prefix = '/',
    ) {
    }

    public function getPrefix(): string
    {
        return $this->prefix;
    }

    /**


ge.
 *
 * (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 c

e): 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 env

ompletely.
 *
 * The possible configurations and use-cases:
 * - setStrictRequirements(true): Throw an exception for mismatching requirements. This
 *   is mostly useful in development environment.
 * - setStrictRequirements(fals


ony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Scheduler\Trigger;

use Symfony\Component\Scheduler\Generator\MessageContext;

final class StaticMessageProvider implements MessageProviderInterface, \Stringable
{
    /**
     * @param array<object> $messages
     */
    public function __construct(
        private array $messages,
        private string $id = '',
        private string

n getMessages(MessageContext $context): iterable
    {
        return $this->messages;
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function __toString(): string
    {
        return $this->description ?: $th

$description = '',
    ) {
    }

    public functio


<?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\Scheduler\Messenger;

/**
 * Represents a service call.
 *
 * @author valtzu <valtzu@gmail.com>
 */
class ServiceCallMessage implements \Stringable
{
    public function __construct(
        private readonly string $serviceId,
        private rea

  {
        return $this->method;
    }

    public function getArguments(): array
    {
        return $this->arguments;
    }

    public function __toString(): string
    {
        return "@$this->serviceId".('__invoke' !== $this->method ? "::$this->met

donly string $method = '__invoke',
        private readonly array $arguments = [],
    ) {
    }

    public function getServiceId(): string
    {
        return $this->serviceId;
    }

    public function getMethod(): string


buted with this source code.
 */

namespace Symfony\Component\Routing;

use Symfony\Component\HttpFoundation\Request;

/**
 * Holds information about the current request.
 *
 * This class implements a fluent interface.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Tobias Schultze <http://tobion.de>
 */
class RequestContext
{
    private string $baseUrl;
    private string $pathInfo;
    private string $method;
    private string $host;
    private string $scheme;
    private int $httpPort;

int $httpPort = 80, int $httpsPort = 443, string $path = '/', string $queryString = '', ?array $parameters = null)
    {
        $this->setBaseUrl($baseUrl);
        $this->setMethod($method);
        $this->setHost($host);
        $this->setScheme($scheme

    private int $httpsPort;
    private string $queryString;
    private array $parameters = [];

    public function __construct(string $baseUrl = '', string $method = 'GET', string $host = 'localhost', string $scheme = 'http',


hor Tobias Schultze <http://tobion.de>
 */
class RouteCompiler implements RouteCompilerInterface
{
    /**
     * This string defines the characters that are automatically considered separators in front of
     * optional placeholders (with default and no static text following). Such a single separator
     * can be left out together with the optional placeholder from matching and generating URLs.
     */
    public const SEPARATORS = '/,;.:-_~+*=@|';

    /**
     * The maximum supported length of a PCRE s

s named _fragment
     * @throws \LogicException           if a variable is referenced more than once
     * @throws \DomainException          if a variable name starts with a digit or if it is too long to be successfully used as
     *

ubpattern name
     * http://pcre.org/current/doc/html/pcre2pattern.html#SEC16.
     *
     * @internal
     */
    public const VARIABLE_MAXIMUM_LENGTH = 32;

    /**
     * @throws \InvalidArgumentException if a path variable i


 *
 * 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;

    /** @va

er/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:

r string[] */
    public array $schemes;

    /** @var (string|DeprecatedAlias)[] */
    public array $aliases = [];

    /**
     * @param string|array<string,string>|null                  $path         The route path (i.e. "/us


ge.
 *
 * (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\Exception\ExceptionInterface;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInte

['HEAD', 'GET'], true)) {
                throw $e;
            }

            if ($this->allowSchemes) {
                redirect_scheme:
                $scheme = $this->context->getScheme();
                $this->context->setScheme(current($this->allow

rface
{
    public function match(string $pathinfo): array
    {
        try {
            return parent::match($pathinfo);
        } catch (ResourceNotFoundException $e) {
            if (!\in_array($this->context->getMethod(),


 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\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\NoConfigurationException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RequestCon

ace
{
    /**
     * Tries to match a URL path with a set of routes.
     *
     * If the matcher cannot find information, it must throw one of the exceptions documented
     * below.
     *
     * @param string $pathinfo The path info to be parsed (raw fo

textAwareInterface;

/**
 * UrlMatcherInterface is the interface that all URL matcher classes must implement.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface UrlMatcherInterface extends RequestContextAwareInterf


*
 * 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 MatcherDumperInterfa

g 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(): Route

ce
{
    /**
     * Dumps a set of routes to a strin


 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\Scheduler\Messenger;

use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Message\RedispatchMessage;
use Symfony\Component\Messenger\Transport\TransportInterface;
use Symfony\Component\Scheduler\Exception\LogicException;
use Symfony\Component\Schedu

 * @param int $fetchSize Best-effort hint about how many messages can be received in one call
     */
    public function get(/* int $fetchSize = 1 */): iterable
    {
        foreach ($this->messageGenerator->getMessages() as $context => $message) {

ler\Generator\MessageGeneratorInterface;

class SchedulerTransport implements TransportInterface
{
    public function __construct(
        private readonly MessageGeneratorInterface $messageGenerator,
    ) {
    }

    /**


y\Component\Routing\Exception\RouteCircularReferenceException;

/**
 * A RouteCollection represents a set of Route instances.
 *
 * When adding a route at the end of the collection, an existing route
 * with the same name is removed first. So there can only be one route
 * with a given name.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Tobias Schultze <http://tobion.de>
 *
 * @implements \IteratorAggregate<string, Route>
 */
class RouteCollection implements \IteratorAggregate, \Countable
{

  private array $resources = [];

    /**
     * @var array<string, int>
     */
    private array $priorities = [];

    public function __clone()
    {
        foreach ($this->routes as $name => $route) {
            $this->routes[$name] = clone $route;

    /**
     * @var array<string, Route>
     */
    private array $routes = [];

    /**
     * @var array<string, Alias>
     */
    private array $aliases = [];

    /**
     * @var array<string, ResourceInterface>
     */


 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 Co

edUrlMatcherTrait;

    public function __construct(array $compiledRoutes, RequestContext $context)
    {
        $this->context = $context;
        [$this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition] = $

mpiledUrlMatcher extends UrlMatcher
{
    use Compil


Dumper 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 [

ovider;
    }

    /**
     * Generates the arrays for CompiledUrlMatcher's constructor.
     */
    public function getCompiledRoutes(bool $forDump = false): array
    {
        // Group hosts by same-suffix, re-order when possible
        $matchHost = fa

         {$this->generateCompiledRoutes()}];

            EOF;
    }

    public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider): void
    {
        $this->expressionLanguageProviders[] = $pr


ge.
 *
 * (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
{
    priv

     $this->compiledRoutes = $compiledRoutes;
        $this->context = $context;
        $this->logger = $logger;
    }

    public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string
    {
        $loc

ate array $compiledRoutes = [];

    public function __construct(
        array $compiledRoutes,
        RequestContext $context,
        ?LoggerInterface $logger = null,
        private ?string $defaultLocale = null,
    ) {


buted with this source code.
 */

namespace Symfony\Component\Scheduler\DependencyInjection;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Messenger\RunCommandMessage;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentExcep

CallMessage;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;

/**
 * @internal
 */
class AddScheduleMessengerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void

tion;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Messenger\Message\RedispatchMessage;
use Symfony\Component\Messenger\Transport\TransportInterface;
use Symfony\Component\Scheduler\Messenger\Service


buted with this source code.
 */

namespace Symfony\Component\Routing\Matcher;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ExceptionInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * TraceableUrlMatcher helps debug path info matching by tracing the match.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class TraceableUrlMatcher extends UrlMatcher
{
    public const ROUTE_DOES_NOT_MATCH = 0;
    public cons

info);
        } catch (ExceptionInterface) {
        }

        return $this->traces;
    }

    public function getTracesForRequest(Request $request): array
    {
        $this->request = $request;
        $traces = $this->getTraces($request->getPathInfo

t ROUTE_ALMOST_MATCHES = 1;
    public const ROUTE_MATCHES = 2;

    protected array $traces;

    public function getTraces(string $pathinfo): array
    {
        $this->traces = [];

        try {
            $this->match($path


n 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\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;

/**
 * RouterInterface is the interface that all Router classes must implement.
 *
 * This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface.
 *
 * @auth

ce RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
{
    /**
     * Gets the RouteCollection instance associated with this Router.
     *
     * WARNING: This method should never be used at runtime as it is SLOW.
     *          You migh

or Fabien Potencier <fabien@symfony.com>
 */
interfa


 *
 * 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

    {
        $compiledRoutes = [];
        foreach ($this->getRoutes()->all() as $name => $route) {
            $compiledRoute = $route->compile();

            $compiledRoutes[$name] = [
                $compiledRoute->getVariables(),
                $r

 Potencier <fabien@symfony.com>
 * @author Tobias Schultze <http://tobion.de>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class CompiledUrlGeneratorDumper extends GeneratorDumper
{
    public function getCompiledRoutes(): array


ge.
 *
 * (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 Alexandr

lic 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();
        }

e Daubois <alex.daubois@gmail.com>
 */
class AttributeDirectoryLoader extends AttributeFileLoader
{
    /**
     * @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed
     */
    pub


 *
 * 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

cted AttributeClassLoader $loader,
    ) {
        if (!\function_exists('token_get_all')) {
            throw new \LogicException('The Tokenizer extension is required for the routing attribute loader.');
        }

        parent::__construct($locator);

 Fabien Potencier <fabien@symfony.com>
 * @author Alexandre Daubois <alex.daubois@gmail.com>
 */
class AttributeFileLoader extends FileLoader
{
    public function __construct(
        FileLocatorInterface $locator,
        prote


ony.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,
        ?strin

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

g $env = null,
    ) {
        parent::__construct($


ocalizedRouteTrait;
use Symfony\Component\Routing\Loader\Configurator\Traits\PrefixTrait;
use Symfony\Component\Routing\RouteCollection;

/**
 * @internal
 */
trait ContentLoaderTrait
{
    use HostTrait;
    use LocalizedRouteTrait;
    use PrefixTrait;

    /**
     * Config keys accepted at the route or import level by {@see validate()}.
     */
    private const AVAILABLE_KEYS = [
        'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'conditio

ng each entry to {@see parseRoute()} or {@see parseImport()}.
     */
    private function loadContent(RouteCollection $collection, array $config, string $path, string $file): void
    {
        foreach ($config as $name => $config) {
            if (!str_

n', 'controller', 'name_prefix', 'trailing_slash_on_root', 'locale', 'format', 'utf8', 'exclude', 'stateless',
    ];

    /**
     * Processes a parsed configuration array, handling `when@<env>` filtering
     * before dispatchi


<?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

  $collection->addCollection($this->import($path));
        }

        $collection->addResource($globResource);

        return $collection;
    }

    public function supports(mixed $resource, ?string $type = null): bool
    {
        return 'glob' === $t

FileLoader
{
    public function load(mixed $resource, ?string $type = null): mixed
    {
        $collection = new RouteCollection();

        foreach ($this->glob($resource, false, $globResource) as $path => $info) {


 *
 * 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;

{
    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.
        p

/**
 * 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


/*
 * 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,
    ) {
    }

 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

  /**
     * 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


 *
 * 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\PrefixTrait;
    use Traits\RouteTrait;

    private string|array|null $host = null;

ray $parentPrefixes = null,
    ) {
        $this->name = $name;
        $this->collection = new RouteCollection();
        $this->route = new Route('');
    }

    public function __serialize(): array
    {
        throw new \BadMethodCallException('Canno

   private bool $trailingSlashOnRoot = true;

    public function __construct(
        private RouteCollection $parent,
        string $name,
        private ?self $parentConfigurator = null, // for GC control
        private ?ar


ge.
 *
 * (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 f

> [
 *             'resource' => 'routing.controllers',
 *         ],
 *     ]);
 *     ```
 *
 * @psalm-type RouteConfig = array{
 *     path: string|array<string,string>,
 *     controller?: string,
 *     methods?: string|list<string>,
 *     requiremen

or configuring the routes of an application.
 *
 * Example:
 *
 *     ```php
 *     // config/routes.php
 *     namespace Symfony\Component\Routing\Loader\Configurator;
 *
 *     return Routes::config([
 *         'controllers' =


 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\

 = 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 inst

Routing\RouteCollection;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
trait AddTrait
{
    use LocalizedRouteTrait;

    protected RouteCollection $collection;
    protected string $name = '';
    protected ?array $prefixes


ge.
 *
 * (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, boo

es = [];
            foreach ($routes->getAliases() as $name => $alias) {
                $aliases[$alias->getId()][] = $name;
            }
            foreach ($routes->all() as $name => $route) {
                if (null === $locale = $route->getDefault

l $trailingSlashOnRoot): void
    {
        if (\is_array($prefix)) {
            foreach ($prefix as $locale => $localePrefix) {
                $prefix[$locale] = trim(trim($localePrefix), '/');
            }
            $alias


ge.
 *
 * (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 r

fix = '', ?array $prefixes = null): RouteCollection
    {
        $paths = [];

        $routes = new RouteCollection();

        if (\is_array($path)) {
            if (null === $prefixes) {
                $paths = $path;
            } elseif ($missing =

outes.
     *
     * @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 $namePre


buted with this source code.
 */

namespace Symfony\Component\Routing\Tests;

use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RequestContext;

class RequestContextTest extends TestCase
{
    public function testConstruct()
    {
        $requestContext = new RequestContext(
            'foo',
            'post',
            'foo.bar',
            'HTTPS',
            8080,
            444,
            '/ba

od());
        $this->assertEquals('foo.bar', $requestContext->getHost());
        $this->assertEquals('https', $requestContext->getScheme());
        $this->assertSame(8080, $requestContext->getHttpPort());
        $this->assertSame(444, $requestContext->

z',
            'bar=foobar',
            [
                'foo' => 'bar',
            ]
        );

        $this->assertEquals('foo', $requestContext->getBaseUrl());
        $this->assertEquals('POST', $requestContext->getMeth


\Component\Routing\RouteCompiler;

class RouteCompilerTest extends TestCase
{
    #[DataProvider('provideCompileData')]
    public function testCompile($name, $arguments, $prefix, $regex, $variables, $tokens)
    {
        $r = new \ReflectionClass(Route::class);
        $route = $r->newInstanceArgs($arguments);

        $compiled = $route->compile();
        $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
        $this->assertEquals($regex, $compiled->getRegex(), $name

pileData()
    {
        return [
            [
                'Static route',
                ['/foo'],
                '/foo', '{^/foo$}sD', [], [
                    ['text', '/foo'],
                ],
            ],

            [
                'Ro

.' (regex)');
        $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
        $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
    }

    public static function provideCom


 *
 * 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

 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.
 *
 * @

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


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 f

rs),
 * 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

or 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 paramete


/*
 * 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>
 */

(mixed $resource, ?string $type = null): RouteCollection
    {
        $collection = new RouteCollection();

        foreach ($this->taggedClasses as $class) {
            $collection->addCollection($this->import($class, 'attribute'));
        }

        r

final class AttributeServicesLoader extends Loader
{
    /**
     * @param class-string[] $taggedClasses
     */
    public function __construct(
        private array $taggedClasses = [],
    ) {
    }

    public function load


ge.
 *
 * (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>
 */
abstra

d.
     */
    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_ma

ct 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 i


 *
 * 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\RouteCollection;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser as YamlParser;
use Symfony\Component\Yaml\Yaml;

/**
 * YamlFileLoader loads Yaml routing files.

 as doParseRoute;
        validate as doValidate;
    }

    private YamlParser $yamlParser;

    /**
     * @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
     */
    public function load(mixed $file, ?string $type

 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Tobias Schultze <http://tobion.de>
 */
class YamlFileLoader extends FileLoader
{
    use ContentLoaderTrait {
        parseImport as doParseImport;
        parseRoute


 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 __con

) {
        $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,

struct(
        RouteCollection $collection,
        RouteCollection $route,
        string $name = '',
        protected ?CollectionConfigurator $parentConfigurator = null, // for GC control
        ?array $prefixes = null,


 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)) {

etPriority($name) ?? 0;
                $routes->remove($name);
                foreach ($hosts as $locale => $host) {
                    $localizedRoute = clone $route;
                    $localizedRoute->setDefault('_locale', $locale);

     $routes->setHost($hosts ?: '');

            return;
        }

        foreach ($routes->all() as $name => $route) {
            if (null === $locale = $route->getDefault('_locale')) {
                $priority = $routes->g


ge.
 *
 * (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\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Routing\CompiledRoute;

class CompiledRouteTestToStringGadget
{
    public static bool $fired = false;

    public function __toString(): string
    {
        self::$fired = true;

s->assertEquals('prefix', $compiled->getStaticPrefix(), '__construct() takes a static prefix as its second argument');
        $this->assertEquals('regex', $compiled->getRegex(), '__construct() takes a regexp as its third argument');
        $this->assertE

        return '';
    }
}

class CompiledRouteTest extends TestCase
{
    public function testAccessors()
    {
        $compiled = new CompiledRoute('prefix', 'regex', ['tokens'], [], null, [], [], ['variables']);
        $thi


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
{

sentation 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;
}

  /**
     * Dumps a set of routes to a string repre


ony.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 Clo

e, ?string $type = null): RouteCollection
    {
        return $closure($this->env);
    }

    public function supports(mixed $resource, ?string $type = null): bool
    {
        return $resource instanceof \Closure && (!$type || 'closure' === $type);

sure.
     */
    public function load(mixed $closur


 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

            if ('.' !== $dir[0]) {
                $this->setCurrentDir($path);
                $subPath = $path.'/'.$dir;
                $subType = null;

                if (is_dir($subPath)) {
                    $subPath .= '/';
                    $s

 $type = null): mixed
    {
        $path = $this->locator->locate($file);

        $collection = new RouteCollection();
        $collection->addResource(new DirectoryResource($path));

        foreach (scandir($path) as $dir) {


 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(

CLASS__);
    }

    public function __unserialize(array $data): void
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        $this->parent->addCollection($this->route);
    }

       private RouteCollection $parent,
        RouteCollection $route,
    ) {
        $this->route = $route;
    }

    public function __serialize(): array
    {
        throw new \BadMethodCallException('Cannot serialize '.__


 *
 * 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->addDefau

requirements);

        return $this;
    }

    /**
     * Adds options.
     *
     * @return $this
     */
    final public function options(array $options): static
    {
        $this->route->addOptions($options);

        return $this;
    }

    /**

lts($defaults);

        return $this;
    }

    /**
     * Adds requirements.
     *
     * @return $this
     */
    final public function requirements(array $requirements): static
    {
        $this->route->addRequirements($


n new class {
    public function __invoke(RoutingConfigurator $routes)
    {
        $routes
            ->collection()
            ->add('foo', '/foo')
            ->condition('abc')
            ->options(['utf8' => true])
            ->add('buz', 'zub')
            ->controller('foo:act')
            ->stateless(true)
            ->add('controller_class', '/controller')
            ->controller(['Acme\MyApp\MyController', 'myAction']);

        $routes->import('php_dsl_sub.php')
            ->prefix('/su

      $routes->import('php_dsl_sub.php')
            ->namePrefix('z_')
            ->prefix('/zub');

        $routes->import('php_dsl_sub_root.php')
            ->prefix('/bus', false);

        $routes->add('ouf', '/ouf')
            ->schemes(['https']


 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\Tests\Matcher;

use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
use Symfony\Component\Routing\RequestContext;
u

k = false)
    {
        $dumper = new CompiledUrlMatcherDumper($routes);
        $compiledRoutes = $dumper->getCompiledRoutes();

        if (!$mock) {
            return new TestCompiledRedirectableUrlMatcher($compiledRoutes, $context ?? new RequestConte

se Symfony\Component\Routing\RouteCollection;

class CompiledRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
{
    protected function getUrlMatcher(RouteCollection $routes, ?RequestContext $context = null, bool $moc


 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\Tests\Matcher;

use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\

 $collection->add('static_host_route', new Route('/test', [], [], [], 'API.example.com'));

        $context = new RequestContext('/test', 'GET', 'api.example.com');
        $matcher = new UrlMatcher($collection, $context);

        $result = $matcher->mat

Routing\Route;
use Symfony\Component\Routing\RouteCollection;

class CompiledUrlMatcherTest extends UrlMatcherTest
{
    public function testStaticHostIsCaseInsensitive()
    {
        $collection = new RouteCollection();


ge.
 *
 * (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\Tests\Matcher;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Routing\Matcher\ExpressionLanguageProvider;
use Symfo

      $functionProvider = new ServiceLocator([
            'env' => static fn () => static fn (string $arg) => [
                'APP_ENV' => 'test',
                'PHP_VERSION' => '7.2',
            ][$arg] ?? null,
            'sum' => static fn () =>

ny\Component\Routing\RequestContext;

class ExpressionLanguageProviderTest extends TestCase
{
    private RequestContext $context;
    private ExpressionLanguage $expressionLanguage;

    protected function setUp(): void
    {


buted with this source code.
 */

namespace Symfony\Component\Routing\Tests\Matcher;

use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

class RedirectableUrlMatcherTest extends UrlMatcherTest
{
    public function testMissingTrailingSlash()
    {
        $coll = new RouteCollection();
        $coll->a

 testExtraTrailingSlash()
    {
        $coll = new RouteCollection();
        $coll->add('foo', new Route('/foo'));

        $matcher = $this->getUrlMatcher($coll, null, true);
        $matcher->expects($this->once())->method('redirect')->willReturn([]);

dd('foo', new Route('/foo/'));

        $matcher = $this->getUrlMatcher($coll, null, true);
        $matcher->expects($this->once())->method('redirect')->willReturn([]);
        $matcher->match('/foo');
    }

    public function


 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\Tests\Fixtures\Psr4Controllers\SubNamespace\EvenDeeperNamespace;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/my/other/route', name: 'my_other_controller_', methods: ['PUT'])]
final class MyOthe

  public function firstAction(): Response
    {
        return new Response('', Response::HTTP_NO_CONTENT);
    }

    #[Route('/second', name: 'two')]
    public function secondAction(): Response
    {
        return new Response('', Response::HTTP_NO_CON

rController
{
    #[Route('/first', name: 'one')]


pace Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures;

use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Tests\Fixtures\AttributedClasses\BarClass;
use Symfony\Component\Routing\Tests\Fixtures\Enum\TestIntBackedEnum;
use Symfony\Component\Routing\Tests\Fixtures\Enum\TestStringBackedEnum;

class DefaultValueController
{
    #[Route(path: '/{default}/path', name: 'action')]
    public function action($default = 'value')
    {
    }

    #[
        Route(path: '/hello/{nam

e: 'string_enum_action')]
    public function stringEnumAction(TestStringBackedEnum $default = TestStringBackedEnum::Diamonds)
    {
    }

    #[Route(path: '/enum/{default<\d+>}', name: 'int_enum_action')]
    public function intEnumAction(TestIntBackedE

e<\w+>}', name: 'hello_without_default'),
        Route(path: 'hello/{name<\w+>?Symfony}', name: 'hello_with_default'),
    ]
    public function hello(string $name = 'World')
    {
    }

    #[Route(path: '/enum/{default}', nam


<?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\Tests\Fixtures\AttributeFixtures;

use Symfony\Component\Routing\Attribute\Route;

#[Route(path: '/defaults', methods: ['GET'], schemes: ['https'], locale: 'g_locale', format: 'g_format')]
class GlobalDefaultsClass
{
    #[Route(path: '/s

    #[Route(path: '/redundant-method', name: 'redundant_method',  methods: ['GET'])]
    public function redundantMethod()
    {
    }

    #[Route(path: '/redundant-scheme', name: 'redundant_scheme', schemes: ['https'])]
    public function redundantSch

pecific-locale', name: 'specific_locale', locale: 's_locale')]
    public function locale()
    {
    }

    #[Route(path: '/specific-format', name: 'specific_format', format: 's_format')]
    public function format()
    {
    }


 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\Tests\Fixtures\AttributeFixtures;

use Symfony\Component\Routing\Attribute\DeprecatedAlias;
use Symfony\Component\Routing\Attribute\Route;

class MultipleDeprecatedAliasRouteController
{
    #[Route('/path', name: 'action_with_multiple_deprecated_alias',

_deprecated', 'MyFirstBundleFixture', '1.0'),
        new DeprecatedAlias('my_second_alias_deprecated', 'MySecondBundleFixture', '2.0'),
        new DeprecatedAlias('my_third_alias_deprecated', 'SurprisedThirdBundleFixture', '3.0'),
    ])]
    public func

alias: [
        new DeprecatedAlias('my_first_alias


null, false, false, null]],
        '/test/baz.html' => [[['_route' => 'baz2'], null, null, null, false, false, null]],
        '/test/baz3' => [[['_route' => 'baz3'], null, null, null, true, false, null]],
        '/foofoo' => [[['_route' => 'foofoo', 'def' => 'test'], null, null, null, false, false, null]],
        '/spa ce' => [[['_route' => 'space'], null, null, null, false, false, null]],
        '/multi/new' => [[['_route' => 'overridden2'], null, null, null, false, false, null]],
        '/multi/hey'

lse, false, null]],
        '/c2/route2' => [[['_route' => 'route2'], 'a.example.com', null, null, false, false, null]],
        '/route4' => [[['_route' => 'route4'], 'a.example.com', null, null, false, false, null]],
        '/c2/route3' => [[['_route' =

 => [[['_route' => 'hey'], null, null, null, true, false, null]],
        '/ababa' => [[['_route' => 'ababa'], null, null, null, false, false, null]],
        '/route1' => [[['_route' => 'route1'], 'a.example.com', null, null, fa


ing Component.
 */

return [
    false, // $matchHost
    [ // $staticRoutes
        '/just_head' => [[['_route' => 'just_head'], null, ['HEAD' => 0], null, false, false, null]],
        '/head_and_get' => [[['_route' => 'head_and_get'], null, ['HEAD' => 0, 'GET' => 1], null, false, false, null]],
        '/get_and_head' => [[['_route' => 'get_and_head'], null, ['GET' => 0, 'HEAD' => 1], null, false, false, null]],
        '/post_and_head' => [[['_route' => 'post_and_head'], null, ['POST' => 0, 'HEAD' => 1]

' => [
            [['_route' => 'put_and_post'], null, ['PUT' => 0, 'POST' => 1], null, false, false, null],
            [['_route' => 'put_and_get_and_head'], null, ['PUT' => 0, 'GET' => 1, 'HEAD' => 2], null, false, false, null],
        ],
    ],
    [

, null, false, false, null]],
        '/put_and_post


by the Symfony Routing Component.
 */

return [
    false, // $matchHost
    [ // $staticRoutes
        '/trailing/simple/no-methods' => [[['_route' => 'simple_trailing_slash_no_methods'], null, null, null, true, false, null]],
        '/trailing/simple/get-method' => [[['_route' => 'simple_trailing_slash_GET_method'], null, ['GET' => 0], null, true, false, null]],
        '/trailing/simple/head-method' => [[['_route' => 'simple_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, true, false, null]],

no_methods'], null, null, null, false, false, null]],
        '/not-trailing/simple/get-method' => [[['_route' => 'simple_not_trailing_slash_GET_method'], null, ['GET' => 0], null, false, false, null]],
        '/not-trailing/simple/head-method' => [[['_ro

       '/trailing/simple/post-method' => [[['_route' => 'simple_trailing_slash_POST_method'], null, ['POST' => 0], null, true, false, null]],
        '/not-trailing/simple/no-methods' => [[['_route' => 'simple_not_trailing_slash_


ge.
 *
 * (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 $colle

tring[]|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->lo

ction,
        private PhpFileLoader $loader,
        private string $path,
        private string $file,
        private ?string $env = null,
    ) {
        $this->collection = $collection;
    }

    /**
     * @param string|s


ctor()
    {
        $route = new Route('/{foo}', ['foo' => 'bar'], ['foo' => '\d+'], ['foo' => 'bar'], '{locale}.example.com');
        $this->assertEquals('/{foo}', $route->getPath(), '__construct() takes a path as its first argument');
        $this->assertEquals(['foo' => 'bar'], $route->getDefaults(), '__construct() takes defaults as its second argument');
        $this->assertEquals(['foo' => '\d+'], $route->getRequirements(), '__construct() takes requirements as its third argument');
        $this->a

);

        $route = new Route('/', [], [], [], '', ['Https'], ['POST', 'put'], 'context.getMethod() == "GET"');
        $this->assertEquals(['https'], $route->getSchemes(), '__construct() takes schemes as its sixth argument and lowercases it');
        $t

ssertEquals('bar', $route->getOption('foo'), '__construct() takes options as its fourth argument');
        $this->assertEquals('{locale}.example.com', $route->getHost(), '__construct() takes a host pattern as its fifth argument'


buted with this source code.
 */

namespace Symfony\Component\Routing\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\CompiledUrlGenerator;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony

(): void
    {
        $this->cacheDir = tempnam(sys_get_temp_dir(), 'sf_router_');
        unlink($this->cacheDir);
        mkdir($this->cacheDir);
    }

    protected function tearDown(): void
    {
        if (is_dir($this->cacheDir)) {
            arr

\Component\Routing\Matcher\UrlMatcherInterface;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Router;

class RouterTest extends TestCase
{
    private string $cacheDir;

    protected function setUp


?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\Tests\Fixtures;

use Symfony\Component\Routing\Loader\AttributeClassLoader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

final class TraceableAttributeClassLoader extends AttributeClassLoader
{
    /

printf('Expected string, got "%s"', get_debug_type($class)));
        }

        $this->foundClasses[] = $class;

        return parent::load($class, $type);
    }

    protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMet

** @var list<string> */
    public array $foundClasses = [];

    public function load(mixed $class, ?string $type = null): RouteCollection
    {
        if (!is_string($class)) {
            throw new \InvalidArgumentException(s


source;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

return function (string $format) {
    $expectedRoutes = new RouteCollection();
    $expectedRoutes->add('imported.en', $route = new Route('/example'));
    $route->setHost('www.example.com');
    $route->setRequirement('_locale', 'en');
    $route->setDefault('_locale', 'en');
    $route->setDefault('_canonical_route', 'imported');
    $route->setDefault('_controller', 'ImportedController::someAction');
    $expect

', 'imported');
    $route->setDefault('_controller', 'ImportedController::someAction');
    $expectedRoutes->add('imported_not_localized.en', $route = new Route('/here'));
    $route->setHost('www.example.com');
    $route->setRequirement('_locale', 'en')

edRoutes->add('imported.nl', $route = new Route('/voorbeeld'));
    $route->setHost('www.example.nl');
    $route->setRequirement('_locale', 'nl');
    $route->setDefault('_locale', 'nl');
    $route->setDefault('_canonical_route


\Resource\FileResource;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

return static function (string $format) {
    $expectedRoutes = new RouteCollection();

    $expectedRoutes->add('route', new Route('/hello'));
    $expectedRoutes->addAlias('alias', 'route');
    $expectedRoutes->addAlias('deprecated', 'route')
        ->setDeprecated('foo/bar', '1.0.0', '');
    $expectedRoutes->addAlias('deprecated-with-custom-message', 'route')
        ->setDeprecated('foo/bar',

dAlias('deep', 'alias');
    $expectedRoutes->addAlias('overrided', 'route');

    $expectedRoutes->addResource(new FileResource(__DIR__."/alias.$format"));
    if ('yaml' === $format) {
        $expectedRoutes->addResource(new FileResource(__DIR__."/overr

'1.0.0', 'foo %alias_id%.');
    $expectedRoutes->ad


micRoutes
        27 => [[['_route' => 'r1'], ['foo'], null, null, false, false, null]],
        38 => [[['_route' => 'r10'], ['foo'], null, null, false, false, null]],
        46 => [[['_route' => 'r100'], ['foo'], null, null, false, false, null]],


?php

/**
 * This file has been auto-generated
 * by the Symfony Routing Component.
 */

return [
    false, // $matchHost
    [ // $staticRoutes
        '/rootprefix/test' => [[['_route' => 'static'], null, null, null, false, false, null]],
        '/with-condition' => [[['_route' => 'with-condition'], null, null, null, false, false, -1]],
    ],
    [ // $regexpList
        0 => '{^(?'
                .'|/rootprefix/([^/]++)(*:27)'
                .'|/with\\-condition/(\\d+)(*:56)'
            .')/?$}sD',

     [null, null, null, null, false, false, 0],
        ],
    ],
    static function ($condition, $context, $request, $params) { // $checkCondition
        switch ($condition) {
            case -1: return ($context->getMethod() == "GET");
            cas

    ],
    [ // $dynamicRoutes
        27 => [[['_route' => 'dynamic'], ['var'], null, null, false, true, null]],
        56 => [
            [['_route' => 'with-condition-dynamic'], ['id'], null, null, false, true, -2],


eturns a route by name');
        $this->assertNull($collection->get('bar'), '->get() returns null if a route does not exist');
    }

    public function testOverriddenRoute()
    {
        $collection = new RouteCollection();
        $collection->add('foo', new Route('/foo'));
        $collection->add('foo', new Route('/foo1'));

        $this->assertEquals('/foo1', $collection->get('foo')->getPath());
    }

    public function testDeepOverriddenRoute()
    {
        $collection = new RouteCollection();

o', new Route('/foo2'));

        $collection1->addCollection($collection2);
        $collection->addCollection($collection1);

        $this->assertEquals('/foo2', $collection1->get('foo')->getPath());
        $this->assertEquals('/foo2', $collection->get

        $collection->add('foo', new Route('/foo'));

        $collection1 = new RouteCollection();
        $collection1->add('foo', new Route('/foo1'));

        $collection2 = new RouteCollection();
        $collection2->add('fo


 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\Tests\Attribute;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\FooController;

class RouteTest extends TestCase
{
    #

ributes(Route::class)[0]->newInstance();

        $this->assertEquals($route->$property, $expectedReturn);
    }

    public static function getValidParameters(): iterable
    {
        return [
            ['simplePath', 'path', '/Blog'],
            ['lo

[DataProvider('getValidParameters')]
    public function testLoadFromAttribute(string $methodName, string $property, mixed $expectedReturn)
    {
        $route = (new \ReflectionMethod(FooController::class, $methodName))->getAtt


 * 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\Tests\Fixtures;

use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
use Symfony\Component\Routing\Matcher\UrlMatcher;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class RedirectableUrlMatcher extends UrlMatcher impl

tableUrlMatcherInterface
{
    public function redirect(string $path, string $route, ?string $scheme = null): array
    {
        return [
            '_controller' => 'Some controller reference...',
            'path' => $path,
            'scheme' => $sc


ymfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

return function (string $format) {
    $expectedRoutes = new RouteCollection();
    $expectedRoutes->add('imported.en', $route = new Route('/example'));
    $route->setHost('www.example.com');
    $route->setRequirement('_locale', 'en');
    $route->setDefault('_locale', 'en');
    $route->setDefault('_canonical_route', 'imported');
    $route->setDefault('_controller', 'Import

    $route->setDefault('_canonical_route', 'imported');
    $route->setDefault('_controller', 'ImportedController::someAction');
    $expectedRoutes->add('imported_not_localized', $route = new Route('/here'));
    $route->setHost('www.example.com');
    $r

edController::someAction');
    $expectedRoutes->add('imported.nl', $route = new Route('/voorbeeld'));
    $route->setHost('www.example.com');
    $route->setRequirement('_locale', 'nl');
    $route->setDefault('_locale', 'nl');


onent\Config\Resource\FileResource;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

return function (string $format) {
    $expectedRoutes = new RouteCollection();
    $expectedRoutes->add('static.en', $route = new Route('/example'));
    $route->setHost('www.example.com');
    $route->setRequirement('_locale', 'en');
    $route->setDefault('_locale', 'en');
    $route->setDefault('_canonical_route', 'static');
    $expectedRoutes->add('static.nl', $route = new Route('/e

  $route->setRequirement('_locale', 'nl');
    $route->setDefault('_locale', 'nl');
    $route->setDefault('_canonical_route', 'static');

    $expectedRoutes->addResource(new FileResource(__DIR__."/route-with-hosts.$format"));

    return $expectedRoutes;

xample'));
    $route->setHost('www.example.nl');