One Hat Cyber Team
Your IP:
216.73.216.30
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
proc
/
self
/
root
/
proc
/
thread-self
/
cwd
/
View File Name :
http-kernel.tar
UriSigner.php 0000644 00000006041 15111167607 0007172 0 ustar 00 <?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\HttpKernel; use Symfony\Component\HttpFoundation\Request; /** * Signs URIs. * * @author Fabien Potencier <fabien@symfony.com> */ class UriSigner { private string $secret; private string $parameter; /** * @param string $secret A secret * @param string $parameter Query string parameter to use */ public function __construct(#[\SensitiveParameter] string $secret, string $parameter = '_hash') { $this->secret = $secret; $this->parameter = $parameter; } /** * Signs a URI. * * The given URI is signed by adding the query string parameter * which value depends on the URI and the secret. */ public function sign(string $uri): string { $url = parse_url($uri); $params = []; if (isset($url['query'])) { parse_str($url['query'], $params); } $uri = $this->buildUrl($url, $params); $params[$this->parameter] = $this->computeHash($uri); return $this->buildUrl($url, $params); } /** * Checks that a URI contains the correct hash. */ public function check(string $uri): bool { $url = parse_url($uri); $params = []; if (isset($url['query'])) { parse_str($url['query'], $params); } if (empty($params[$this->parameter])) { return false; } $hash = $params[$this->parameter]; unset($params[$this->parameter]); return hash_equals($this->computeHash($this->buildUrl($url, $params)), $hash); } public function checkRequest(Request $request): bool { $qs = ($qs = $request->server->get('QUERY_STRING')) ? '?'.$qs : ''; // we cannot use $request->getUri() here as we want to work with the original URI (no query string reordering) return $this->check($request->getSchemeAndHttpHost().$request->getBaseUrl().$request->getPathInfo().$qs); } private function computeHash(string $uri): string { return base64_encode(hash_hmac('sha256', $uri, $this->secret, true)); } private function buildUrl(array $url, array $params = []): string { ksort($params, \SORT_STRING); $url['query'] = http_build_query($params, '', '&'); $scheme = isset($url['scheme']) ? $url['scheme'].'://' : ''; $host = $url['host'] ?? ''; $port = isset($url['port']) ? ':'.$url['port'] : ''; $user = $url['user'] ?? ''; $pass = isset($url['pass']) ? ':'.$url['pass'] : ''; $pass = ($user || $pass) ? "$pass@" : ''; $path = $url['path'] ?? ''; $query = $url['query'] ? '?'.$url['query'] : ''; $fragment = isset($url['fragment']) ? '#'.$url['fragment'] : ''; return $scheme.$user.$pass.$host.$port.$path.$query.$fragment; } } ControllerMetadata/ArgumentMetadata.php 0000644 00000007335 15111167607 0014301 0 ustar 00 <?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\HttpKernel\ControllerMetadata; /** * Responsible for storing metadata of an argument. * * @author Iltar van der Berg <kjarli@gmail.com> */ class ArgumentMetadata { public const IS_INSTANCEOF = 2; private string $name; private ?string $type; private bool $isVariadic; private bool $hasDefaultValue; private mixed $defaultValue; private bool $isNullable; private array $attributes; /** * @param object[] $attributes */ public function __construct(string $name, ?string $type, bool $isVariadic, bool $hasDefaultValue, mixed $defaultValue, bool $isNullable = false, array $attributes = []) { $this->name = $name; $this->type = $type; $this->isVariadic = $isVariadic; $this->hasDefaultValue = $hasDefaultValue; $this->defaultValue = $defaultValue; $this->isNullable = $isNullable || null === $type || ($hasDefaultValue && null === $defaultValue); $this->attributes = $attributes; } /** * Returns the name as given in PHP, $foo would yield "foo". */ public function getName(): string { return $this->name; } /** * Returns the type of the argument. * * The type is the PHP class in 5.5+ and additionally the basic type in PHP 7.0+. */ public function getType(): ?string { return $this->type; } /** * Returns whether the argument is defined as "...$variadic". */ public function isVariadic(): bool { return $this->isVariadic; } /** * Returns whether the argument has a default value. * * Implies whether an argument is optional. */ public function hasDefaultValue(): bool { return $this->hasDefaultValue; } /** * Returns whether the argument accepts null values. */ public function isNullable(): bool { return $this->isNullable; } /** * Returns the default value of the argument. * * @throws \LogicException if no default value is present; {@see self::hasDefaultValue()} */ public function getDefaultValue(): mixed { if (!$this->hasDefaultValue) { throw new \LogicException(sprintf('Argument $%s does not have a default value. Use "%s::hasDefaultValue()" to avoid this exception.', $this->name, __CLASS__)); } return $this->defaultValue; } /** * @param class-string $name * @param self::IS_INSTANCEOF|0 $flags * * @return array<object> */ public function getAttributes(string $name = null, int $flags = 0): array { if (!$name) { return $this->attributes; } return $this->getAttributesOfType($name, $flags); } /** * @template T of object * * @param class-string<T> $name * @param self::IS_INSTANCEOF|0 $flags * * @return array<T> */ public function getAttributesOfType(string $name, int $flags = 0): array { $attributes = []; if ($flags & self::IS_INSTANCEOF) { foreach ($this->attributes as $attribute) { if ($attribute instanceof $name) { $attributes[] = $attribute; } } } else { foreach ($this->attributes as $attribute) { if ($attribute::class === $name) { $attributes[] = $attribute; } } } return $attributes; } } ControllerMetadata/error_log 0000644 00000000662 15111167607 0012256 0 ustar 00 [19-Nov-2025 02:00:52 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php on line 19 ControllerMetadata/ArgumentMetadataFactory.php 0000644 00000003652 15111167607 0015627 0 ustar 00 <?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\HttpKernel\ControllerMetadata; /** * Builds {@see ArgumentMetadata} objects based on the given Controller. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface { public function createArgumentMetadata(string|object|array $controller, \ReflectionFunctionAbstract $reflector = null): array { $arguments = []; $reflector ??= new \ReflectionFunction($controller(...)); foreach ($reflector->getParameters() as $param) { $attributes = []; foreach ($param->getAttributes() as $reflectionAttribute) { if (class_exists($reflectionAttribute->getName())) { $attributes[] = $reflectionAttribute->newInstance(); } } $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $param->isVariadic(), $param->isDefaultValueAvailable(), $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, $param->allowsNull(), $attributes); } return $arguments; } /** * Returns an associated type to the given parameter if available. */ private function getType(\ReflectionParameter $parameter): ?string { if (!$type = $parameter->getType()) { return null; } $name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type; return match (strtolower($name)) { 'self' => $parameter->getDeclaringClass()?->name, 'parent' => get_parent_class($parameter->getDeclaringClass()?->name ?? '') ?: null, default => $name, }; } } ControllerMetadata/ArgumentMetadataFactoryInterface.php 0000644 00000001261 15111167607 0017442 0 ustar 00 <?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\HttpKernel\ControllerMetadata; /** * Builds method argument data. * * @author Iltar van der Berg <kjarli@gmail.com> */ interface ArgumentMetadataFactoryInterface { /** * @param \ReflectionFunctionAbstract|null $reflector * * @return ArgumentMetadata[] */ public function createArgumentMetadata(string|object|array $controller/* , \ReflectionFunctionAbstract $reflector = null */): array; } Controller/ContainerControllerResolver.php 0000644 00000004251 15111167607 0015117 0 ustar 00 <?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\HttpKernel\Controller; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Container; /** * A controller resolver searching for a controller in a psr-11 container when using the "service::method" notation. * * @author Fabien Potencier <fabien@symfony.com> * @author Maxime Steinhausser <maxime.steinhausser@gmail.com> */ class ContainerControllerResolver extends ControllerResolver { protected $container; public function __construct(ContainerInterface $container, LoggerInterface $logger = null) { $this->container = $container; parent::__construct($logger); } protected function instantiateController(string $class): object { $class = ltrim($class, '\\'); if ($this->container->has($class)) { return $this->container->get($class); } try { return parent::instantiateController($class); } catch (\Error $e) { } $this->throwExceptionIfControllerWasRemoved($class, $e); if ($e instanceof \ArgumentCountError) { throw new \InvalidArgumentException(sprintf('Controller "%s" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?', $class), 0, $e); } throw new \InvalidArgumentException(sprintf('Controller "%s" does neither exist as service nor as class.', $class), 0, $e); } private function throwExceptionIfControllerWasRemoved(string $controller, \Throwable $previous): void { if ($this->container instanceof Container && isset($this->container->getRemovedIds()[$controller])) { throw new \InvalidArgumentException(sprintf('Controller "%s" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?', $controller), 0, $previous); } } } Controller/ArgumentResolver/RequestValueResolver.php 0000644 00000002632 15111167607 0017063 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Yields the same instance as the request object passed along. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class RequestValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); return Request::class === $argument->getType() || is_subclass_of($argument->getType(), Request::class); } public function resolve(Request $request, ArgumentMetadata $argument): array { return Request::class === $argument->getType() || is_subclass_of($argument->getType(), Request::class) ? [$request] : []; } } Controller/ArgumentResolver/VariadicValueResolver.php 0000644 00000003367 15111167607 0017163 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Yields a variadic argument's values from the request attributes. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class VariadicValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); return $argument->isVariadic() && $request->attributes->has($argument->getName()); } public function resolve(Request $request, ArgumentMetadata $argument): array { if (!$argument->isVariadic() || !$request->attributes->has($argument->getName())) { return []; } $values = $request->attributes->get($argument->getName()); if (!\is_array($values)) { throw new \InvalidArgumentException(sprintf('The action argument "...$%1$s" is required to be an array, the request attribute "%1$s" contains a type of "%2$s" instead.', $argument->getName(), get_debug_type($values))); } return $values; } } Controller/ArgumentResolver/DefaultValueResolver.php 0000644 00000003120 15111167607 0017010 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Yields the default value defined in the action signature when no value has been given. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class DefaultValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); return $argument->hasDefaultValue() || (null !== $argument->getType() && $argument->isNullable() && !$argument->isVariadic()); } public function resolve(Request $request, ArgumentMetadata $argument): array { if ($argument->hasDefaultValue()) { return [$argument->getDefaultValue()]; } if (null !== $argument->getType() && $argument->isNullable() && !$argument->isVariadic()) { return [null]; } return []; } } Controller/ArgumentResolver/RequestPayloadValueResolver.php 0000644 00000020403 15111167607 0020371 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\MapQueryString; use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Serializer\Exception\NotEncodableValueException; use Symfony\Component\Serializer\Exception\PartialDenormalizationException; use Symfony\Component\Serializer\Exception\UnsupportedFormatException; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\Exception\ValidationFailedException; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Contracts\Translation\TranslatorInterface; /** * @author Konstantin Myakshin <molodchick@gmail.com> * * @final */ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscriberInterface { /** * @see \Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT * @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS */ private const CONTEXT_DENORMALIZE = [ 'disable_type_enforcement' => true, 'collect_denormalization_errors' => true, ]; /** * @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS */ private const CONTEXT_DESERIALIZE = [ 'collect_denormalization_errors' => true, ]; public function __construct( private readonly SerializerInterface&DenormalizerInterface $serializer, private readonly ?ValidatorInterface $validator = null, private readonly ?TranslatorInterface $translator = null, ) { } public function resolve(Request $request, ArgumentMetadata $argument): iterable { $attribute = $argument->getAttributesOfType(MapQueryString::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? $argument->getAttributesOfType(MapRequestPayload::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? null; if (!$attribute) { return []; } if ($argument->isVariadic()) { throw new \LogicException(sprintf('Mapping variadic argument "$%s" is not supported.', $argument->getName())); } $attribute->metadata = $argument; return [$attribute]; } public function onKernelControllerArguments(ControllerArgumentsEvent $event): void { $arguments = $event->getArguments(); foreach ($arguments as $i => $argument) { if ($argument instanceof MapQueryString) { $payloadMapper = 'mapQueryString'; $validationFailedCode = Response::HTTP_NOT_FOUND; } elseif ($argument instanceof MapRequestPayload) { $payloadMapper = 'mapRequestPayload'; $validationFailedCode = Response::HTTP_UNPROCESSABLE_ENTITY; } else { continue; } $request = $event->getRequest(); if (!$type = $argument->metadata->getType()) { throw new \LogicException(sprintf('Could not resolve the "$%s" controller argument: argument should be typed.', $argument->metadata->getName())); } if ($this->validator) { $violations = new ConstraintViolationList(); try { $payload = $this->$payloadMapper($request, $type, $argument); } catch (PartialDenormalizationException $e) { $trans = $this->translator ? $this->translator->trans(...) : fn ($m, $p) => strtr($m, $p); foreach ($e->getErrors() as $error) { $parameters = ['{{ type }}' => implode('|', $error->getExpectedTypes())]; if ($error->canUseMessageForUser()) { $parameters['hint'] = $error->getMessage(); } $template = 'This value should be of type {{ type }}.'; $message = $trans($template, $parameters, 'validators'); $violations->add(new ConstraintViolation($message, $template, $parameters, null, $error->getPath(), null)); } $payload = $e->getData(); } if (null !== $payload) { $violations->addAll($this->validator->validate($payload, null, $argument->validationGroups ?? null)); } if (\count($violations)) { throw new HttpException($validationFailedCode, implode("\n", array_map(static fn ($e) => $e->getMessage(), iterator_to_array($violations))), new ValidationFailedException($payload, $violations)); } } else { try { $payload = $this->$payloadMapper($request, $type, $argument); } catch (PartialDenormalizationException $e) { throw new HttpException($validationFailedCode, implode("\n", array_map(static fn ($e) => $e->getMessage(), $e->getErrors())), $e); } } if (null === $payload) { $payload = match (true) { $argument->metadata->hasDefaultValue() => $argument->metadata->getDefaultValue(), $argument->metadata->isNullable() => null, default => throw new HttpException($validationFailedCode) }; } $arguments[$i] = $payload; } $event->setArguments($arguments); } public static function getSubscribedEvents(): array { return [ KernelEvents::CONTROLLER_ARGUMENTS => 'onKernelControllerArguments', ]; } private function mapQueryString(Request $request, string $type, MapQueryString $attribute): ?object { if (!$data = $request->query->all()) { return null; } return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE); } private function mapRequestPayload(Request $request, string $type, MapRequestPayload $attribute): ?object { if (null === $format = $request->getContentTypeFormat()) { throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, 'Unsupported format.'); } if ($attribute->acceptFormat && !\in_array($format, (array) $attribute->acceptFormat, true)) { throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format, expects "%s", but "%s" given.', implode('", "', (array) $attribute->acceptFormat), $format)); } if ($data = $request->request->all()) { return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE); } if ('' === $data = $request->getContent()) { return null; } if ('form' === $format) { throw new HttpException(Response::HTTP_BAD_REQUEST, 'Request payload contains invalid "form" data.'); } try { return $this->serializer->deserialize($data, $type, $format, self::CONTEXT_DESERIALIZE + $attribute->serializationContext); } catch (UnsupportedFormatException $e) { throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format: "%s".', $format), $e); } catch (NotEncodableValueException $e) { throw new HttpException(Response::HTTP_BAD_REQUEST, sprintf('Request payload contains invalid "%s" data.', $format), $e); } } } Controller/ArgumentResolver/NotTaggedControllerValueResolver.php 0000644 00000006334 15111167607 0021356 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Psr\Container\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Provides an intuitive error message when controller fails because it is not registered as a service. * * @author Simeon Kolev <simeon.kolev9@gmail.com> */ final class NotTaggedControllerValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { private ContainerInterface $container; public function __construct(ContainerInterface $container) { $this->container = $container; } /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); $controller = $request->attributes->get('_controller'); if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) { $controller = $controller[0].'::'.$controller[1]; } elseif (!\is_string($controller) || '' === $controller) { return false; } if ('\\' === $controller[0]) { $controller = ltrim($controller, '\\'); } if (!$this->container->has($controller) && false !== $i = strrpos($controller, ':')) { $controller = substr($controller, 0, $i).strtolower(substr($controller, $i)); } return false === $this->container->has($controller); } public function resolve(Request $request, ArgumentMetadata $argument): array { $controller = $request->attributes->get('_controller'); if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) { $controller = $controller[0].'::'.$controller[1]; } elseif (!\is_string($controller) || '' === $controller) { return []; } if ('\\' === $controller[0]) { $controller = ltrim($controller, '\\'); } if (!$this->container->has($controller)) { $controller = (false !== $i = strrpos($controller, ':')) ? substr($controller, 0, $i).strtolower(substr($controller, $i)) : $controller.'::__invoke'; } if ($this->container->has($controller)) { return []; } $what = sprintf('argument $%s of "%s()"', $argument->getName(), $controller); $message = sprintf('Could not resolve %s, maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?', $what); throw new RuntimeException($message); } } Controller/ArgumentResolver/ServiceValueResolver.php 0000644 00000006776 15111167610 0017042 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Psr\Container\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Yields a service keyed by _controller and argument name. * * @author Nicolas Grekas <p@tchwork.com> */ final class ServiceValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { private ContainerInterface $container; public function __construct(ContainerInterface $container) { $this->container = $container; } /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); $controller = $request->attributes->get('_controller'); if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) { $controller = $controller[0].'::'.$controller[1]; } elseif (!\is_string($controller) || '' === $controller) { return false; } if ('\\' === $controller[0]) { $controller = ltrim($controller, '\\'); } if (!$this->container->has($controller) && false !== $i = strrpos($controller, ':')) { $controller = substr($controller, 0, $i).strtolower(substr($controller, $i)); } return $this->container->has($controller) && $this->container->get($controller)->has($argument->getName()); } public function resolve(Request $request, ArgumentMetadata $argument): array { $controller = $request->attributes->get('_controller'); if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) { $controller = $controller[0].'::'.$controller[1]; } elseif (!\is_string($controller) || '' === $controller) { return []; } if ('\\' === $controller[0]) { $controller = ltrim($controller, '\\'); } if (!$this->container->has($controller) && false !== $i = strrpos($controller, ':')) { $controller = substr($controller, 0, $i).strtolower(substr($controller, $i)); } if (!$this->container->has($controller) || !$this->container->get($controller)->has($argument->getName())) { return []; } try { return [$this->container->get($controller)->get($argument->getName())]; } catch (RuntimeException $e) { $what = sprintf('argument $%s of "%s()"', $argument->getName(), $controller); $message = preg_replace('/service "\.service_locator\.[^"]++"/', $what, $e->getMessage()); if ($e->getMessage() === $message) { $message = sprintf('Cannot resolve %s: %s', $what, $message); } $r = new \ReflectionProperty($e, 'message'); $r->setValue($e, $message); throw $e; } } } Controller/ArgumentResolver/SessionValueResolver.php 0000644 00000003476 15111167610 0017057 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Yields the Session. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class SessionValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); if (!$request->hasSession()) { return false; } $type = $argument->getType(); if (SessionInterface::class !== $type && !is_subclass_of($type, SessionInterface::class)) { return false; } return $request->getSession() instanceof $type; } public function resolve(Request $request, ArgumentMetadata $argument): array { if (!$request->hasSession()) { return []; } $type = $argument->getType(); if (SessionInterface::class !== $type && !is_subclass_of($type, SessionInterface::class)) { return []; } return $request->getSession() instanceof $type ? [$request->getSession()] : []; } } Controller/ArgumentResolver/RequestAttributeValueResolver.php 0000644 00000002651 15111167610 0020742 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Yields a non-variadic argument's value from the request attributes. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class RequestAttributeValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); return !$argument->isVariadic() && $request->attributes->has($argument->getName()); } public function resolve(Request $request, ArgumentMetadata $argument): array { return !$argument->isVariadic() && $request->attributes->has($argument->getName()) ? [$request->attributes->get($argument->getName())] : []; } } Controller/ArgumentResolver/BackedEnumValueResolver.php 0000644 00000006715 15111167611 0017432 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Attempt to resolve backed enum cases from request attributes, for a route path parameter, * leading to a 404 Not Found if the attribute value isn't a valid backing value for the enum type. * * @author Maxime Steinhausser <maxime.steinhausser@gmail.com> * * @final since Symfony 6.2 */ class BackedEnumValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); if (!is_subclass_of($argument->getType(), \BackedEnum::class)) { return false; } if ($argument->isVariadic()) { // only target route path parameters, which cannot be variadic. return false; } // do not support if no value can be resolved at all // letting the \Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver be used // or \Symfony\Component\HttpKernel\Controller\ArgumentResolver fail with a meaningful error. return $request->attributes->has($argument->getName()); } public function resolve(Request $request, ArgumentMetadata $argument): iterable { if (!is_subclass_of($argument->getType(), \BackedEnum::class)) { return []; } if ($argument->isVariadic()) { // only target route path parameters, which cannot be variadic. return []; } // do not support if no value can be resolved at all // letting the \Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver be used // or \Symfony\Component\HttpKernel\Controller\ArgumentResolver fail with a meaningful error. if (!$request->attributes->has($argument->getName())) { return []; } $value = $request->attributes->get($argument->getName()); if (null === $value) { return [null]; } if ($value instanceof \BackedEnum) { return [$value]; } if (!\is_int($value) && !\is_string($value)) { throw new \LogicException(sprintf('Could not resolve the "%s $%s" controller argument: expecting an int or string, got "%s".', $argument->getType(), $argument->getName(), get_debug_type($value))); } /** @var class-string<\BackedEnum> $enumType */ $enumType = $argument->getType(); try { return [$enumType::from($value)]; } catch (\ValueError $e) { throw new NotFoundHttpException(sprintf('Could not resolve the "%s $%s" controller argument: ', $argument->getType(), $argument->getName()).$e->getMessage(), $e); } } } Controller/ArgumentResolver/UidValueResolver.php 0000644 00000003743 15111167611 0016153 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Uid\AbstractUid; final class UidValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); return !$argument->isVariadic() && \is_string($request->attributes->get($argument->getName())) && null !== $argument->getType() && is_subclass_of($argument->getType(), AbstractUid::class, true); } public function resolve(Request $request, ArgumentMetadata $argument): array { if ($argument->isVariadic() || !\is_string($value = $request->attributes->get($argument->getName())) || null === ($uidClass = $argument->getType()) || !is_subclass_of($argument->getType(), AbstractUid::class, true) ) { return []; } /* @var class-string<AbstractUid> $uidClass */ try { return [$uidClass::fromString($value)]; } catch (\InvalidArgumentException $e) { throw new NotFoundHttpException(sprintf('The uid for the "%s" parameter is invalid.', $argument->getName()), $e); } } } Controller/ArgumentResolver/TraceableValueResolver.php 0000644 00000003731 15111167611 0017311 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\Stopwatch\Stopwatch; /** * Provides timing information via the stopwatch. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class TraceableValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { private ArgumentValueResolverInterface|ValueResolverInterface $inner; private Stopwatch $stopwatch; public function __construct(ArgumentValueResolverInterface|ValueResolverInterface $inner, Stopwatch $stopwatch) { $this->inner = $inner; $this->stopwatch = $stopwatch; } /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { if ($this->inner instanceof ValueResolverInterface) { return true; } $method = $this->inner::class.'::'.__FUNCTION__; $this->stopwatch->start($method, 'controller.argument_value_resolver'); $return = $this->inner->supports($request, $argument); $this->stopwatch->stop($method); return $return; } public function resolve(Request $request, ArgumentMetadata $argument): iterable { $method = $this->inner::class.'::'.__FUNCTION__; $this->stopwatch->start($method, 'controller.argument_value_resolver'); yield from $this->inner->resolve($request, $argument); $this->stopwatch->stop($method); } } Controller/ArgumentResolver/QueryParameterValueResolver.php 0000644 00000007066 15111167611 0020402 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\MapQueryParameter; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * @author Ruud Kamphuis <ruud@ticketswap.com> * @author Nicolas Grekas <p@tchwork.com> */ final class QueryParameterValueResolver implements ValueResolverInterface { public function resolve(Request $request, ArgumentMetadata $argument): array { if (!$attribute = $argument->getAttributesOfType(MapQueryParameter::class)[0] ?? null) { return []; } $name = $attribute->name ?? $argument->getName(); if (!$request->query->has($name)) { if ($argument->isNullable() || $argument->hasDefaultValue()) { return []; } throw new NotFoundHttpException(sprintf('Missing query parameter "%s".', $name)); } $value = $request->query->all()[$name]; if (null === $attribute->filter && 'array' === $argument->getType()) { if (!$argument->isVariadic()) { return [(array) $value]; } $filtered = array_values(array_filter((array) $value, \is_array(...))); if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) { throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name)); } return $filtered; } $options = [ 'flags' => $attribute->flags | \FILTER_NULL_ON_FAILURE, 'options' => $attribute->options, ]; if ('array' === $argument->getType() || $argument->isVariadic()) { $value = (array) $value; $options['flags'] |= \FILTER_REQUIRE_ARRAY; } else { $options['flags'] |= \FILTER_REQUIRE_SCALAR; } $filter = match ($argument->getType()) { 'array' => \FILTER_DEFAULT, 'string' => \FILTER_DEFAULT, 'int' => \FILTER_VALIDATE_INT, 'float' => \FILTER_VALIDATE_FLOAT, 'bool' => \FILTER_VALIDATE_BOOL, default => throw new \LogicException(sprintf('#[MapQueryParameter] cannot be used on controller argument "%s$%s" of type "%s"; one of array, string, int, float or bool should be used.', $argument->isVariadic() ? '...' : '', $argument->getName(), $argument->getType() ?? 'mixed')) }; $value = filter_var($value, $attribute->filter ?? $filter, $options); if (null === $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) { throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name)); } if (!\is_array($value)) { return [$value]; } $filtered = array_filter($value, static fn ($v) => null !== $v); if ($argument->isVariadic()) { $filtered = array_values($filtered); } if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) { throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name)); } return $argument->isVariadic() ? $filtered : [$filtered]; } } Controller/ArgumentResolver/DateTimeValueResolver.php 0000644 00000006521 15111167611 0017123 0 ustar 00 <?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\HttpKernel\Controller\ArgumentResolver; use Psr\Clock\ClockInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\MapDateTime; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Convert DateTime instances from request attribute variable. * * @author Benjamin Eberlei <kontakt@beberlei.de> * @author Tim Goudriaan <tim@codedmonkey.com> */ final class DateTimeValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface { public function __construct( private readonly ?ClockInterface $clock = null, ) { } /** * @deprecated since Symfony 6.2, use resolve() instead */ public function supports(Request $request, ArgumentMetadata $argument): bool { @trigger_deprecation('symfony/http-kernel', '6.2', 'The "%s()" method is deprecated, use "resolve()" instead.', __METHOD__); return is_a($argument->getType(), \DateTimeInterface::class, true) && $request->attributes->has($argument->getName()); } public function resolve(Request $request, ArgumentMetadata $argument): array { if (!is_a($argument->getType(), \DateTimeInterface::class, true) || !$request->attributes->has($argument->getName())) { return []; } $value = $request->attributes->get($argument->getName()); $class = \DateTimeInterface::class === $argument->getType() ? \DateTimeImmutable::class : $argument->getType(); if (!$value) { if ($argument->isNullable()) { return [null]; } if (!$this->clock) { return [new $class()]; } $value = $this->clock->now(); } if ($value instanceof \DateTimeInterface) { return [$value instanceof $class ? $value : $class::createFromInterface($value)]; } $format = null; if ($attributes = $argument->getAttributes(MapDateTime::class, ArgumentMetadata::IS_INSTANCEOF)) { $attribute = $attributes[0]; $format = $attribute->format; } if (null !== $format) { $date = $class::createFromFormat($format, $value, $this->clock?->now()->getTimeZone()); if (($class::getLastErrors() ?: ['warning_count' => 0])['warning_count']) { $date = false; } } else { if (false !== filter_var($value, \FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { $value = '@'.$value; } try { $date = new $class($value, $this->clock?->now()->getTimeZone()); } catch (\Exception) { $date = false; } } if (!$date) { throw new NotFoundHttpException(sprintf('Invalid date given for parameter "%s".', $argument->getName())); } return [$date]; } } Controller/ControllerResolverInterface.php 0000644 00000002534 15111167611 0015072 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; /** * A ControllerResolverInterface implementation knows how to determine the * controller to execute based on a Request object. * * A Controller can be any valid PHP callable. * * @author Fabien Potencier <fabien@symfony.com> */ interface ControllerResolverInterface { /** * Returns the Controller instance associated with a Request. * * As several resolvers can exist for a single application, a resolver must * return false when it is not able to determine the controller. * * The resolver must only throw an exception when it should be able to load a * controller but cannot because of some errors made by the developer. * * @return callable|false A PHP callable representing the Controller, * or false if this resolver is not able to determine the controller * * @throws \LogicException If a controller was found based on the request but it is not callable */ public function getController(Request $request): callable|false; } Controller/ArgumentResolverInterface.php 0000644 00000001614 15111167611 0014527 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; /** * An ArgumentResolverInterface instance knows how to determine the * arguments for a specific action. * * @author Fabien Potencier <fabien@symfony.com> */ interface ArgumentResolverInterface { /** * Returns the arguments to pass to the controller. * * @param \ReflectionFunctionAbstract|null $reflector * * @throws \RuntimeException When no value could be provided for a required argument */ public function getArguments(Request $request, callable $controller/* , \ReflectionFunctionAbstract $reflector = null */): array; } Controller/ErrorController.php 0000644 00000004043 15111167611 0012536 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Renders error or exception pages from a given FlattenException. * * @author Yonel Ceruto <yonelceruto@gmail.com> * @author Matthias Pigulla <mp@webfactory.de> */ class ErrorController { private HttpKernelInterface $kernel; private string|object|array|null $controller; private ErrorRendererInterface $errorRenderer; public function __construct(HttpKernelInterface $kernel, string|object|array|null $controller, ErrorRendererInterface $errorRenderer) { $this->kernel = $kernel; $this->controller = $controller; $this->errorRenderer = $errorRenderer; } public function __invoke(\Throwable $exception): Response { $exception = $this->errorRenderer->render($exception); return new Response($exception->getAsString(), $exception->getStatusCode(), $exception->getHeaders()); } public function preview(Request $request, int $code): Response { /* * This Request mimics the parameters set by * \Symfony\Component\HttpKernel\EventListener\ErrorListener::duplicateRequest, with * the additional "showException" flag. */ $subRequest = $request->duplicate(null, null, [ '_controller' => $this->controller, 'exception' => new HttpException($code, 'This is a sample exception.'), 'logger' => null, 'showException' => false, ]); return $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST); } } Controller/ControllerResolver.php 0000644 00000015156 15111167611 0013255 0 ustar 00 <?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\HttpKernel\Controller; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; /** * This implementation uses the '_controller' request attribute to determine * the controller to execute. * * @author Fabien Potencier <fabien@symfony.com> * @author Tobias Schultze <http://tobion.de> */ class ControllerResolver implements ControllerResolverInterface { private ?LoggerInterface $logger; public function __construct(LoggerInterface $logger = null) { $this->logger = $logger; } public function getController(Request $request): callable|false { if (!$controller = $request->attributes->get('_controller')) { $this->logger?->warning('Unable to look for the controller as the "_controller" parameter is missing.'); return false; } if (\is_array($controller)) { if (isset($controller[0]) && \is_string($controller[0]) && isset($controller[1])) { try { $controller[0] = $this->instantiateController($controller[0]); } catch (\Error|\LogicException $e) { if (\is_callable($controller)) { return $controller; } throw $e; } } if (!\is_callable($controller)) { throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller)); } return $controller; } if (\is_object($controller)) { if (!\is_callable($controller)) { throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller)); } return $controller; } if (\function_exists($controller)) { return $controller; } try { $callable = $this->createController($controller); } catch (\InvalidArgumentException $e) { throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$e->getMessage(), 0, $e); } if (!\is_callable($callable)) { throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($callable)); } return $callable; } /** * Returns a callable for the given controller. * * @throws \InvalidArgumentException When the controller cannot be created */ protected function createController(string $controller): callable { if (!str_contains($controller, '::')) { $controller = $this->instantiateController($controller); if (!\is_callable($controller)) { throw new \InvalidArgumentException($this->getControllerError($controller)); } return $controller; } [$class, $method] = explode('::', $controller, 2); try { $controller = [$this->instantiateController($class), $method]; } catch (\Error|\LogicException $e) { try { if ((new \ReflectionMethod($class, $method))->isStatic()) { return $class.'::'.$method; } } catch (\ReflectionException) { throw $e; } throw $e; } if (!\is_callable($controller)) { throw new \InvalidArgumentException($this->getControllerError($controller)); } return $controller; } /** * Returns an instantiated controller. */ protected function instantiateController(string $class): object { return new $class(); } private function getControllerError(mixed $callable): string { if (\is_string($callable)) { if (str_contains($callable, '::')) { $callable = explode('::', $callable, 2); } else { return sprintf('Function "%s" does not exist.', $callable); } } if (\is_object($callable)) { $availableMethods = $this->getClassMethodsWithoutMagicMethods($callable); $alternativeMsg = $availableMethods ? sprintf(' or use one of the available methods: "%s"', implode('", "', $availableMethods)) : ''; return sprintf('Controller class "%s" cannot be called without a method name. You need to implement "__invoke"%s.', get_debug_type($callable), $alternativeMsg); } if (!\is_array($callable)) { return sprintf('Invalid type for controller given, expected string, array or object, got "%s".', get_debug_type($callable)); } if (!isset($callable[0]) || !isset($callable[1]) || 2 !== \count($callable)) { return 'Invalid array callable, expected [controller, method].'; } [$controller, $method] = $callable; if (\is_string($controller) && !class_exists($controller)) { return sprintf('Class "%s" does not exist.', $controller); } $className = \is_object($controller) ? get_debug_type($controller) : $controller; if (method_exists($controller, $method)) { return sprintf('Method "%s" on class "%s" should be public and non-abstract.', $method, $className); } $collection = $this->getClassMethodsWithoutMagicMethods($controller); $alternatives = []; foreach ($collection as $item) { $lev = levenshtein($method, $item); if ($lev <= \strlen($method) / 3 || str_contains($item, $method)) { $alternatives[] = $item; } } asort($alternatives); $message = sprintf('Expected method "%s" on class "%s"', $method, $className); if (\count($alternatives) > 0) { $message .= sprintf(', did you mean "%s"?', implode('", "', $alternatives)); } else { $message .= sprintf('. Available methods: "%s".', implode('", "', $collection)); } return $message; } private function getClassMethodsWithoutMagicMethods($classOrObject): array { $methods = get_class_methods($classOrObject); return array_filter($methods, fn (string $method) => 0 !== strncmp($method, '__', 2)); } } Controller/ArgumentResolver.php 0000644 00000014241 15111167611 0012706 0 ustar 00 <?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\HttpKernel\Controller; use Psr\Container\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestValueResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\SessionValueResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\TraceableValueResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\VariadicValueResolver; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface; use Symfony\Component\HttpKernel\Exception\ResolverNotFoundException; use Symfony\Contracts\Service\ServiceProviderInterface; /** * Responsible for resolving the arguments passed to an action. * * @author Iltar van der Berg <kjarli@gmail.com> */ final class ArgumentResolver implements ArgumentResolverInterface { private ArgumentMetadataFactoryInterface $argumentMetadataFactory; private iterable $argumentValueResolvers; private ?ContainerInterface $namedResolvers; /** * @param iterable<mixed, ArgumentValueResolverInterface|ValueResolverInterface> $argumentValueResolvers */ public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [], ContainerInterface $namedResolvers = null) { $this->argumentMetadataFactory = $argumentMetadataFactory ?? new ArgumentMetadataFactory(); $this->argumentValueResolvers = $argumentValueResolvers ?: self::getDefaultArgumentValueResolvers(); $this->namedResolvers = $namedResolvers; } public function getArguments(Request $request, callable $controller, \ReflectionFunctionAbstract $reflector = null): array { $arguments = []; foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller, $reflector) as $metadata) { $argumentValueResolvers = $this->argumentValueResolvers; $disabledResolvers = []; if ($this->namedResolvers && $attributes = $metadata->getAttributesOfType(ValueResolver::class, $metadata::IS_INSTANCEOF)) { $resolverName = null; foreach ($attributes as $attribute) { if ($attribute->disabled) { $disabledResolvers[$attribute->resolver] = true; } elseif ($resolverName) { throw new \LogicException(sprintf('You can only pin one resolver per argument, but argument "$%s" of "%s()" has more.', $metadata->getName(), $this->getPrettyName($controller))); } else { $resolverName = $attribute->resolver; } } if ($resolverName) { if (!$this->namedResolvers->has($resolverName)) { throw new ResolverNotFoundException($resolverName, $this->namedResolvers instanceof ServiceProviderInterface ? array_keys($this->namedResolvers->getProvidedServices()) : []); } $argumentValueResolvers = [ $this->namedResolvers->get($resolverName), new DefaultValueResolver(), ]; } } foreach ($argumentValueResolvers as $name => $resolver) { if ((!$resolver instanceof ValueResolverInterface || $resolver instanceof TraceableValueResolver) && !$resolver->supports($request, $metadata)) { continue; } if (isset($disabledResolvers[\is_int($name) ? $resolver::class : $name])) { continue; } $count = 0; foreach ($resolver->resolve($request, $metadata) as $argument) { ++$count; $arguments[] = $argument; } if (1 < $count && !$metadata->isVariadic()) { throw new \InvalidArgumentException(sprintf('"%s::resolve()" must yield at most one value for non-variadic arguments.', get_debug_type($resolver))); } if ($count) { // continue to the next controller argument continue 2; } if (!$resolver instanceof ValueResolverInterface) { throw new \InvalidArgumentException(sprintf('"%s::resolve()" must yield at least one value.', get_debug_type($resolver))); } } throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or there is a non-optional argument after this one.', $this->getPrettyName($controller), $metadata->getName())); } return $arguments; } /** * @return iterable<int, ArgumentValueResolverInterface> */ public static function getDefaultArgumentValueResolvers(): iterable { return [ new RequestAttributeValueResolver(), new RequestValueResolver(), new SessionValueResolver(), new DefaultValueResolver(), new VariadicValueResolver(), ]; } private function getPrettyName($controller): string { if (\is_array($controller)) { if (\is_object($controller[0])) { $controller[0] = get_debug_type($controller[0]); } return $controller[0].'::'.$controller[1]; } if (\is_object($controller)) { return get_debug_type($controller); } return $controller; } } Controller/ArgumentValueResolverInterface.php 0000644 00000001734 15111167611 0015527 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Responsible for resolving the value of an argument based on its metadata. * * @author Iltar van der Berg <kjarli@gmail.com> * * @deprecated since Symfony 6.2, implement ValueResolverInterface instead */ interface ArgumentValueResolverInterface { /** * Whether this resolver can resolve the value for the given ArgumentMetadata. */ public function supports(Request $request, ArgumentMetadata $argument): bool; /** * Returns the possible value(s). */ public function resolve(Request $request, ArgumentMetadata $argument): iterable; } Controller/TraceableArgumentResolver.php 0000644 00000002401 15111167611 0014504 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Stopwatch\Stopwatch; /** * @author Fabien Potencier <fabien@symfony.com> */ class TraceableArgumentResolver implements ArgumentResolverInterface { private ArgumentResolverInterface $resolver; private Stopwatch $stopwatch; public function __construct(ArgumentResolverInterface $resolver, Stopwatch $stopwatch) { $this->resolver = $resolver; $this->stopwatch = $stopwatch; } /** * @param \ReflectionFunctionAbstract|null $reflector */ public function getArguments(Request $request, callable $controller/* , \ReflectionFunctionAbstract $reflector = null */): array { $reflector = 2 < \func_num_args() ? func_get_arg(2) : null; $e = $this->stopwatch->start('controller.get_arguments'); try { return $this->resolver->getArguments($request, $controller, $reflector); } finally { $e->stop(); } } } Controller/error_log 0000644 00000003117 15111167611 0010606 0 ustar 00 [20-Nov-2025 06:14:12 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/TraceableArgumentResolver.php:20 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/TraceableArgumentResolver.php on line 20 [20-Nov-2025 06:15:12 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Controller\ControllerResolverInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/ControllerResolver.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/ControllerResolver.php on line 24 [20-Nov-2025 06:23:27 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Controller\ControllerResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/ContainerControllerResolver.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/ContainerControllerResolver.php on line 24 [20-Nov-2025 06:24:32 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Controller\ControllerResolverInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php:20 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php on line 20 Controller/ControllerReference.php 0000644 00000002432 15111167611 0013343 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface; /** * Acts as a marker and a data holder for a Controller. * * Some methods in Symfony accept both a URI (as a string) or a controller as * an argument. In the latter case, instead of passing an array representing * the controller, you can use an instance of this class. * * @author Fabien Potencier <fabien@symfony.com> * * @see FragmentRendererInterface */ class ControllerReference { public $controller; public $attributes = []; public $query = []; /** * @param string $controller The controller name * @param array $attributes An array of parameters to add to the Request attributes * @param array $query An array of parameters to add to the Request query string */ public function __construct(string $controller, array $attributes = [], array $query = []) { $this->controller = $controller; $this->attributes = $attributes; $this->query = $query; } } Controller/ValueResolverInterface.php 0000644 00000001311 15111167611 0014013 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; /** * Responsible for resolving the value of an argument based on its metadata. * * @author Nicolas Grekas <p@tchwork.com> */ interface ValueResolverInterface { /** * Returns the possible value(s). */ public function resolve(Request $request, ArgumentMetadata $argument): iterable; } Controller/TraceableControllerResolver.php 0000644 00000002041 15111167611 0015045 0 ustar 00 <?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\HttpKernel\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Stopwatch\Stopwatch; /** * @author Fabien Potencier <fabien@symfony.com> */ class TraceableControllerResolver implements ControllerResolverInterface { private ControllerResolverInterface $resolver; private Stopwatch $stopwatch; public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch) { $this->resolver = $resolver; $this->stopwatch = $stopwatch; } public function getController(Request $request): callable|false { $e = $this->stopwatch->start('controller.get_callable'); try { return $this->resolver->getController($request); } finally { $e->stop(); } } } Bundle/AbstractBundle.php 0000644 00000003610 15111167611 0011363 0 ustar 00 <?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\HttpKernel\Bundle; use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ConfigurableExtensionInterface; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; /** * A Bundle that provides configuration hooks. * * @author Yonel Ceruto <yonelceruto@gmail.com> */ abstract class AbstractBundle extends Bundle implements ConfigurableExtensionInterface { protected string $extensionAlias = ''; public function configure(DefinitionConfigurator $definition): void { } public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void { } public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void { } public function getContainerExtension(): ?ExtensionInterface { if ('' === $this->extensionAlias) { $this->extensionAlias = Container::underscore(preg_replace('/Bundle$/', '', $this->getName())); } return $this->extension ??= new BundleExtension($this, $this->extensionAlias); } public function getPath(): string { if (null === $this->path) { $reflected = new \ReflectionObject($this); // assume the modern directory structure by default $this->path = \dirname($reflected->getFileName(), 2); } return $this->path; } } Bundle/BundleExtension.php 0000644 00000004262 15111167611 0011600 0 ustar 00 <?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\HttpKernel\Bundle; use Symfony\Component\Config\Definition\Configuration; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ConfigurableExtensionInterface; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Extension\ExtensionTrait; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; /** * @author Yonel Ceruto <yonelceruto@gmail.com> * * @internal */ class BundleExtension extends Extension implements PrependExtensionInterface { use ExtensionTrait; public function __construct( private ConfigurableExtensionInterface $subject, private string $alias, ) { } public function getConfiguration(array $config, ContainerBuilder $container): ?ConfigurationInterface { return new Configuration($this->subject, $container, $this->getAlias()); } public function getAlias(): string { return $this->alias; } public function prepend(ContainerBuilder $container): void { $callback = function (ContainerConfigurator $configurator) use ($container) { $this->subject->prependExtension($configurator, $container); }; $this->executeConfiguratorCallback($container, $callback, $this->subject); } public function load(array $configs, ContainerBuilder $container): void { $config = $this->processConfiguration($this->getConfiguration([], $container), $configs); $callback = function (ContainerConfigurator $configurator) use ($config, $container) { $this->subject->loadExtension($config, $configurator, $container); }; $this->executeConfiguratorCallback($container, $callback, $this->subject); } } Bundle/error_log 0000644 00000003171 15111167611 0007674 0 ustar 00 [19-Nov-2025 05:16:01 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Bundle\Bundle" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/AbstractBundle.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/AbstractBundle.php on line 26 [19-Nov-2025 12:09:14 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Bundle\Bundle" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/AbstractBundle.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/AbstractBundle.php on line 26 [19-Nov-2025 12:09:59 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\DependencyInjection\Extension\Extension" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/BundleExtension.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/BundleExtension.php on line 28 [19-Nov-2025 12:12:06 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\ContainerAwareInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/BundleInterface.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/BundleInterface.php on line 23 [20-Nov-2025 05:08:21 UTC] PHP Fatal error: Trait "Symfony\Component\DependencyInjection\ContainerAwareTrait" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Bundle/Bundle.php on line 25 Bundle/BundleInterface.php 0000644 00000003021 15111167611 0011514 0 ustar 00 <?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\HttpKernel\Bundle; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; /** * BundleInterface. * * @author Fabien Potencier <fabien@symfony.com> */ interface BundleInterface extends ContainerAwareInterface { /** * Boots the Bundle. * * @return void */ public function boot(); /** * Shutdowns the Bundle. * * @return void */ public function shutdown(); /** * Builds the bundle. * * It is only ever called once when the cache is empty. * * @return void */ public function build(ContainerBuilder $container); /** * Returns the container extension that should be implicitly loaded. */ public function getContainerExtension(): ?ExtensionInterface; /** * Returns the bundle name (the class short name). */ public function getName(): string; /** * Gets the Bundle namespace. */ public function getNamespace(): string; /** * Gets the Bundle directory path. * * The path should always be returned as a Unix path (with /). */ public function getPath(): string; } Bundle/Bundle.php 0000644 00000010211 15111167611 0007672 0 ustar 00 <?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\HttpKernel\Bundle; use Symfony\Component\Console\Application; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; /** * An implementation of BundleInterface that adds a few conventions for DependencyInjection extensions. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class Bundle implements BundleInterface { use ContainerAwareTrait; protected $name; protected $extension; protected $path; private string $namespace; /** * @return void */ public function boot() { } /** * @return void */ public function shutdown() { } /** * This method can be overridden to register compilation passes, * other extensions, ... * * @return void */ public function build(ContainerBuilder $container) { } /** * Returns the bundle's container extension. * * @throws \LogicException */ public function getContainerExtension(): ?ExtensionInterface { if (null === $this->extension) { $extension = $this->createContainerExtension(); if (null !== $extension) { if (!$extension instanceof ExtensionInterface) { throw new \LogicException(sprintf('Extension "%s" must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', get_debug_type($extension))); } // check naming convention $basename = preg_replace('/Bundle$/', '', $this->getName()); $expectedAlias = Container::underscore($basename); if ($expectedAlias != $extension->getAlias()) { throw new \LogicException(sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', $expectedAlias, $extension->getAlias())); } $this->extension = $extension; } else { $this->extension = false; } } return $this->extension ?: null; } public function getNamespace(): string { if (!isset($this->namespace)) { $this->parseClassName(); } return $this->namespace; } public function getPath(): string { if (null === $this->path) { $reflected = new \ReflectionObject($this); $this->path = \dirname($reflected->getFileName()); } return $this->path; } /** * Returns the bundle name (the class short name). */ final public function getName(): string { if (null === $this->name) { $this->parseClassName(); } return $this->name; } /** * @return void */ public function registerCommands(Application $application) { } /** * Returns the bundle's container extension class. */ protected function getContainerExtensionClass(): string { $basename = preg_replace('/Bundle$/', '', $this->getName()); return $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; } /** * Creates the bundle's container extension. */ protected function createContainerExtension(): ?ExtensionInterface { return class_exists($class = $this->getContainerExtensionClass()) ? new $class() : null; } private function parseClassName(): void { $pos = strrpos(static::class, '\\'); $this->namespace = false === $pos ? '' : substr(static::class, 0, $pos); $this->name ??= false === $pos ? static::class : substr(static::class, $pos + 1); } } Resources/welcome.html.php 0000644 00000077434 15111167611 0011644 0 ustar 00 <!DOCTYPE html> <html dir="ltr" lang="en"> <head> <meta charset="UTF-8" /> <meta name="robots" content="noindex,nofollow,noarchive,nosnippet,noodp,notranslate,noimageindex" /> <title>Welcome to Symfony!</title> <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>👋</text></svg>"> <style> <?php $hue = random_int(0, 360); ?> <?php $darkColor = static fn (float $alpha = 1) => "hsla($hue, 20%, 45%, $alpha)"; ?> <?php $lightColor = static fn (float $alpha = 1) => "hsla($hue, 20%, 95%, $alpha)"; ?> body { background: <?= $lightColor(); ?>; color: <?= $darkColor(); ?>; display: flex; font: 16px/1.5 sans-serif; justify-content: center; margin: 0; } h1, h2 { line-height: 1.2; margin: 0 0 .5em; } h1 { font-size: 36px; } h2 { font-size: 21px; margin-bottom: 1em; } a { color: <?= $darkColor(0.75); ?> } a:hover { text-decoration: none; } code { border-radius: 25px; background: <?= $lightColor(); ?>; box-shadow: 0 0 45px -15px hsl(<?= $hue; ?>, 20%, 2%); color: <?= $darkColor(); ?>; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; align-items: center; padding-right: 20px; position: relative; word-wrap: break-word; z-index: 1; } svg { overflow: hidden; vertical-align: text-bottom; } .wrapper { text-align: center; width: 100%; } .container { position: relative; background: radial-gradient(ellipse at bottom, <?= $darkColor(); ?> 0%, hsl(<?= $hue; ?>, 20%, 13%) 100%); background-attachment: fixed; color: <?= $lightColor(); ?>; } .container:after { content: ""; position: absolute; height: 2px; width: 2px; top: -2px; left: 0; background: white; box-shadow: 778px 1019px 0 0 rgba(255, 255, 255, 0.826) , 1075px 1688px 0 0 rgba(255,255,255, 0.275) , 388px 1021px 0 0 rgba(255,255,255, 0.259) , 1238px 626px 0 0 rgba(255,255,255, 0.469) , 997px 904px 0 0 rgba(255,255,255, 0.925) , 921px 1345px 0 0 rgba(255,255,255, 0.698) , 337px 1236px 0 0 rgba(255,255,255, 0.838) , 460px 569px 0 0 rgba(255,255,255, 0.01) , 690px 1488px 0 0 rgba(255,255,255, 0.154) , 859px 926px 0 0 rgba(255,255,255, 0.515) , 1272px 791px 0 0 rgba(255,255,255, 1) , 238px 1256px 0 0 rgba(255,255,255, 0.633) , 1486px 897px 0 0 rgba(255,255,255, 0.88) , 667px 6px 0 0 rgba(255,255,255, 0.508) , 853px 504px 0 0 rgba(255,255,255, 0.248) , 1329px 1778px 0 0 rgba(255,255,255, 0.217) , 768px 1340px 0 0 rgba(255,255,255, 0.792) , 631px 1383px 0 0 rgba(255,255,255, 0.698) , 991px 1603px 0 0 rgba(255,255,255, 0.939) , 1778px 1767px 0 0 rgba(255,255,255, 0.784) , 285px 546px 0 0 rgba(255,255,255, 0.8) , 1224px 1333px 0 0 rgba(255,255,255, 0.676) , 1154px 397px 0 0 rgba(255,255,255, 0.974) , 1210px 1004px 0 0 rgba(255,255,255, 0.894) , 1632px 953px 0 0 rgba(255,255,255, 0.281) , 449px 1144px 0 0 rgba(255,255,255, 0.706) , 1426px 771px 0 0 rgba(255,255,255, 0.737) , 1438px 1634px 0 0 rgba(255,255,255, 0.984) , 806px 168px 0 0 rgba(255,255,255, 0.807) , 731px 1067px 0 0 rgba(255,255,255, 0.734) , 1731px 1785px 0 0 rgba(255,255,255, 0.528) , 23px 975px 0 0 rgba(255,255,255, 0.068) , 575px 1088px 0 0 rgba(255,255,255, 0.876) , 1205px 1668px 0 0 rgba(255,255,255, 0.601) , 18px 1457px 0 0 rgba(255,255,255, 0.176) , 252px 1163px 0 0 rgba(255,255,255, 0.416) , 1752px 1px 0 0 rgba(255,255,255, 0.374) , 382px 767px 0 0 rgba(255,255,255, 0.073) , 133px 1462px 0 0 rgba(255,255,255, 0.706) , 851px 1166px 0 0 rgba(255,255,255, 0.535) , 374px 921px 0 0 rgba(255,255,255, 0.548) , 554px 1598px 0 0 rgba(255,255,255, 0.062) , 314px 685px 0 0 rgba(255,255,255, 0.187) , 1443px 209px 0 0 rgba(255,255,255, 0.097) , 1774px 1625px 0 0 rgba(255,255,255, 0.32) , 58px 278px 0 0 rgba(255,255,255, 0.684) , 986px 338px 0 0 rgba(255,255,255, 0.272) , 718px 1357px 0 0 rgba(255,255,255, 0.317) , 722px 983px 0 0 rgba(255,255,255, 0.568) , 1124px 992px 0 0 rgba(255,255,255, 0.199) , 581px 619px 0 0 rgba(255,255,255, 0.44) , 1120px 285px 0 0 rgba(255,255,255, 0.425) , 702px 138px 0 0 rgba(255,255,255, 0.816) , 262px 767px 0 0 rgba(255,255,255, 0.92) , 1204px 38px 0 0 rgba(255,255,255, 0.197) , 1196px 410px 0 0 rgba(255,255,255, 0.453) , 707px 699px 0 0 rgba(255,255,255, 0.481) , 1590px 1488px 0 0 rgba(255,255,255, 0.559) , 879px 1763px 0 0 rgba(255,255,255, 0.241) , 106px 686px 0 0 rgba(255,255,255, 0.175) , 158px 569px 0 0 rgba(255,255,255, 0.549) , 711px 1219px 0 0 rgba(255,255,255, 0.476) , 1339px 53px 0 0 rgba(255,255,255, 0.275) , 1410px 172px 0 0 rgba(255,255,255, 0.449) , 1601px 1484px 0 0 rgba(255,255,255, 0.988) , 1328px 1752px 0 0 rgba(255,255,255, 0.827) , 1733px 1475px 0 0 rgba(255,255,255, 0.567) , 559px 742px 0 0 rgba(255,255,255, 0.423) , 772px 844px 0 0 rgba(255,255,255, 0.039) , 602px 520px 0 0 rgba(255,255,255, 0.284) , 1158px 1067px 0 0 rgba(255,255,255, 0.066) , 1562px 730px 0 0 rgba(255,255,255, 0.086) , 1792px 615px 0 0 rgba(255,255,255, 0.438) , 1085px 1191px 0 0 rgba(255,255,255, 0.157) , 1402px 1087px 0 0 rgba(255,255,255, 0.797) , 569px 1685px 0 0 rgba(255,255,255, 0.992) , 1608px 52px 0 0 rgba(255,255,255, 0.302) , 1697px 1246px 0 0 rgba(255,255,255, 0.295) , 899px 1490px 0 0 rgba(255,255,255, 0.73) , 993px 901px 0 0 rgba(255,255,255, 0.961) , 1193px 1023px 0 0 rgba(255,255,255, 0.671) , 1224px 176px 0 0 rgba(255,255,255, 0.786) , 721px 1308px 0 0 rgba(255,255,255, 0.691) , 1702px 730px 0 0 rgba(255,255,255, 0.841) , 1480px 1498px 0 0 rgba(255,255,255, 0.655) , 181px 1612px 0 0 rgba(255,255,255, 0.588) , 1776px 679px 0 0 rgba(255,255,255, 0.821) , 892px 706px 0 0 rgba(255,255,255, 0.056) , 859px 267px 0 0 rgba(255,255,255, 0.565) , 784px 1285px 0 0 rgba(255,255,255, 0.029) , 1561px 1198px 0 0 rgba(255,255,255, 0.315) , 205px 421px 0 0 rgba(255,255,255, 0.584) , 236px 406px 0 0 rgba(255,255,255, 0.166) , 1259px 689px 0 0 rgba(255,255,255, 0.321) , 448px 317px 0 0 rgba(255,255,255, 0.495) , 1318px 466px 0 0 rgba(255,255,255, 0.275) , 1053px 297px 0 0 rgba(255,255,255, 0.035) , 716px 538px 0 0 rgba(255,255,255, 0.764) , 381px 207px 0 0 rgba(255,255,255, 0.692) , 871px 1140px 0 0 rgba(255,255,255, 0.342) , 361px 53px 0 0 rgba(255,255,255, 0.984) , 1565px 1593px 0 0 rgba(255,255,255, 0.102) , 145px 277px 0 0 rgba(255,255,255, 0.866) , 220px 1503px 0 0 rgba(255,255,255, 0.936) , 1068px 1475px 0 0 rgba(255,255,255, 0.156) , 1548px 483px 0 0 rgba(255,255,255, 0.768) , 710px 103px 0 0 rgba(255,255,255, 0.809) , 1660px 921px 0 0 rgba(255,255,255, 0.952) , 462px 1252px 0 0 rgba(255,255,255, 0.825) , 1123px 1628px 0 0 rgba(255,255,255, 0.409) , 1274px 729px 0 0 rgba(255,255,255, 0.26) , 1739px 679px 0 0 rgba(255,255,255, 0.83) , 1550px 1518px 0 0 rgba(255,255,255, 0.25) , 1624px 346px 0 0 rgba(255,255,255, 0.557) , 1023px 579px 0 0 rgba(255,255,255, 0.854) , 217px 661px 0 0 rgba(255,255,255, 0.731) , 1504px 549px 0 0 rgba(255,255,255, 0.705) , 939px 5px 0 0 rgba(255,255,255, 0.389) , 284px 735px 0 0 rgba(255,255,255, 0.355) , 13px 1679px 0 0 rgba(255,255,255, 0.712) , 137px 1592px 0 0 rgba(255,255,255, 0.619) , 1113px 505px 0 0 rgba(255,255,255, 0.651) , 1584px 510px 0 0 rgba(255,255,255, 0.41) , 346px 913px 0 0 rgba(255,255,255, 0.09) , 198px 1490px 0 0 rgba(255,255,255, 0.103) , 447px 1128px 0 0 rgba(255,255,255, 0.314) , 1356px 324px 0 0 rgba(255,255,255, 0.324) , 648px 667px 0 0 rgba(255,255,255, 0.155) , 442px 260px 0 0 rgba(255,255,255, 0.22) , 210px 401px 0 0 rgba(255,255,255, 0.682) , 422px 1772px 0 0 rgba(255,255,255, 0.671) , 276px 349px 0 0 rgba(255,255,255, 0.683) , 131px 539px 0 0 rgba(255,255,255, 0.977) , 892px 94px 0 0 rgba(255,255,255, 0.081) , 1295px 222px 0 0 rgba(255,255,255, 0.961) , 5px 1727px 0 0 rgba(255,255,255, 0.311) , 714px 1148px 0 0 rgba(255,255,255, 0.846) , 1455px 1182px 0 0 rgba(255,255,255, 0.313) , 1370px 708px 0 0 rgba(255,255,255, 0.824) , 812px 433px 0 0 rgba(255,255,255, 0.75) , 1110px 558px 0 0 rgba(255,255,255, 0.709) , 1132px 1543px 0 0 rgba(255,255,255, 0.868) , 644px 610px 0 0 rgba(255,255,255, 0.166) , 269px 1481px 0 0 rgba(255,255,255, 0.889) , 1712px 590px 0 0 rgba(255,255,255, 0.139) , 1159px 599px 0 0 rgba(255,255,255, 0.992) , 1551px 209px 0 0 rgba(255,255,255, 0.033) , 1020px 1721px 0 0 rgba(255,255,255, 0.028) , 216px 373px 0 0 rgba(255,255,255, 0.665) , 877px 532px 0 0 rgba(255,255,255, 0.686) , 1326px 885px 0 0 rgba(255,255,255, 0.517) , 972px 1704px 0 0 rgba(255,255,255, 0.499) , 749px 181px 0 0 rgba(255,255,255, 0.712) , 1511px 1650px 0 0 rgba(255,255,255, 0.101) , 1432px 183px 0 0 rgba(255,255,255, 0.545) , 1541px 1338px 0 0 rgba(255,255,255, 0.71) , 513px 1406px 0 0 rgba(255,255,255, 0.17) , 1314px 1197px 0 0 rgba(255,255,255, 0.789) , 824px 1659px 0 0 rgba(255,255,255, 0.597) , 308px 298px 0 0 rgba(255,255,255, 0.917) , 1225px 659px 0 0 rgba(255,255,255, 0.229) , 1253px 257px 0 0 rgba(255,255,255, 0.631) , 1653px 185px 0 0 rgba(255,255,255, 0.113) , 336px 614px 0 0 rgba(255,255,255, 0.045) , 1093px 898px 0 0 rgba(255,255,255, 0.617) , 730px 5px 0 0 rgba(255,255,255, 0.11) , 785px 645px 0 0 rgba(255,255,255, 0.516) , 989px 678px 0 0 rgba(255,255,255, 0.917) , 1511px 1614px 0 0 rgba(255,255,255, 0.938) , 584px 1117px 0 0 rgba(255,255,255, 0.631) , 534px 1012px 0 0 rgba(255,255,255, 0.668) , 1325px 1778px 0 0 rgba(255,255,255, 0.293) , 1632px 754px 0 0 rgba(255,255,255, 0.26) , 78px 1258px 0 0 rgba(255,255,255, 0.52) , 779px 1691px 0 0 rgba(255,255,255, 0.878) , 253px 1706px 0 0 rgba(255,255,255, 0.75) , 1358px 245px 0 0 rgba(255,255,255, 0.027) , 361px 1629px 0 0 rgba(255,255,255, 0.238) , 1134px 232px 0 0 rgba(255,255,255, 0.387) , 1685px 777px 0 0 rgba(255,255,255, 0.156) , 515px 724px 0 0 rgba(255,255,255, 0.863) , 588px 1728px 0 0 rgba(255,255,255, 0.159) , 1132px 47px 0 0 rgba(255,255,255, 0.691) , 315px 1446px 0 0 rgba(255,255,255, 0.782) , 79px 233px 0 0 rgba(255,255,255, 0.317) , 1498px 1050px 0 0 rgba(255,255,255, 0.358) , 30px 1073px 0 0 rgba(255,255,255, 0.939) , 1637px 620px 0 0 rgba(255,255,255, 0.141) , 1736px 1683px 0 0 rgba(255,255,255, 0.682) , 1298px 1505px 0 0 rgba(255,255,255, 0.863) , 972px 85px 0 0 rgba(255,255,255, 0.941) , 349px 1356px 0 0 rgba(255,255,255, 0.672) , 1545px 1429px 0 0 rgba(255,255,255, 0.859) , 1076px 467px 0 0 rgba(255,255,255, 0.024) , 189px 1647px 0 0 rgba(255,255,255, 0.838) , 423px 1722px 0 0 rgba(255,255,255, 0.771) , 1691px 1719px 0 0 rgba(255,255,255, 0.676) , 1747px 658px 0 0 rgba(255,255,255, 0.255) , 149px 1492px 0 0 rgba(255,255,255, 0.911) , 1203px 1138px 0 0 rgba(255,255,255, 0.964) , 781px 1584px 0 0 rgba(255,255,255, 0.465) , 1609px 1595px 0 0 rgba(255,255,255, 0.688) , 447px 1655px 0 0 rgba(255,255,255, 0.166) , 914px 1153px 0 0 rgba(255,255,255, 0.085) , 600px 1058px 0 0 rgba(255,255,255, 0.821) , 804px 505px 0 0 rgba(255,255,255, 0.608) , 1506px 584px 0 0 rgba(255,255,255, 0.618) , 587px 1290px 0 0 rgba(255,255,255, 0.071) , 258px 600px 0 0 rgba(255,255,255, 0.243) , 328px 395px 0 0 rgba(255,255,255, 0.065) , 846px 783px 0 0 rgba(255,255,255, 0.995) , 1138px 1294px 0 0 rgba(255,255,255, 0.703) , 1668px 633px 0 0 rgba(255,255,255, 0.27) , 337px 103px 0 0 rgba(255,255,255, 0.202) , 132px 986px 0 0 rgba(255,255,255, 0.726) , 414px 757px 0 0 rgba(255,255,255, 0.752) , 8px 1311px 0 0 rgba(255,255,255, 0.307) , 1791px 910px 0 0 rgba(255,255,255, 0.346) , 844px 216px 0 0 rgba(255,255,255, 0.156) , 1547px 1723px 0 0 rgba(255,255,255, 0.73) , 1187px 398px 0 0 rgba(255,255,255, 0.698) , 1550px 1520px 0 0 rgba(255,255,255, 0.462) , 1346px 655px 0 0 rgba(255,255,255, 0.58) , 668px 770px 0 0 rgba(255,255,255, 0.422) , 1774px 1435px 0 0 rgba(255,255,255, 0.089) , 693px 1061px 0 0 rgba(255,255,255, 0.893) , 132px 1689px 0 0 rgba(255,255,255, 0.937) , 894px 1561px 0 0 rgba(255,255,255, 0.88) , 906px 1706px 0 0 rgba(255,255,255, 0.567) , 1140px 297px 0 0 rgba(255,255,255, 0.358) , 13px 1288px 0 0 rgba(255,255,255, 0.464) , 1744px 423px 0 0 rgba(255,255,255, 0.845) , 119px 1548px 0 0 rgba(255,255,255, 0.769) , 1249px 1321px 0 0 rgba(255,255,255, 0.29) , 123px 795px 0 0 rgba(255,255,255, 0.597) , 390px 1542px 0 0 rgba(255,255,255, 0.47) , 825px 667px 0 0 rgba(255,255,255, 0.049) , 1071px 875px 0 0 rgba(255,255,255, 0.06) , 1428px 1786px 0 0 rgba(255,255,255, 0.222) , 993px 696px 0 0 rgba(255,255,255, 0.399) , 1585px 247px 0 0 rgba(255,255,255, 0.094) , 1340px 1312px 0 0 rgba(255,255,255, 0.603) , 1640px 725px 0 0 rgba(255,255,255, 0.026) , 1161px 1397px 0 0 rgba(255,255,255, 0.222) , 966px 1132px 0 0 rgba(255,255,255, 0.69) , 1782px 1275px 0 0 rgba(255,255,255, 0.606) , 1117px 1533px 0 0 rgba(255,255,255, 0.248) , 1027px 959px 0 0 rgba(255,255,255, 0.46) , 459px 839px 0 0 rgba(255,255,255, 0.98) , 1192px 265px 0 0 rgba(255,255,255, 0.523) , 175px 501px 0 0 rgba(255,255,255, 0.371) , 626px 19px 0 0 rgba(255,255,255, 0.246) , 46px 1173px 0 0 rgba(255,255,255, 0.124) , 573px 925px 0 0 rgba(255,255,255, 0.621) , 1px 283px 0 0 rgba(255,255,255, 0.943) , 778px 1213px 0 0 rgba(255,255,255, 0.128) , 435px 593px 0 0 rgba(255,255,255, 0.378) , 32px 394px 0 0 rgba(255,255,255, 0.451) , 1019px 1055px 0 0 rgba(255,255,255, 0.685) , 1423px 1233px 0 0 rgba(255,255,255, 0.354) , 494px 841px 0 0 rgba(255,255,255, 0.322) , 667px 194px 0 0 rgba(255,255,255, 0.655) , 1671px 195px 0 0 rgba(255,255,255, 0.502) , 403px 1710px 0 0 rgba(255,255,255, 0.623) , 665px 1597px 0 0 rgba(255,255,255, 0.839) , 61px 1742px 0 0 rgba(255,255,255, 0.566) , 1490px 1654px 0 0 rgba(255,255,255, 0.646) , 1361px 1604px 0 0 rgba(255,255,255, 0.101) , 1191px 1023px 0 0 rgba(255,255,255, 0.881) , 550px 378px 0 0 rgba(255,255,255, 0.573) , 1332px 1234px 0 0 rgba(255,255,255, 0.922) , 760px 1205px 0 0 rgba(255,255,255, 0.992) , 1506px 1328px 0 0 rgba(255,255,255, 0.723) , 1126px 813px 0 0 rgba(255,255,255, 0.549) , 67px 240px 0 0 rgba(255,255,255, 0.901) , 125px 1301px 0 0 rgba(255,255,255, 0.464) , 643px 391px 0 0 rgba(255,255,255, 0.589) , 1114px 1756px 0 0 rgba(255,255,255, 0.321) , 1602px 699px 0 0 rgba(255,255,255, 0.274) , 510px 393px 0 0 rgba(255,255,255, 0.185) , 171px 1217px 0 0 rgba(255,255,255, 0.932) , 1202px 1362px 0 0 rgba(255,255,255, 0.726) , 1160px 1324px 0 0 rgba(255,255,255, 0.867) , 121px 319px 0 0 rgba(255,255,255, 0.992) , 1474px 835px 0 0 rgba(255,255,255, 0.89) , 357px 1213px 0 0 rgba(255,255,255, 0.91) , 783px 976px 0 0 rgba(255,255,255, 0.941) , 750px 1599px 0 0 rgba(255,255,255, 0.515) , 323px 450px 0 0 rgba(255,255,255, 0.966) , 1078px 282px 0 0 rgba(255,255,255, 0.947) , 1164px 46px 0 0 rgba(255,255,255, 0.296) , 1792px 705px 0 0 rgba(255,255,255, 0.485) , 880px 1287px 0 0 rgba(255,255,255, 0.894) , 60px 1402px 0 0 rgba(255,255,255, 0.816) , 752px 894px 0 0 rgba(255,255,255, 0.803) , 285px 1535px 0 0 rgba(255,255,255, 0.93) , 1528px 401px 0 0 rgba(255,255,255, 0.727) , 651px 1767px 0 0 rgba(255,255,255, 0.146) , 1498px 1190px 0 0 rgba(255,255,255, 0.042) , 394px 1786px 0 0 rgba(255,255,255, 0.159) , 1318px 9px 0 0 rgba(255,255,255, 0.575) , 1699px 1675px 0 0 rgba(255,255,255, 0.511) , 82px 986px 0 0 rgba(255,255,255, 0.906) , 940px 970px 0 0 rgba(255,255,255, 0.562) , 1624px 259px 0 0 rgba(255,255,255, 0.537) , 1782px 222px 0 0 rgba(255,255,255, 0.259) , 1572px 1725px 0 0 rgba(255,255,255, 0.716) , 1080px 1557px 0 0 rgba(255,255,255, 0.245) , 1727px 648px 0 0 rgba(255,255,255, 0.471) , 899px 231px 0 0 rgba(255,255,255, 0.445) , 1061px 1074px 0 0 rgba(255,255,255, 0.079) , 556px 478px 0 0 rgba(255,255,255, 0.524) , 343px 359px 0 0 rgba(255,255,255, 0.162) , 711px 1254px 0 0 rgba(255,255,255, 0.323) , 1335px 242px 0 0 rgba(255,255,255, 0.936) , 933px 39px 0 0 rgba(255,255,255, 0.784) , 1629px 908px 0 0 rgba(255,255,255, 0.289) , 1800px 229px 0 0 rgba(255,255,255, 0.399) , 1589px 926px 0 0 rgba(255,255,255, 0.709) , 976px 694px 0 0 rgba(255,255,255, 0.855) , 1163px 1240px 0 0 rgba(255,255,255, 0.754) , 1662px 1784px 0 0 rgba(255,255,255, 0.088) , 656px 1388px 0 0 rgba(255,255,255, 0.688) , 1190px 1100px 0 0 rgba(255,255,255, 0.769) , 33px 392px 0 0 rgba(255,255,255, 0.301) , 56px 1405px 0 0 rgba(255,255,255, 0.969) , 1491px 118px 0 0 rgba(255,255,255, 0.991) , 1216px 997px 0 0 rgba(255,255,255, 0.727) , 1617px 712px 0 0 rgba(255,255,255, 0.45) , 163px 553px 0 0 rgba(255,255,255, 0.977) , 103px 140px 0 0 rgba(255,255,255, 0.916) , 1099px 1404px 0 0 rgba(255,255,255, 0.167) , 1423px 587px 0 0 rgba(255,255,255, 0.792) , 1797px 309px 0 0 rgba(255,255,255, 0.526) , 381px 141px 0 0 rgba(255,255,255, 0.005) , 1214px 802px 0 0 rgba(255,255,255, 0.887) , 211px 829px 0 0 rgba(255,255,255, 0.72) , 1103px 1507px 0 0 rgba(255,255,255, 0.642) , 244px 1231px 0 0 rgba(255,255,255, 0.184) , 118px 1747px 0 0 rgba(255,255,255, 0.475) , 183px 1293px 0 0 rgba(255,255,255, 0.148) , 911px 1362px 0 0 rgba(255,255,255, 0.073) , 817px 457px 0 0 rgba(255,255,255, 0.459) , 756px 18px 0 0 rgba(255,255,255, 0.544) , 481px 1118px 0 0 rgba(255,255,255, 0.878) , 380px 138px 0 0 rgba(255,255,255, 0.132) , 320px 646px 0 0 rgba(255,255,255, 0.04) , 1724px 1716px 0 0 rgba(255,255,255, 0.381) , 978px 1269px 0 0 rgba(255,255,255, 0.431) , 1530px 255px 0 0 rgba(255,255,255, 0.31) , 664px 204px 0 0 rgba(255,255,255, 0.913) , 474px 703px 0 0 rgba(255,255,255, 0.832) , 1722px 1204px 0 0 rgba(255,255,255, 0.356) , 1453px 821px 0 0 rgba(255,255,255, 0.195) , 730px 1468px 0 0 rgba(255,255,255, 0.696) , 928px 1610px 0 0 rgba(255,255,255, 0.894) , 1036px 304px 0 0 rgba(255,255,255, 0.696) , 1590px 172px 0 0 rgba(255,255,255, 0.729) , 249px 1590px 0 0 rgba(255,255,255, 0.277) , 357px 81px 0 0 rgba(255,255,255, 0.526) , 726px 1261px 0 0 rgba(255,255,255, 0.149) , 643px 946px 0 0 rgba(255,255,255, 0.005) , 1263px 995px 0 0 rgba(255,255,255, 0.124) , 1564px 1107px 0 0 rgba(255,255,255, 0.789) , 388px 83px 0 0 rgba(255,255,255, 0.498) , 715px 681px 0 0 rgba(255,255,255, 0.655) , 1618px 1624px 0 0 rgba(255,255,255, 0.63) , 1423px 1576px 0 0 rgba(255,255,255, 0.52) , 564px 1786px 0 0 rgba(255,255,255, 0.482) , 1066px 735px 0 0 rgba(255,255,255, 0.276) , 714px 1179px 0 0 rgba(255,255,255, 0.395) , 967px 1006px 0 0 rgba(255,255,255, 0.923) , 1136px 1790px 0 0 rgba(255,255,255, 0.801) , 215px 1690px 0 0 rgba(255,255,255, 0.957) , 1500px 1338px 0 0 rgba(255,255,255, 0.541) , 1679px 1065px 0 0 rgba(255,255,255, 0.925) , 426px 1489px 0 0 rgba(255,255,255, 0.193) , 1273px 853px 0 0 rgba(255,255,255, 0.317) , 665px 1189px 0 0 rgba(255,255,255, 0.512) , 520px 552px 0 0 rgba(255,255,255, 0.925) , 253px 438px 0 0 rgba(255,255,255, 0.588) , 369px 1354px 0 0 rgba(255,255,255, 0.889) , 749px 205px 0 0 rgba(255,255,255, 0.243) , 820px 145px 0 0 rgba(255,255,255, 0.207) , 1739px 228px 0 0 rgba(255,255,255, 0.267) , 392px 495px 0 0 rgba(255,255,255, 0.504) , 721px 1044px 0 0 rgba(255,255,255, 0.823) , 833px 912px 0 0 rgba(255,255,255, 0.222) , 865px 1499px 0 0 rgba(255,255,255, 0.003) , 313px 756px 0 0 rgba(255,255,255, 0.727) , 439px 1187px 0 0 rgba(255,255,255, 0.572) , 6px 1238px 0 0 rgba(255,255,255, 0.676) , 1567px 11px 0 0 rgba(255,255,255, 0.701) , 1216px 757px 0 0 rgba(255,255,255, 0.87) , 916px 588px 0 0 rgba(255,255,255, 0.565) , 831px 215px 0 0 rgba(255,255,255, 0.597) , 1289px 697px 0 0 rgba(255,255,255, 0.964) , 307px 34px 0 0 rgba(255,255,255, 0.462) , 3px 1685px 0 0 rgba(255,255,255, 0.464) , 1115px 1421px 0 0 rgba(255,255,255, 0.303) , 1451px 473px 0 0 rgba(255,255,255, 0.142) , 1374px 1205px 0 0 rgba(255,255,255, 0.086) , 1564px 317px 0 0 rgba(255,255,255, 0.773) , 304px 1127px 0 0 rgba(255,255,255, 0.653) , 446px 214px 0 0 rgba(255,255,255, 0.135) , 1541px 459px 0 0 rgba(255,255,255, 0.725) , 1387px 880px 0 0 rgba(255,255,255, 0.157) , 1172px 224px 0 0 rgba(255,255,255, 0.088) , 1420px 637px 0 0 rgba(255,255,255, 0.916) , 1385px 932px 0 0 rgba(255,255,255, 0.225) , 174px 1472px 0 0 rgba(255,255,255, 0.649) , 252px 750px 0 0 rgba(255,255,255, 0.277) , 825px 1042px 0 0 rgba(255,255,255, 0.707) , 840px 703px 0 0 rgba(255,255,255, 0.948) , 1478px 1800px 0 0 rgba(255,255,255, 0.151) , 95px 1303px 0 0 rgba(255,255,255, 0.332) , 1198px 740px 0 0 rgba(255,255,255, 0.443) , 141px 312px 0 0 rgba(255,255,255, 0.04) , 291px 729px 0 0 rgba(255,255,255, 0.284) , 1209px 1506px 0 0 rgba(255,255,255, 0.741) , 1188px 307px 0 0 rgba(255,255,255, 0.141) , 958px 41px 0 0 rgba(255,255,255, 0.858) , 1311px 1484px 0 0 rgba(255,255,255, 0.097) , 846px 1153px 0 0 rgba(255,255,255, 0.862) , 1238px 1376px 0 0 rgba(255,255,255, 0.071) , 1499px 342px 0 0 rgba(255,255,255, 0.719) , 640px 833px 0 0 rgba(255,255,255, 0.966) , 712px 545px 0 0 rgba(255,255,255, 0.194) , 1655px 1542px 0 0 rgba(255,255,255, 0.82) , 616px 353px 0 0 rgba(255,255,255, 0.871) , 1591px 1631px 0 0 rgba(255,255,255, 0.61) , 1664px 591px 0 0 rgba(255,255,255, 0.35) , 934px 454px 0 0 rgba(255,255,255, 0.58) , 1175px 477px 0 0 rgba(255,255,255, 0.966) , 299px 914px 0 0 rgba(255,255,255, 0.839) , 534px 243px 0 0 rgba(255,255,255, 0.194) , 773px 1135px 0 0 rgba(255,255,255, 0.42) , 1696px 1472px 0 0 rgba(255,255,255, 0.552) , 125px 523px 0 0 rgba(255,255,255, 0.591) , 1195px 382px 0 0 rgba(255,255,255, 0.904) , 1609px 1374px 0 0 rgba(255,255,255, 0.579) , 843px 82px 0 0 rgba(255,255,255, 0.072) , 1604px 451px 0 0 rgba(255,255,255, 0.545) , 1322px 190px 0 0 rgba(255,255,255, 0.034) , 528px 228px 0 0 rgba(255,255,255, 0.146) , 1470px 1169px 0 0 rgba(255,255,255, 0.912) , 502px 1350px 0 0 rgba(255,255,255, 0.594) , 1031px 298px 0 0 rgba(255,255,255, 0.368) , 1100px 1427px 0 0 rgba(255,255,255, 0.79) , 979px 1105px 0 0 rgba(255,255,255, 0.973) , 643px 1184px 0 0 rgba(255,255,255, 0.813) , 1636px 1701px 0 0 rgba(255,255,255, 0.013) , 1004px 245px 0 0 rgba(255,255,255, 0.412) , 680px 740px 0 0 rgba(255,255,255, 0.967) , 1599px 562px 0 0 rgba(255,255,255, 0.66) , 256px 1617px 0 0 rgba(255,255,255, 0.463) , 314px 1092px 0 0 rgba(255,255,255, 0.734) , 870px 900px 0 0 rgba(255,255,255, 0.512) , 530px 60px 0 0 rgba(255,255,255, 0.198) , 1786px 896px 0 0 rgba(255,255,255, 0.392) , 636px 212px 0 0 rgba(255,255,255, 0.997) , 672px 540px 0 0 rgba(255,255,255, 0.632) , 1118px 1649px 0 0 rgba(255,255,255, 0.377) , 433px 647px 0 0 rgba(255,255,255, 0.902) , 1200px 1737px 0 0 rgba(255,255,255, 0.262) , 1258px 143px 0 0 rgba(255,255,255, 0.729) , 1603px 1364px 0 0 rgba(255,255,255, 0.192) , 66px 1756px 0 0 rgba(255,255,255, 0.681) , 946px 263px 0 0 rgba(255,255,255, 0.105) , 1216px 1082px 0 0 rgba(255,255,255, 0.287) , 6px 1143px 0 0 rgba(255,255,255, 0.017) , 1631px 126px 0 0 rgba(255,255,255, 0.449) , 357px 1565px 0 0 rgba(255,255,255, 0.163) , 1752px 261px 0 0 rgba(255,255,255, 0.423) , 1247px 1631px 0 0 rgba(255,255,255, 0.312) , 320px 671px 0 0 rgba(255,255,255, 0.695) , 1375px 596px 0 0 rgba(255,255,255, 0.856) , 1456px 1340px 0 0 rgba(255,255,255, 0.564) , 447px 1044px 0 0 rgba(255,255,255, 0.623) , 1732px 447px 0 0 rgba(255,255,255, 0.216) , 174px 1509px 0 0 rgba(255,255,255, 0.398) , 16px 861px 0 0 rgba(255,255,255, 0.904) , 878px 1296px 0 0 rgba(255,255,255, 0.205) , 1725px 1483px 0 0 rgba(255,255,255, 0.704) , 255px 48px 0 0 rgba(255,255,255, 0.7) , 610px 1669px 0 0 rgba(255,255,255, 0.865) , 1044px 1251px 0 0 rgba(255,255,255, 0.98) , 884px 862px 0 0 rgba(255,255,255, 0.198) , 986px 545px 0 0 rgba(255,255,255, 0.379) , 1620px 217px 0 0 rgba(255,255,255, 0.159) , 383px 1763px 0 0 rgba(255,255,255, 0.518) , 595px 974px 0 0 rgba(255,255,255, 0.347) , 359px 14px 0 0 rgba(255,255,255, 0.863) , 95px 1385px 0 0 rgba(255,255,255, 0.011) , 411px 1030px 0 0 rgba(255,255,255, 0.038) , 345px 789px 0 0 rgba(255,255,255, 0.771) , 421px 460px 0 0 rgba(255,255,255, 0.133) , 972px 1160px 0 0 rgba(255,255,255, 0.342) , 597px 1061px 0 0 rgba(255,255,255, 0.781) , 1017px 1092px 0 0 rgba(255,255,255, 0.437); } .warning { background: <?= $lightColor(); ?>; display: flex; align-items: center; padding: 10px; text-align: left; justify-content: center; } .warning svg { flex-shrink: 0; height: 32px; width: 32px; margin-right: 10px; } .warning p { line-height: 1.4; margin: 0; } .container svg.wave { position: absolute; bottom: -2px; left: 0; z-index: 1; } .container .logo { margin-bottom: 1em; } .container .logo svg { fill: hsl(<?= $hue; ?>, 20%, 26%); } .welcome { padding-top: 4em; margin-bottom: 3em; } .welcome small { display: block; font-size: 85%; } .status { padding-bottom: 2em; } .status code, .status .status-ready { display: none; } .version { font-size: 34px; } .check { background: <?= $darkColor(); ?>; border-radius: 20px; width: 50px; display: flex; align-items: center; justify-content: center; height: 37px; margin: 6px 8px 6px 6px; } .check svg { fill: <?= $lightColor(); ?>; } .status-ready { margin: 28px 0 0; } .resources { margin: 0 auto; max-width: 1366px; padding: 2.5em 0 3.5em; } .resources .row { margin-left: 30px; margin-right: 30px; display: flex; justify-content: space-evenly; } .resource { padding: 0 10px; position: relative; } .resource svg { height: 48px; width: 48px; fill: <?= $darkColor(); ?>; margin-bottom: 5px; } .resource h2 { font-size: 18px; font-weight: normal; margin-bottom: 5px; } .resource p { margin-top: 5px; } .resource a { display: block; font-size: 14px; } @media (min-width: 768px) { @-webkit-keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } } .sf-toolbar { opacity: 0; -webkit-animation: fade-in 1s .2s forwards; animation: fade-in 1s .2s forwards; z-index: 99999; } .resources .row { margin-left: 50px; margin-right: 50px; } .resource { padding: 0 30px; } .status { padding-bottom: 4em; } .status code { display: inline-flex; } .status .status-ready { display: block; } .resource svg { height: 64px; width: 64px; } .resource h2 { font-size: 22px; } .resource a { font-size: 16px; margin-top: 0; } } @media (min-width: 992px) { body { font-size: 20px; } .warning { text-align: center; } } </style> </head> <body> <div class="wrapper"> <div class="warning"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="32"><path fill="currentColor" d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z" class=""></path></svg> <p> You're seeing this page because you haven't configured any homepage URL and <a href="https://symfony.com/doc/<?= $docVersion; ?>/debug-mode">debug mode</a> is enabled. </p> </div> <div class="container"> <div class="welcome"> <div class="logo"> <svg xmlns="http://www.w3.org/2000/svg" width="112.165" height="112.166"><path d="M112.165 56.079c0 30.976-25.109 56.087-56.084 56.087C25.108 112.166 0 87.055 0 56.079 0 25.108 25.107 0 56.081 0c30.975 0 56.084 25.108 56.084 56.079z" style="fill: <?= $lightColor(); ?>;"/><path d="M80.603 20.75c-5.697.195-10.67 3.34-14.373 7.68-4.1 4.765-6.824 10.411-8.791 16.18-3.514-2.882-6.223-6.611-11.864-8.233-4.359-1.253-8.936-.737-13.146 2.399-1.992 1.489-3.367 3.738-4.02 5.859-1.692 5.498 1.778 10.396 3.354 12.151l3.447 3.691c.709.725 2.422 2.613 1.584 5.319-.9 2.947-4.451 4.85-8.092 3.731-1.627-.499-3.963-1.71-3.439-3.413.215-.699.715-1.225.984-1.821.244-.521.363-.907.438-1.14.665-2.169-.245-4.994-2.57-5.713-2.171-.666-4.391-.138-5.252 2.655-.977 3.174.543 8.935 8.681 11.441 9.535 2.935 17.597-2.259 18.742-9.026.721-4.239-1.195-7.392-4.701-11.441l-2.859-3.163c-1.73-1.729-2.324-4.677-.533-6.942 1.512-1.912 3.664-2.726 7.191-1.768 5.15 1.396 7.443 4.969 11.271 7.851-1.578 5.187-2.613 10.392-3.547 15.059l-.574 3.481c-2.736 14.352-4.826 22.235-10.256 26.76-1.094.779-2.658 1.943-5.014 2.027-1.238.037-1.637-.814-1.654-1.186-.027-.865.703-1.264 1.188-1.652.727-.396 1.824-1.053 1.748-3.156-.078-2.484-2.137-4.639-5.111-4.541-2.229.075-5.625 2.171-5.497 6.011.131 3.967 3.827 6.938 9.401 6.75 2.979-.102 9.633-1.312 16.188-9.105 7.631-8.935 9.766-19.175 11.372-26.671l1.793-9.897c.992.119 2.059.2 3.217.228 9.504.201 14.256-4.72 14.328-8.302.049-2.167-1.42-4.302-3.479-4.251-1.471.041-3.32 1.022-3.762 3.057-.436 1.995 3.023 3.798.32 5.553-1.92 1.242-5.361 2.116-10.209 1.407l.881-4.872c1.799-9.238 4.018-20.6 12.436-20.878.615-.029 2.857.026 2.91 1.512.014.493-.109.623-.689 1.757-.592.884-.814 1.64-.785 2.504.08 2.356 1.873 3.908 4.471 3.818 3.473-.116 4.469-3.496 4.412-5.233-.146-4.085-4.449-6.665-10.14-6.477z"/></svg> </div> <h1><small>Welcome to</small> Symfony <span class="version"><?= $version; ?></span></h1> </div> <div class="status"> <code> <span class="check"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg> </span> <span><?= $projectDir; ?></span> </code> <p class="status-ready">Your application is now ready and you can start working on it.</p> </div> <svg style="pointer-events: none" class="wave" width="100%" height="50px" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 75"><defs><style>.a{fill:none}.b{clip-path:url(#a)}.c,.d {fill: <?= $lightColor(); ?>}.d{opacity:0.5;isolation:isolate;}</style><clipPath id="a"><rect class="a" width="1920" height="75"></rect></clipPath></defs><g class="b"><path class="c" d="M1963,327H-105V65A2647.49,2647.49,0,0,1,431,19c217.7,3.5,239.6,30.8,470,36,297.3,6.7,367.5-36.2,642-28a2511.41,2511.41,0,0,1,420,48"></path></g><g class="b"><path class="d" d="M-127,404H1963V44c-140.1-28-343.3-46.7-566,22-75.5,23.3-118.5,45.9-162,64-48.6,20.2-404.7,128-784,0C355.2,97.7,341.6,78.3,235,50,86.6,10.6-41.8,6.9-127,10"></path></g><g class="b"><path class="d" d="M1979,462-155,446V106C251.8,20.2,576.6,15.9,805,30c167.4,10.3,322.3,32.9,680,56,207,13.4,378,20.3,494,24"></path></g><g class="b"><path class="d" d="M1998,484H-243V100c445.8,26.8,794.2-4.1,1035-39,141-20.4,231.1-40.1,378-45,349.6-11.6,636.7,73.8,828,150"></path></g></svg> </div> <div class="resources"> <div class="row"> <div class="resource"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 11.55C9.64 9.35 6.48 8 3 8v11c3.48 0 6.64 1.35 9 3.55 2.36-2.19 5.52-3.55 9-3.55V8c-3.48 0-6.64 1.35-9 3.55zM12 8c1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3 1.34 3 3 3z"/></svg> <h2>Documentation</h2> <a href="https://symfony.com/doc/<?= $docVersion; ?>/index.html"> Guides, components, references </a> </div> <div class="resource"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg> <h2>Tutorials</h2> <a href="https://symfony.com/doc/<?= $docVersion; ?>/page_creation.html"> Create your first page </a> </div> <div class="resource"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></svg> <h2>Community</h2> <a href="https://symfony.com/community"> Connect, get help, or contribute </a> </div> </div> </div> </div> </body> </html> Resources/error_log 0000644 00000001552 15111167611 0010436 0 ustar 00 [19-Nov-2025 15:55:46 UTC] PHP Warning: Undefined variable $docVersion in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Resources/welcome.html.php on line 72 [19-Nov-2025 15:55:46 UTC] PHP Warning: Undefined variable $version in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Resources/welcome.html.php on line 81 [19-Nov-2025 15:55:46 UTC] PHP Warning: Undefined variable $projectDir in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Resources/welcome.html.php on line 89 [19-Nov-2025 15:55:46 UTC] PHP Warning: Undefined variable $docVersion in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Resources/welcome.html.php on line 102 [19-Nov-2025 15:55:46 UTC] PHP Warning: Undefined variable $docVersion in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Resources/welcome.html.php on line 109 HttpClientKernel.php 0000644 00000007536 15111167611 0010507 0 ustar 00 <?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\HttpKernel; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\Mime\Part\AbstractPart; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\Multipart\FormDataPart; use Symfony\Component\Mime\Part\TextPart; use Symfony\Contracts\HttpClient\HttpClientInterface; // Help opcache.preload discover always-needed symbols class_exists(ResponseHeaderBag::class); /** * An implementation of a Symfony HTTP kernel using a "real" HTTP client. * * @author Fabien Potencier <fabien@symfony.com> */ final class HttpClientKernel implements HttpKernelInterface { private HttpClientInterface $client; public function __construct(HttpClientInterface $client = null) { if (null === $client && !class_exists(HttpClient::class)) { throw new \LogicException(sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); } $this->client = $client ?? HttpClient::create(); } public function handle(Request $request, int $type = HttpKernelInterface::MAIN_REQUEST, bool $catch = true): Response { $headers = $this->getHeaders($request); $body = ''; if (null !== $part = $this->getBody($request)) { $headers = array_merge($headers, $part->getPreparedHeaders()->toArray()); $body = $part->bodyToIterable(); } $response = $this->client->request($request->getMethod(), $request->getUri(), [ 'headers' => $headers, 'body' => $body, ] + $request->attributes->get('http_client_options', [])); $response = new Response($response->getContent(!$catch), $response->getStatusCode(), $response->getHeaders(!$catch)); $response->headers->remove('X-Body-File'); $response->headers->remove('X-Body-Eval'); $response->headers->remove('X-Content-Digest'); $response->headers = new class($response->headers->all()) extends ResponseHeaderBag { protected function computeCacheControlValue(): string { return $this->getCacheControlHeader(); // preserve the original value } }; return $response; } private function getBody(Request $request): ?AbstractPart { if (\in_array($request->getMethod(), ['GET', 'HEAD'])) { return null; } if (!class_exists(AbstractPart::class)) { throw new \LogicException('You cannot pass non-empty bodies as the Mime component is not installed. Try running "composer require symfony/mime".'); } if ($content = $request->getContent()) { return new TextPart($content, 'utf-8', 'plain', '8bit'); } $fields = $request->request->all(); foreach ($request->files->all() as $name => $file) { $fields[$name] = DataPart::fromPath($file->getPathname(), $file->getClientOriginalName(), $file->getClientMimeType()); } return new FormDataPart($fields); } private function getHeaders(Request $request): array { $headers = []; foreach ($request->headers as $key => $value) { $headers[$key] = $value; } $cookies = []; foreach ($request->cookies->all() as $name => $value) { $cookies[] = $name.'='.$value; } if ($cookies) { $headers['cookie'] = implode('; ', $cookies); } return $headers; } } EventListener/RouterListener.php 0000644 00000014514 15111167611 0013037 0 ustar 00 <?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\HttpKernel\EventListener; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RequestContextAwareInterface; /** * Initializes the context from the request and sets request attributes based on a matching route. * * @author Fabien Potencier <fabien@symfony.com> * @author Yonel Ceruto <yonelceruto@gmail.com> * * @final */ class RouterListener implements EventSubscriberInterface { private RequestMatcherInterface|UrlMatcherInterface $matcher; private RequestContext $context; private ?LoggerInterface $logger; private RequestStack $requestStack; private ?string $projectDir; private bool $debug; /** * @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface) * * @throws \InvalidArgumentException */ public function __construct(UrlMatcherInterface|RequestMatcherInterface $matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null, string $projectDir = null, bool $debug = true) { if (null === $context && !$matcher instanceof RequestContextAwareInterface) { throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.'); } $this->matcher = $matcher; $this->context = $context ?? $matcher->getContext(); $this->requestStack = $requestStack; $this->logger = $logger; $this->projectDir = $projectDir; $this->debug = $debug; } private function setCurrentRequest(?Request $request): void { if (null !== $request) { try { $this->context->fromRequest($request); } catch (\UnexpectedValueException $e) { throw new BadRequestHttpException($e->getMessage(), $e, $e->getCode()); } } } /** * After a sub-request is done, we need to reset the routing context to the parent request so that the URL generator * operates on the correct context again. */ public function onKernelFinishRequest(): void { $this->setCurrentRequest($this->requestStack->getParentRequest()); } public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); $this->setCurrentRequest($request); if ($request->attributes->has('_controller')) { // routing is already done return; } // add attributes based on the request (routing) try { // matching a request is more powerful than matching a URL path + context, so try that first if ($this->matcher instanceof RequestMatcherInterface) { $parameters = $this->matcher->matchRequest($request); } else { $parameters = $this->matcher->match($request->getPathInfo()); } $this->logger?->info('Matched route "{route}".', [ 'route' => $parameters['_route'] ?? 'n/a', 'route_parameters' => $parameters, 'request_uri' => $request->getUri(), 'method' => $request->getMethod(), ]); $request->attributes->add($parameters); unset($parameters['_route'], $parameters['_controller']); $request->attributes->set('_route_params', $parameters); } catch (ResourceNotFoundException $e) { $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getUriForPath($request->getPathInfo())); if ($referer = $request->headers->get('referer')) { $message .= sprintf(' (from "%s")', $referer); } throw new NotFoundHttpException($message, $e); } catch (MethodNotAllowedException $e) { $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getUriForPath($request->getPathInfo()), implode(', ', $e->getAllowedMethods())); throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e); } } public function onKernelException(ExceptionEvent $event): void { if (!$this->debug || !($e = $event->getThrowable()) instanceof NotFoundHttpException) { return; } if ($e->getPrevious() instanceof NoConfigurationException) { $event->setResponse($this->createWelcomeResponse()); } } public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => [['onKernelRequest', 32]], KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', 0]], KernelEvents::EXCEPTION => ['onKernelException', -64], ]; } private function createWelcomeResponse(): Response { $version = Kernel::VERSION; $projectDir = realpath((string) $this->projectDir).\DIRECTORY_SEPARATOR; $docVersion = substr(Kernel::VERSION, 0, 3); ob_start(); include \dirname(__DIR__).'/Resources/welcome.html.php'; return new Response(ob_get_clean(), Response::HTTP_NOT_FOUND); } } EventListener/DumpListener.php 0000644 00000003701 15111167611 0012460 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\VarDumper\Cloner\ClonerInterface; use Symfony\Component\VarDumper\Dumper\DataDumperInterface; use Symfony\Component\VarDumper\Server\Connection; use Symfony\Component\VarDumper\VarDumper; /** * Configures dump() handler. * * @author Nicolas Grekas <p@tchwork.com> */ class DumpListener implements EventSubscriberInterface { private ClonerInterface $cloner; private DataDumperInterface $dumper; private ?Connection $connection; public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper, Connection $connection = null) { $this->cloner = $cloner; $this->dumper = $dumper; $this->connection = $connection; } /** * @return void */ public function configure() { $cloner = $this->cloner; $dumper = $this->dumper; $connection = $this->connection; VarDumper::setHandler(static function ($var, string $label = null) use ($cloner, $dumper, $connection) { $data = $cloner->cloneVar($var); if (null !== $label) { $data = $data->withContext(['label' => $label]); } if (!$connection || !$connection->write($data)) { $dumper->dump($data); } }); } public static function getSubscribedEvents(): array { if (!class_exists(ConsoleEvents::class)) { return []; } // Register early to have a working dump() as early as possible return [ConsoleEvents::COMMAND => ['configure', 1024]]; } } EventListener/ResponseListener.php 0000644 00000003547 15111167611 0013361 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; /** * ResponseListener fixes the Response headers based on the Request. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class ResponseListener implements EventSubscriberInterface { private string $charset; private bool $addContentLanguageHeader; public function __construct(string $charset, bool $addContentLanguageHeader = false) { $this->charset = $charset; $this->addContentLanguageHeader = $addContentLanguageHeader; } /** * Filters the Response. */ public function onKernelResponse(ResponseEvent $event): void { if (!$event->isMainRequest()) { return; } $response = $event->getResponse(); if (null === $response->getCharset()) { $response->setCharset($this->charset); } if ($this->addContentLanguageHeader && !$response->isInformational() && !$response->isEmpty() && !$response->headers->has('Content-Language')) { $response->headers->set('Content-Language', $event->getRequest()->getLocale()); } if ($event->getRequest()->attributes->get('_vary_by_language')) { $response->setVary('Accept-Language', false); } $response->prepare($event->getRequest()); } public static function getSubscribedEvents(): array { return [ KernelEvents::RESPONSE => 'onKernelResponse', ]; } } EventListener/ErrorListener.php 0000644 00000017753 15111167611 0012660 0 ustar 00 <?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\HttpKernel\EventListener; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; use Symfony\Component\ErrorHandler\Exception\FlattenException; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\WithHttpStatus; use Symfony\Component\HttpKernel\Attribute\WithLogLevel; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; /** * @author Fabien Potencier <fabien@symfony.com> */ class ErrorListener implements EventSubscriberInterface { protected $controller; protected $logger; protected $debug; /** * @var array<class-string, array{log_level: string|null, status_code: int<100,599>|null}> */ protected $exceptionsMapping; /** * @param array<class-string, array{log_level: string|null, status_code: int<100,599>|null}> $exceptionsMapping */ public function __construct(string|object|array|null $controller, LoggerInterface $logger = null, bool $debug = false, array $exceptionsMapping = []) { $this->controller = $controller; $this->logger = $logger; $this->debug = $debug; $this->exceptionsMapping = $exceptionsMapping; } /** * @return void */ public function logKernelException(ExceptionEvent $event) { $throwable = $event->getThrowable(); $logLevel = $this->resolveLogLevel($throwable); foreach ($this->exceptionsMapping as $class => $config) { if (!$throwable instanceof $class || !$config['status_code']) { continue; } if (!$throwable instanceof HttpExceptionInterface || $throwable->getStatusCode() !== $config['status_code']) { $headers = $throwable instanceof HttpExceptionInterface ? $throwable->getHeaders() : []; $throwable = new HttpException($config['status_code'], $throwable->getMessage(), $throwable, $headers); $event->setThrowable($throwable); } break; } // There's no specific status code defined in the configuration for this exception if (!$throwable instanceof HttpExceptionInterface) { $class = new \ReflectionClass($throwable); do { if ($attributes = $class->getAttributes(WithHttpStatus::class, \ReflectionAttribute::IS_INSTANCEOF)) { /** @var WithHttpStatus $instance */ $instance = $attributes[0]->newInstance(); $throwable = new HttpException($instance->statusCode, $throwable->getMessage(), $throwable, $instance->headers); $event->setThrowable($throwable); break; } } while ($class = $class->getParentClass()); } $e = FlattenException::createFromThrowable($throwable); $this->logException($throwable, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()), $logLevel); } /** * @return void */ public function onKernelException(ExceptionEvent $event) { if (null === $this->controller) { return; } $throwable = $event->getThrowable(); $request = $this->duplicateRequest($throwable, $event->getRequest()); try { $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false); } catch (\Exception $e) { $f = FlattenException::createFromThrowable($e); $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), $e->getFile(), $e->getLine())); $prev = $e; do { if ($throwable === $wrapper = $prev) { throw $e; } } while ($prev = $wrapper->getPrevious()); $prev = new \ReflectionProperty($wrapper instanceof \Exception ? \Exception::class : \Error::class, 'previous'); $prev->setValue($wrapper, $throwable); throw $e; } $event->setResponse($response); if ($this->debug) { $event->getRequest()->attributes->set('_remove_csp_headers', true); } } public function removeCspHeader(ResponseEvent $event): void { if ($this->debug && $event->getRequest()->attributes->get('_remove_csp_headers', false)) { $event->getResponse()->headers->remove('Content-Security-Policy'); } } /** * @return void */ public function onControllerArguments(ControllerArgumentsEvent $event) { $e = $event->getRequest()->attributes->get('exception'); if (!$e instanceof \Throwable || false === $k = array_search($e, $event->getArguments(), true)) { return; } $r = new \ReflectionFunction($event->getController()(...)); $r = $r->getParameters()[$k] ?? null; if ($r && (!($r = $r->getType()) instanceof \ReflectionNamedType || FlattenException::class === $r->getName())) { $arguments = $event->getArguments(); $arguments[$k] = FlattenException::createFromThrowable($e); $event->setArguments($arguments); } } public static function getSubscribedEvents(): array { return [ KernelEvents::CONTROLLER_ARGUMENTS => 'onControllerArguments', KernelEvents::EXCEPTION => [ ['logKernelException', 0], ['onKernelException', -128], ], KernelEvents::RESPONSE => ['removeCspHeader', -128], ]; } /** * Logs an exception. */ protected function logException(\Throwable $exception, string $message, string $logLevel = null): void { if (null === $this->logger) { return; } $logLevel ??= $this->resolveLogLevel($exception); $this->logger->log($logLevel, $message, ['exception' => $exception]); } /** * Resolves the level to be used when logging the exception. */ private function resolveLogLevel(\Throwable $throwable): string { foreach ($this->exceptionsMapping as $class => $config) { if ($throwable instanceof $class && $config['log_level']) { return $config['log_level']; } } $class = new \ReflectionClass($throwable); do { if ($attributes = $class->getAttributes(WithLogLevel::class)) { /** @var WithLogLevel $instance */ $instance = $attributes[0]->newInstance(); return $instance->level; } } while ($class = $class->getParentClass()); if (!$throwable instanceof HttpExceptionInterface || $throwable->getStatusCode() >= 500) { return LogLevel::CRITICAL; } return LogLevel::ERROR; } /** * Clones the request for the exception. */ protected function duplicateRequest(\Throwable $exception, Request $request): Request { $attributes = [ '_controller' => $this->controller, 'exception' => $exception, 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, ]; $request = $request->duplicate(null, null, $attributes); $request->setMethod('GET'); return $request; } } EventListener/ValidateRequestListener.php 0000644 00000002225 15111167612 0014656 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; /** * Validates Requests. * * @author Magnus Nordlander <magnus@fervo.se> * * @final */ class ValidateRequestListener implements EventSubscriberInterface { /** * Performs the validation. */ public function onKernelRequest(RequestEvent $event): void { if (!$event->isMainRequest()) { return; } $request = $event->getRequest(); if ($request::getTrustedProxies()) { $request->getClientIps(); } $request->getHost(); } public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => [ ['onKernelRequest', 256], ], ]; } } EventListener/ProfilerListener.php 0000644 00000012207 15111167612 0013337 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestMatcherInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\Event\TerminateEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Profiler\Profile; use Symfony\Component\HttpKernel\Profiler\Profiler; /** * ProfilerListener collects data for the current request by listening to the kernel events. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class ProfilerListener implements EventSubscriberInterface { private Profiler $profiler; private ?RequestMatcherInterface $matcher; private bool $onlyException; private bool $onlyMainRequests; private ?\Throwable $exception = null; /** @var \SplObjectStorage<Request, Profile> */ private \SplObjectStorage $profiles; private RequestStack $requestStack; private ?string $collectParameter; /** @var \SplObjectStorage<Request, Request|null> */ private \SplObjectStorage $parents; /** * @param bool $onlyException True if the profiler only collects data when an exception occurs, false otherwise * @param bool $onlyMainRequests True if the profiler only collects data when the request is the main request, false otherwise */ public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, bool $onlyException = false, bool $onlyMainRequests = false, string $collectParameter = null) { $this->profiler = $profiler; $this->matcher = $matcher; $this->onlyException = $onlyException; $this->onlyMainRequests = $onlyMainRequests; $this->profiles = new \SplObjectStorage(); $this->parents = new \SplObjectStorage(); $this->requestStack = $requestStack; $this->collectParameter = $collectParameter; } /** * Handles the onKernelException event. */ public function onKernelException(ExceptionEvent $event): void { if ($this->onlyMainRequests && !$event->isMainRequest()) { return; } $this->exception = $event->getThrowable(); } /** * Handles the onKernelResponse event. */ public function onKernelResponse(ResponseEvent $event): void { if ($this->onlyMainRequests && !$event->isMainRequest()) { return; } if ($this->onlyException && null === $this->exception) { return; } $request = $event->getRequest(); if (null !== $this->collectParameter && null !== $collectParameterValue = $request->get($this->collectParameter)) { true === $collectParameterValue || filter_var($collectParameterValue, \FILTER_VALIDATE_BOOL) ? $this->profiler->enable() : $this->profiler->disable(); } $exception = $this->exception; $this->exception = null; if (null !== $this->matcher && !$this->matcher->matches($request)) { return; } $session = $request->hasPreviousSession() ? $request->getSession() : null; if ($session instanceof Session) { $usageIndexValue = $usageIndexReference = &$session->getUsageIndex(); $usageIndexReference = \PHP_INT_MIN; } try { if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) { return; } } finally { if ($session instanceof Session) { $usageIndexReference = $usageIndexValue; } } $this->profiles[$request] = $profile; $this->parents[$request] = $this->requestStack->getParentRequest(); } public function onKernelTerminate(TerminateEvent $event): void { // attach children to parents foreach ($this->profiles as $request) { if (null !== $parentRequest = $this->parents[$request]) { if (isset($this->profiles[$parentRequest])) { $this->profiles[$parentRequest]->addChild($this->profiles[$request]); } } } // save profiles foreach ($this->profiles as $request) { $this->profiler->saveProfile($this->profiles[$request]); } $this->profiles = new \SplObjectStorage(); $this->parents = new \SplObjectStorage(); } public static function getSubscribedEvents(): array { return [ KernelEvents::RESPONSE => ['onKernelResponse', -100], KernelEvents::EXCEPTION => ['onKernelException', 0], KernelEvents::TERMINATE => ['onKernelTerminate', -1024], ]; } } EventListener/LocaleListener.php 0000644 00000006145 15111167612 0012760 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\RequestContextAwareInterface; /** * Initializes the locale based on the current request. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class LocaleListener implements EventSubscriberInterface { private ?RequestContextAwareInterface $router; private string $defaultLocale; private RequestStack $requestStack; private bool $useAcceptLanguageHeader; private array $enabledLocales; public function __construct(RequestStack $requestStack, string $defaultLocale = 'en', RequestContextAwareInterface $router = null, bool $useAcceptLanguageHeader = false, array $enabledLocales = []) { $this->defaultLocale = $defaultLocale; $this->requestStack = $requestStack; $this->router = $router; $this->useAcceptLanguageHeader = $useAcceptLanguageHeader; $this->enabledLocales = $enabledLocales; } public function setDefaultLocale(KernelEvent $event): void { $event->getRequest()->setDefaultLocale($this->defaultLocale); } public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); $this->setLocale($request); $this->setRouterContext($request); } public function onKernelFinishRequest(FinishRequestEvent $event): void { if (null !== $parentRequest = $this->requestStack->getParentRequest()) { $this->setRouterContext($parentRequest); } } private function setLocale(Request $request): void { if ($locale = $request->attributes->get('_locale')) { $request->setLocale($locale); } elseif ($this->useAcceptLanguageHeader) { if ($preferredLanguage = $request->getPreferredLanguage($this->enabledLocales)) { $request->setLocale($preferredLanguage); } $request->attributes->set('_vary_by_language', true); } } private function setRouterContext(Request $request): void { $this->router?->getContext()->setParameter('_locale', $request->getLocale()); } public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => [ ['setDefaultLocale', 100], // must be registered after the Router to have access to the _locale ['onKernelRequest', 16], ], KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', 0]], ]; } } EventListener/DisallowRobotsIndexingListener.php 0000644 00000002114 15111167612 0016206 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; /** * Ensures that the application is not indexed by search engines. * * @author Gary PEGEOT <garypegeot@gmail.com> */ class DisallowRobotsIndexingListener implements EventSubscriberInterface { private const HEADER_NAME = 'X-Robots-Tag'; public function onResponse(ResponseEvent $event): void { if (!$event->getResponse()->headers->has(static::HEADER_NAME)) { $event->getResponse()->headers->set(static::HEADER_NAME, 'noindex'); } } public static function getSubscribedEvents(): array { return [ KernelEvents::RESPONSE => ['onResponse', -255], ]; } } EventListener/AbstractSessionListener.php 0000644 00000030302 15111167612 0014660 0 ustar 00 <?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\HttpKernel\EventListener; use Psr\Container\ContainerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionUtils; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\Exception\UnexpectedSessionUsageException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Contracts\Service\ResetInterface; /** * Sets the session onto the request on the "kernel.request" event and saves * it on the "kernel.response" event. * * In addition, if the session has been started it overrides the Cache-Control * header in such a way that all caching is disabled in that case. * If you have a scenario where caching responses with session information in * them makes sense, you can disable this behaviour by setting the header * AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER on the response. * * @author Johannes M. Schmitt <schmittjoh@gmail.com> * @author Tobias Schultze <http://tobion.de> * * @internal */ abstract class AbstractSessionListener implements EventSubscriberInterface, ResetInterface { public const NO_AUTO_CACHE_CONTROL_HEADER = 'Symfony-Session-NoAutoCacheControl'; protected $container; private bool $debug; /** * @var array<string, mixed> */ private $sessionOptions; public function __construct(ContainerInterface $container = null, bool $debug = false, array $sessionOptions = []) { $this->container = $container; $this->debug = $debug; $this->sessionOptions = $sessionOptions; } public function onKernelRequest(RequestEvent $event): void { if (!$event->isMainRequest()) { return; } $request = $event->getRequest(); if (!$request->hasSession()) { $request->setSessionFactory(function () use ($request) { // Prevent calling `$this->getSession()` twice in case the Request (and the below factory) is cloned static $sess; if (!$sess) { $sess = $this->getSession(); $request->setSession($sess); /* * For supporting sessions in php runtime with runners like roadrunner or swoole, the session * cookie needs to be read from the cookie bag and set on the session storage. * * Do not set it when a native php session is active. */ if ($sess && !$sess->isStarted() && \PHP_SESSION_ACTIVE !== session_status()) { $sessionId = $sess->getId() ?: $request->cookies->get($sess->getName(), ''); $sess->setId($sessionId); } } return $sess; }); } } public function onKernelResponse(ResponseEvent $event): void { if (!$event->isMainRequest() || (!$this->container->has('initialized_session') && !$event->getRequest()->hasSession())) { return; } $response = $event->getResponse(); $autoCacheControl = !$response->headers->has(self::NO_AUTO_CACHE_CONTROL_HEADER); // Always remove the internal header if present $response->headers->remove(self::NO_AUTO_CACHE_CONTROL_HEADER); if (!$event->getRequest()->hasSession(true)) { return; } $session = $event->getRequest()->getSession(); if ($session->isStarted()) { /* * Saves the session, in case it is still open, before sending the response/headers. * * This ensures several things in case the developer did not save the session explicitly: * * * If a session save handler without locking is used, it ensures the data is available * on the next request, e.g. after a redirect. PHPs auto-save at script end via * session_register_shutdown is executed after fastcgi_finish_request. So in this case * the data could be missing the next request because it might not be saved the moment * the new request is processed. * * A locking save handler (e.g. the native 'files') circumvents concurrency problems like * the one above. But by saving the session before long-running things in the terminate event, * we ensure the session is not blocked longer than needed. * * When regenerating the session ID no locking is involved in PHPs session design. See * https://bugs.php.net/61470 for a discussion. So in this case, the session must * be saved anyway before sending the headers with the new session ID. Otherwise session * data could get lost again for concurrent requests with the new ID. One result could be * that you get logged out after just logging in. * * This listener should be executed as one of the last listeners, so that previous listeners * can still operate on the open session. This prevents the overhead of restarting it. * Listeners after closing the session can still work with the session as usual because * Symfonys session implementation starts the session on demand. So writing to it after * it is saved will just restart it. */ $session->save(); /* * For supporting sessions in php runtime with runners like roadrunner or swoole the session * cookie need to be written on the response object and should not be written by PHP itself. */ $sessionName = $session->getName(); $sessionId = $session->getId(); $sessionOptions = $this->getSessionOptions($this->sessionOptions); $sessionCookiePath = $sessionOptions['cookie_path'] ?? '/'; $sessionCookieDomain = $sessionOptions['cookie_domain'] ?? null; $sessionCookieSecure = $sessionOptions['cookie_secure'] ?? false; $sessionCookieHttpOnly = $sessionOptions['cookie_httponly'] ?? true; $sessionCookieSameSite = $sessionOptions['cookie_samesite'] ?? Cookie::SAMESITE_LAX; $sessionUseCookies = $sessionOptions['use_cookies'] ?? true; SessionUtils::popSessionCookie($sessionName, $sessionId); if ($sessionUseCookies) { $request = $event->getRequest(); $requestSessionCookieId = $request->cookies->get($sessionName); $isSessionEmpty = ($session instanceof Session ? $session->isEmpty() : !$session->all()) && empty($_SESSION); // checking $_SESSION to keep compatibility with native sessions if ($requestSessionCookieId && $isSessionEmpty) { // PHP internally sets the session cookie value to "deleted" when setcookie() is called with empty string $value argument // which happens in \Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler::destroy // when the session gets invalidated (for example on logout) so we must handle this case here too // otherwise we would send two Set-Cookie headers back with the response SessionUtils::popSessionCookie($sessionName, 'deleted'); $response->headers->clearCookie( $sessionName, $sessionCookiePath, $sessionCookieDomain, $sessionCookieSecure, $sessionCookieHttpOnly, $sessionCookieSameSite ); } elseif ($sessionId !== $requestSessionCookieId && !$isSessionEmpty) { $expire = 0; $lifetime = $sessionOptions['cookie_lifetime'] ?? null; if ($lifetime) { $expire = time() + $lifetime; } $response->headers->setCookie( Cookie::create( $sessionName, $sessionId, $expire, $sessionCookiePath, $sessionCookieDomain, $sessionCookieSecure, $sessionCookieHttpOnly, false, $sessionCookieSameSite ) ); } } } if ($session instanceof Session ? 0 === $session->getUsageIndex() : !$session->isStarted()) { return; } if ($autoCacheControl) { $maxAge = $response->headers->hasCacheControlDirective('public') ? 0 : (int) $response->getMaxAge(); $response ->setExpires(new \DateTimeImmutable('+'.$maxAge.' seconds')) ->setPrivate() ->setMaxAge($maxAge) ->headers->addCacheControlDirective('must-revalidate'); } if (!$event->getRequest()->attributes->get('_stateless', false)) { return; } if ($this->debug) { throw new UnexpectedSessionUsageException('Session was used while the request was declared stateless.'); } if ($this->container->has('logger')) { $this->container->get('logger')->warning('Session was used while the request was declared stateless.'); } } public function onSessionUsage(): void { if (!$this->debug) { return; } if ($this->container?->has('session_collector')) { $this->container->get('session_collector')(); } if (!$requestStack = $this->container?->has('request_stack') ? $this->container->get('request_stack') : null) { return; } $stateless = false; $clonedRequestStack = clone $requestStack; while (null !== ($request = $clonedRequestStack->pop()) && !$stateless) { $stateless = $request->attributes->get('_stateless'); } if (!$stateless) { return; } if (!$session = $requestStack->getCurrentRequest()->getSession()) { return; } if ($session->isStarted()) { $session->save(); } throw new UnexpectedSessionUsageException('Session was used while the request was declared stateless.'); } public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => ['onKernelRequest', 128], // low priority to come after regular response listeners KernelEvents::RESPONSE => ['onKernelResponse', -1000], ]; } public function reset(): void { if (\PHP_SESSION_ACTIVE === session_status()) { session_abort(); } session_unset(); $_SESSION = []; if (!headers_sent()) { // session id can only be reset when no headers were so we check for headers_sent first session_id(''); } } /** * Gets the session object. */ abstract protected function getSession(): ?SessionInterface; private function getSessionOptions(array $sessionOptions): array { $mergedSessionOptions = []; foreach (session_get_cookie_params() as $key => $value) { $mergedSessionOptions['cookie_'.$key] = $value; } foreach ($sessionOptions as $key => $value) { // do the same logic as in the NativeSessionStorage if ('cookie_secure' === $key && 'auto' === $value) { continue; } $mergedSessionOptions[$key] = $value; } return $mergedSessionOptions; } } EventListener/error_log 0000644 00000015063 15111167612 0011256 0 ustar 00 [19-Nov-2025 11:11:41 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ResponseListener.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ResponseListener.php on line 25 [19-Nov-2025 11:12:14 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/LocaleAwareListener.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/LocaleAwareListener.php on line 26 [19-Nov-2025 11:13:16 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\EventListener\AbstractSessionListener" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/SessionListener.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/SessionListener.php on line 23 [19-Nov-2025 11:16:23 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php:31 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php on line 31 [19-Nov-2025 11:18:16 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/RouterListener.php:42 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/RouterListener.php on line 42 [19-Nov-2025 11:19:15 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/SurrogateListener.php:27 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/SurrogateListener.php on line 27 [19-Nov-2025 11:20:20 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ProfilerListener.php:33 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ProfilerListener.php on line 33 [19-Nov-2025 11:21:25 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php on line 28 [19-Nov-2025 11:22:28 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ErrorListener.php:33 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ErrorListener.php on line 33 [19-Nov-2025 11:23:29 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/DisallowRobotsIndexingListener.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/DisallowRobotsIndexingListener.php on line 23 [19-Nov-2025 11:24:33 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/DumpListener.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/DumpListener.php on line 26 [19-Nov-2025 11:25:33 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php on line 25 [19-Nov-2025 11:26:34 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/LocaleListener.php:30 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/LocaleListener.php on line 30 [19-Nov-2025 11:27:39 UTC] PHP Fatal error: Uncaught Error: Call to undefined function Symfony\Component\HttpKernel\EventListener\trigger_deprecation() in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php on line 19 [19-Nov-2025 11:29:46 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php on line 25 [19-Nov-2025 11:30:41 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php:41 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php on line 41 [19-Nov-2025 11:37:11 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\EventDispatcher\EventSubscriberInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/FragmentListener.php:34 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/EventListener/FragmentListener.php on line 34 EventListener/LocaleAwareListener.php 0000644 00000004621 15111167612 0013735 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Contracts\Translation\LocaleAwareInterface; /** * Pass the current locale to the provided services. * * @author Pierre Bobiet <pierrebobiet@gmail.com> */ class LocaleAwareListener implements EventSubscriberInterface { private iterable $localeAwareServices; private RequestStack $requestStack; /** * @param iterable<mixed, LocaleAwareInterface> $localeAwareServices */ public function __construct(iterable $localeAwareServices, RequestStack $requestStack) { $this->localeAwareServices = $localeAwareServices; $this->requestStack = $requestStack; } public function onKernelRequest(RequestEvent $event): void { $this->setLocale($event->getRequest()->getLocale(), $event->getRequest()->getDefaultLocale()); } public function onKernelFinishRequest(FinishRequestEvent $event): void { if (null === $parentRequest = $this->requestStack->getParentRequest()) { foreach ($this->localeAwareServices as $service) { $service->setLocale($event->getRequest()->getDefaultLocale()); } return; } $this->setLocale($parentRequest->getLocale(), $parentRequest->getDefaultLocale()); } public static function getSubscribedEvents(): array { return [ // must be registered after the Locale listener KernelEvents::REQUEST => [['onKernelRequest', 15]], KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', -15]], ]; } private function setLocale(string $locale, string $defaultLocale): void { foreach ($this->localeAwareServices as $service) { try { $service->setLocale($locale); } catch (\InvalidArgumentException) { $service->setLocale($defaultLocale); } } } } EventListener/SessionListener.php 0000644 00000001365 15111167612 0013203 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\HttpFoundation\Session\SessionInterface; /** * Sets the session in the request. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class SessionListener extends AbstractSessionListener { protected function getSession(): ?SessionInterface { if ($this->container->has('session_factory')) { return $this->container->get('session_factory')->createSession(); } return null; } } EventListener/SurrogateListener.php 0000644 00000003427 15111167612 0013534 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\HttpCache\HttpCache; use Symfony\Component\HttpKernel\HttpCache\SurrogateInterface; use Symfony\Component\HttpKernel\KernelEvents; /** * SurrogateListener adds a Surrogate-Control HTTP header when the Response needs to be parsed for Surrogates. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class SurrogateListener implements EventSubscriberInterface { private ?SurrogateInterface $surrogate; public function __construct(SurrogateInterface $surrogate = null) { $this->surrogate = $surrogate; } /** * Filters the Response. */ public function onKernelResponse(ResponseEvent $event): void { if (!$event->isMainRequest()) { return; } $kernel = $event->getKernel(); $surrogate = $this->surrogate; if ($kernel instanceof HttpCache) { $surrogate = $kernel->getSurrogate(); if (null !== $this->surrogate && $this->surrogate->getName() !== $surrogate->getName()) { $surrogate = $this->surrogate; } } if (null === $surrogate) { return; } $surrogate->addSurrogateControl($event->getResponse()); } public static function getSubscribedEvents(): array { return [ KernelEvents::RESPONSE => 'onKernelResponse', ]; } } EventListener/FragmentListener.php 0000644 00000005573 15111167612 0013330 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\UriSigner; /** * Handles content fragments represented by special URIs. * * All URL paths starting with /_fragment are handled as * content fragments by this listener. * * Throws an AccessDeniedHttpException exception if the request * is not signed or if it is not an internal sub-request. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class FragmentListener implements EventSubscriberInterface { private UriSigner $signer; private string $fragmentPath; /** * @param string $fragmentPath The path that triggers this listener */ public function __construct(UriSigner $signer, string $fragmentPath = '/_fragment') { $this->signer = $signer; $this->fragmentPath = $fragmentPath; } /** * Fixes request attributes when the path is '/_fragment'. * * @throws AccessDeniedHttpException if the request does not come from a trusted IP */ public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); if ($this->fragmentPath !== rawurldecode($request->getPathInfo())) { return; } if ($request->attributes->has('_controller')) { // Is a sub-request: no need to parse _path but it should still be removed from query parameters as below. $request->query->remove('_path'); return; } if ($event->isMainRequest()) { $this->validateRequest($request); } parse_str($request->query->get('_path', ''), $attributes); $request->attributes->add($attributes); $request->attributes->set('_route_params', array_replace($request->attributes->get('_route_params', []), $attributes)); $request->query->remove('_path'); } protected function validateRequest(Request $request): void { // is the Request safe? if (!$request->isMethodSafe()) { throw new AccessDeniedHttpException(); } // is the Request signed? if ($this->signer->checkRequest($request)) { return; } throw new AccessDeniedHttpException(); } public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => [['onKernelRequest', 48]], ]; } } EventListener/CacheAttributeListener.php 0000644 00000015400 15111167612 0014442 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\Cache; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; /** * Handles HTTP cache headers configured via the Cache attribute. * * @author Fabien Potencier <fabien@symfony.com> */ class CacheAttributeListener implements EventSubscriberInterface { /** * @var \SplObjectStorage<Request, \DateTimeInterface> */ private \SplObjectStorage $lastModified; /** * @var \SplObjectStorage<Request, string> */ private \SplObjectStorage $etags; public function __construct( private ?ExpressionLanguage $expressionLanguage = null, ) { $this->lastModified = new \SplObjectStorage(); $this->etags = new \SplObjectStorage(); } /** * Handles HTTP validation headers. * * @return void */ public function onKernelControllerArguments(ControllerArgumentsEvent $event) { $request = $event->getRequest(); if (!\is_array($attributes = $request->attributes->get('_cache') ?? $event->getAttributes()[Cache::class] ?? null)) { return; } $request->attributes->set('_cache', $attributes); $response = null; $lastModified = null; $etag = null; /** @var Cache[] $attributes */ foreach ($attributes as $cache) { if (null !== $cache->lastModified) { $lastModified = $this->getExpressionLanguage()->evaluate($cache->lastModified, array_merge($request->attributes->all(), $event->getNamedArguments())); ($response ??= new Response())->setLastModified($lastModified); } if (null !== $cache->etag) { $etag = hash('sha256', $this->getExpressionLanguage()->evaluate($cache->etag, array_merge($request->attributes->all(), $event->getNamedArguments()))); ($response ??= new Response())->setEtag($etag); } } if ($response?->isNotModified($request)) { $event->setController(static fn () => $response); $event->stopPropagation(); return; } if (null !== $etag) { $this->etags[$request] = $etag; } if (null !== $lastModified) { $this->lastModified[$request] = $lastModified; } } /** * Modifies the response to apply HTTP cache headers when needed. * * @return void */ public function onKernelResponse(ResponseEvent $event) { $request = $event->getRequest(); /** @var Cache[] $attributes */ if (!\is_array($attributes = $request->attributes->get('_cache'))) { return; } $response = $event->getResponse(); // http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-12#section-3.1 if (!\in_array($response->getStatusCode(), [200, 203, 300, 301, 302, 304, 404, 410])) { unset($this->lastModified[$request]); unset($this->etags[$request]); return; } if (isset($this->lastModified[$request]) && !$response->headers->has('Last-Modified')) { $response->setLastModified($this->lastModified[$request]); } if (isset($this->etags[$request]) && !$response->headers->has('Etag')) { $response->setEtag($this->etags[$request]); } unset($this->lastModified[$request]); unset($this->etags[$request]); $hasVary = $response->headers->has('Vary'); foreach (array_reverse($attributes) as $cache) { if (null !== $cache->smaxage && !$response->headers->hasCacheControlDirective('s-maxage')) { $response->setSharedMaxAge($this->toSeconds($cache->smaxage)); } if ($cache->mustRevalidate) { $response->headers->addCacheControlDirective('must-revalidate'); } if (null !== $cache->maxage && !$response->headers->hasCacheControlDirective('max-age')) { $response->setMaxAge($this->toSeconds($cache->maxage)); } if (null !== $cache->maxStale && !$response->headers->hasCacheControlDirective('max-stale')) { $response->headers->addCacheControlDirective('max-stale', $this->toSeconds($cache->maxStale)); } if (null !== $cache->staleWhileRevalidate && !$response->headers->hasCacheControlDirective('stale-while-revalidate')) { $response->headers->addCacheControlDirective('stale-while-revalidate', $this->toSeconds($cache->staleWhileRevalidate)); } if (null !== $cache->staleIfError && !$response->headers->hasCacheControlDirective('stale-if-error')) { $response->headers->addCacheControlDirective('stale-if-error', $this->toSeconds($cache->staleIfError)); } if (null !== $cache->expires && !$response->headers->has('Expires')) { $response->setExpires(new \DateTimeImmutable('@'.strtotime($cache->expires, time()))); } if (!$hasVary && $cache->vary) { $response->setVary($cache->vary, false); } } foreach ($attributes as $cache) { if (true === $cache->public) { $response->setPublic(); } if (false === $cache->public) { $response->setPrivate(); } } } public static function getSubscribedEvents(): array { return [ KernelEvents::CONTROLLER_ARGUMENTS => ['onKernelControllerArguments', 10], KernelEvents::RESPONSE => ['onKernelResponse', -10], ]; } private function getExpressionLanguage(): ExpressionLanguage { return $this->expressionLanguage ??= class_exists(ExpressionLanguage::class) ? new ExpressionLanguage() : throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".'); } private function toSeconds(int|string $time): int { if (!is_numeric($time)) { $now = time(); $time = strtotime($time, $now) - $now; } return $time; } } EventListener/DebugHandlersListener.php 0000644 00000007526 15111167612 0014274 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleEvent; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\ErrorHandler\ErrorHandler; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\KernelEvents; /** * Sets an exception handler. * * @author Nicolas Grekas <p@tchwork.com> * * @final * * @internal */ class DebugHandlersListener implements EventSubscriberInterface { private string|object|null $earlyHandler; private ?\Closure $exceptionHandler; private bool $firstCall = true; private bool $hasTerminatedWithException = false; /** * @param callable|null $exceptionHandler A handler that must support \Throwable instances that will be called on Exception */ public function __construct(callable $exceptionHandler = null) { $handler = set_exception_handler('is_int'); $this->earlyHandler = \is_array($handler) ? $handler[0] : null; restore_exception_handler(); $this->exceptionHandler = null === $exceptionHandler ? null : $exceptionHandler(...); } /** * Configures the error handler. */ public function configure(object $event = null): void { if ($event instanceof ConsoleEvent && !\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) { return; } if (!$event instanceof KernelEvent ? !$this->firstCall : !$event->isMainRequest()) { return; } $this->firstCall = $this->hasTerminatedWithException = false; if (!$this->exceptionHandler) { if ($event instanceof KernelEvent) { if (method_exists($kernel = $event->getKernel(), 'terminateWithException')) { $request = $event->getRequest(); $hasRun = &$this->hasTerminatedWithException; $this->exceptionHandler = static function (\Throwable $e) use ($kernel, $request, &$hasRun) { if ($hasRun) { throw $e; } $hasRun = true; $kernel->terminateWithException($e, $request); }; } } elseif ($event instanceof ConsoleEvent && $app = $event->getCommand()->getApplication()) { $output = $event->getOutput(); if ($output instanceof ConsoleOutputInterface) { $output = $output->getErrorOutput(); } $this->exceptionHandler = static function (\Throwable $e) use ($app, $output) { $app->renderThrowable($e, $output); }; } } if ($this->exceptionHandler) { $handler = set_exception_handler('is_int'); $handler = \is_array($handler) ? $handler[0] : null; restore_exception_handler(); if (!$handler instanceof ErrorHandler) { $handler = $this->earlyHandler; } if ($handler instanceof ErrorHandler) { $handler->setExceptionHandler($this->exceptionHandler); } $this->exceptionHandler = null; } } public static function getSubscribedEvents(): array { $events = [KernelEvents::REQUEST => ['configure', 2048]]; if (\defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) { $events[ConsoleEvents::COMMAND] = ['configure', 2048]; } return $events; } } EventListener/StreamedResponseListener.php 0000644 00000002561 15111167612 0015042 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; trigger_deprecation('symfony/http-kernel', '6.1', 'The "%s" class is deprecated.', StreamedResponseListener::class); /** * StreamedResponseListener is responsible for sending the Response * to the client. * * @author Fabien Potencier <fabien@symfony.com> * * @final * * @deprecated since Symfony 6.1 */ class StreamedResponseListener implements EventSubscriberInterface { /** * Filters the Response. */ public function onKernelResponse(ResponseEvent $event): void { if (!$event->isMainRequest()) { return; } $response = $event->getResponse(); if ($response instanceof StreamedResponse) { $response->send(); } } public static function getSubscribedEvents(): array { return [ KernelEvents::RESPONSE => ['onKernelResponse', -1024], ]; } } EventListener/AddRequestFormatsListener.php 0000644 00000002260 15111167612 0015150 0 ustar 00 <?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\HttpKernel\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; /** * Adds configured formats to each request. * * @author Gildas Quemener <gildas.quemener@gmail.com> * * @final */ class AddRequestFormatsListener implements EventSubscriberInterface { private array $formats; public function __construct(array $formats) { $this->formats = $formats; } /** * Adds request formats. */ public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); foreach ($this->formats as $format => $mimeTypes) { $request->setFormat($format, $mimeTypes); } } public static function getSubscribedEvents(): array { return [KernelEvents::REQUEST => ['onKernelRequest', 100]]; } } README.md 0000644 00000001244 15111167612 0006025 0 ustar 00 HttpKernel Component ==================== The HttpKernel component provides a structured process for converting a Request into a Response by making use of the EventDispatcher component. It's flexible enough to create full-stack frameworks, micro-frameworks or advanced CMS systems like Drupal. Resources --------- * [Documentation](https://symfony.com/doc/current/components/http_kernel.html) * [Contributing](https://symfony.com/doc/current/contributing/index.html) * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) in the [main Symfony repository](https://github.com/symfony/symfony) LICENSE 0000644 00000002054 15111167612 0005553 0 ustar 00 Copyright (c) 2004-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Profiler/ProfilerStorageInterface.php 0000644 00000002735 15111167612 0013777 0 ustar 00 <?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\HttpKernel\Profiler; /** * ProfilerStorageInterface. * * This interface exists for historical reasons. The only supported * implementation is FileProfilerStorage. * * As the profiler must only be used on non-production servers, the file storage * is more than enough and no other implementations will ever be supported. * * @internal * * @author Fabien Potencier <fabien@symfony.com> */ interface ProfilerStorageInterface { /** * Finds profiler tokens for the given criteria. * * @param int|null $limit The maximum number of tokens to return * @param int|null $start The start date to search from * @param int|null $end The end date to search to */ public function find(?string $ip, ?string $url, ?int $limit, ?string $method, int $start = null, int $end = null): array; /** * Reads data associated with the given token. * * The method returns false if the token does not exist in the storage. */ public function read(string $token): ?Profile; /** * Saves a Profile. */ public function write(Profile $profile): bool; /** * Purges all data from the database. * * @return void */ public function purge(); } Profiler/Profile.php 0000644 00000012024 15111167612 0010437 0 ustar 00 <?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\HttpKernel\Profiler; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; /** * Profile. * * @author Fabien Potencier <fabien@symfony.com> */ class Profile { private string $token; /** * @var DataCollectorInterface[] */ private array $collectors = []; private ?string $ip = null; private ?string $method = null; private ?string $url = null; private ?int $time = null; private ?int $statusCode = null; private ?self $parent = null; /** * @var Profile[] */ private array $children = []; public function __construct(string $token) { $this->token = $token; } /** * @return void */ public function setToken(string $token) { $this->token = $token; } /** * Gets the token. */ public function getToken(): string { return $this->token; } /** * Sets the parent token. * * @return void */ public function setParent(self $parent) { $this->parent = $parent; } /** * Returns the parent profile. */ public function getParent(): ?self { return $this->parent; } /** * Returns the parent token. */ public function getParentToken(): ?string { return $this->parent?->getToken(); } /** * Returns the IP. */ public function getIp(): ?string { return $this->ip; } /** * @return void */ public function setIp(?string $ip) { $this->ip = $ip; } /** * Returns the request method. */ public function getMethod(): ?string { return $this->method; } /** * @return void */ public function setMethod(string $method) { $this->method = $method; } /** * Returns the URL. */ public function getUrl(): ?string { return $this->url; } /** * @return void */ public function setUrl(?string $url) { $this->url = $url; } public function getTime(): int { return $this->time ?? 0; } /** * @return void */ public function setTime(int $time) { $this->time = $time; } /** * @return void */ public function setStatusCode(int $statusCode) { $this->statusCode = $statusCode; } public function getStatusCode(): ?int { return $this->statusCode; } /** * Finds children profilers. * * @return self[] */ public function getChildren(): array { return $this->children; } /** * Sets children profiler. * * @param Profile[] $children * * @return void */ public function setChildren(array $children) { $this->children = []; foreach ($children as $child) { $this->addChild($child); } } /** * Adds the child token. * * @return void */ public function addChild(self $child) { $this->children[] = $child; $child->setParent($this); } public function getChildByToken(string $token): ?self { foreach ($this->children as $child) { if ($token === $child->getToken()) { return $child; } } return null; } /** * Gets a Collector by name. * * @throws \InvalidArgumentException if the collector does not exist */ public function getCollector(string $name): DataCollectorInterface { if (!isset($this->collectors[$name])) { throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); } return $this->collectors[$name]; } /** * Gets the Collectors associated with this profile. * * @return DataCollectorInterface[] */ public function getCollectors(): array { return $this->collectors; } /** * Sets the Collectors associated with this profile. * * @param DataCollectorInterface[] $collectors * * @return void */ public function setCollectors(array $collectors) { $this->collectors = []; foreach ($collectors as $collector) { $this->addCollector($collector); } } /** * Adds a Collector. * * @return void */ public function addCollector(DataCollectorInterface $collector) { $this->collectors[$collector->getName()] = $collector; } public function hasCollector(string $name): bool { return isset($this->collectors[$name]); } public function __sleep(): array { return ['token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time', 'statusCode']; } } Profiler/Profiler.php 0000644 00000015107 15111167612 0010626 0 ustar 00 <?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\HttpKernel\Profiler; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; use Symfony\Contracts\Service\ResetInterface; /** * Profiler. * * @author Fabien Potencier <fabien@symfony.com> */ class Profiler implements ResetInterface { private ProfilerStorageInterface $storage; /** * @var DataCollectorInterface[] */ private array $collectors = []; private ?LoggerInterface $logger; private bool $initiallyEnabled = true; private bool $enabled = true; public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null, bool $enable = true) { $this->storage = $storage; $this->logger = $logger; $this->initiallyEnabled = $this->enabled = $enable; } /** * Disables the profiler. * * @return void */ public function disable() { $this->enabled = false; } /** * Enables the profiler. * * @return void */ public function enable() { $this->enabled = true; } public function isEnabled(): bool { return $this->enabled; } /** * Loads the Profile for the given Response. */ public function loadProfileFromResponse(Response $response): ?Profile { if (!$token = $response->headers->get('X-Debug-Token')) { return null; } return $this->loadProfile($token); } /** * Loads the Profile for the given token. */ public function loadProfile(string $token): ?Profile { return $this->storage->read($token); } /** * Saves a Profile. */ public function saveProfile(Profile $profile): bool { // late collect foreach ($profile->getCollectors() as $collector) { if ($collector instanceof LateDataCollectorInterface) { $collector->lateCollect(); } } if (!($ret = $this->storage->write($profile)) && null !== $this->logger) { $this->logger->warning('Unable to store the profiler information.', ['configured_storage' => $this->storage::class]); } return $ret; } /** * Purges all data from the storage. * * @return void */ public function purge() { $this->storage->purge(); } /** * Finds profiler tokens for the given criteria. * * @param int|null $limit The maximum number of tokens to return * @param string|null $start The start date to search from * @param string|null $end The end date to search to * * @see https://php.net/datetime.formats for the supported date/time formats */ public function find(?string $ip, ?string $url, ?int $limit, ?string $method, ?string $start, ?string $end, string $statusCode = null): array { return $this->storage->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end), $statusCode); } /** * Collects data for the given Response. */ public function collect(Request $request, Response $response, \Throwable $exception = null): ?Profile { if (false === $this->enabled) { return null; } $profile = new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6)); $profile->setTime(time()); $profile->setUrl($request->getUri()); $profile->setMethod($request->getMethod()); $profile->setStatusCode($response->getStatusCode()); try { $profile->setIp($request->getClientIp()); } catch (ConflictingHeadersException) { $profile->setIp('Unknown'); } if ($prevToken = $response->headers->get('X-Debug-Token')) { $response->headers->set('X-Previous-Debug-Token', $prevToken); } $response->headers->set('X-Debug-Token', $profile->getToken()); foreach ($this->collectors as $collector) { $collector->collect($request, $response, $exception); // we need to clone for sub-requests $profile->addCollector(clone $collector); } return $profile; } /** * @return void */ public function reset() { foreach ($this->collectors as $collector) { $collector->reset(); } $this->enabled = $this->initiallyEnabled; } /** * Gets the Collectors associated with this profiler. */ public function all(): array { return $this->collectors; } /** * Sets the Collectors associated with this profiler. * * @param DataCollectorInterface[] $collectors An array of collectors * * @return void */ public function set(array $collectors = []) { $this->collectors = []; foreach ($collectors as $collector) { $this->add($collector); } } /** * Adds a Collector. * * @return void */ public function add(DataCollectorInterface $collector) { $this->collectors[$collector->getName()] = $collector; } /** * Returns true if a Collector for the given name exists. * * @param string $name A collector name */ public function has(string $name): bool { return isset($this->collectors[$name]); } /** * Gets a Collector by name. * * @param string $name A collector name * * @throws \InvalidArgumentException if the collector does not exist */ public function get(string $name): DataCollectorInterface { if (!isset($this->collectors[$name])) { throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); } return $this->collectors[$name]; } private function getTimestamp(?string $value): ?int { if (null === $value || '' === $value) { return null; } try { $value = new \DateTimeImmutable(is_numeric($value) ? '@'.$value : $value); } catch (\Exception) { return null; } return $value->getTimestamp(); } } Profiler/error_log 0000644 00000002670 15111167612 0010251 0 ustar 00 [19-Nov-2025 14:57:44 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php on line 19 [19-Nov-2025 19:18:23 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Contracts\Service\ResetInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/Profiler.php:27 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/Profiler.php on line 27 [19-Nov-2025 23:11:10 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php on line 19 [20-Nov-2025 01:25:31 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Contracts\Service\ResetInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/Profiler.php:27 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Profiler/Profiler.php on line 27 Profiler/FileProfilerStorage.php 0000644 00000023307 15111167612 0012754 0 ustar 00 <?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\HttpKernel\Profiler; /** * Storage for profiler using files. * * @author Alexandre Salomé <alexandre.salome@gmail.com> */ class FileProfilerStorage implements ProfilerStorageInterface { /** * Folder where profiler data are stored. */ private string $folder; /** * Constructs the file storage using a "dsn-like" path. * * Example : "file:/path/to/the/storage/folder" * * @throws \RuntimeException */ public function __construct(string $dsn) { if (!str_starts_with($dsn, 'file:')) { throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn)); } $this->folder = substr($dsn, 5); if (!is_dir($this->folder) && false === @mkdir($this->folder, 0777, true) && !is_dir($this->folder)) { throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $this->folder)); } } public function find(?string $ip, ?string $url, ?int $limit, ?string $method, int $start = null, int $end = null, string $statusCode = null): array { $file = $this->getIndexFilename(); if (!file_exists($file)) { return []; } $file = fopen($file, 'r'); fseek($file, 0, \SEEK_END); $result = []; while (\count($result) < $limit && $line = $this->readLineFromFile($file)) { $values = str_getcsv($line); if (7 !== \count($values)) { // skip invalid lines continue; } [$csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent, $csvStatusCode] = $values; $csvTime = (int) $csvTime; if ($ip && !str_contains($csvIp, $ip) || $url && !str_contains($csvUrl, $url) || $method && !str_contains($csvMethod, $method) || $statusCode && !str_contains($csvStatusCode, $statusCode)) { continue; } if (!empty($start) && $csvTime < $start) { continue; } if (!empty($end) && $csvTime > $end) { continue; } $result[$csvToken] = [ 'token' => $csvToken, 'ip' => $csvIp, 'method' => $csvMethod, 'url' => $csvUrl, 'time' => $csvTime, 'parent' => $csvParent, 'status_code' => $csvStatusCode, ]; } fclose($file); return array_values($result); } /** * @return void */ public function purge() { $flags = \FilesystemIterator::SKIP_DOTS; $iterator = new \RecursiveDirectoryIterator($this->folder, $flags); $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($iterator as $file) { if (is_file($file)) { unlink($file); } else { rmdir($file); } } } public function read(string $token): ?Profile { return $this->doRead($token); } /** * @throws \RuntimeException */ public function write(Profile $profile): bool { $file = $this->getFilename($profile->getToken()); $profileIndexed = is_file($file); if (!$profileIndexed) { // Create directory $dir = \dirname($file); if (!is_dir($dir) && false === @mkdir($dir, 0777, true) && !is_dir($dir)) { throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $dir)); } } $profileToken = $profile->getToken(); // when there are errors in sub-requests, the parent and/or children tokens // may equal the profile token, resulting in infinite loops $parentToken = $profile->getParentToken() !== $profileToken ? $profile->getParentToken() : null; $childrenToken = array_filter(array_map(fn (Profile $p) => $profileToken !== $p->getToken() ? $p->getToken() : null, $profile->getChildren())); // Store profile $data = [ 'token' => $profileToken, 'parent' => $parentToken, 'children' => $childrenToken, 'data' => $profile->getCollectors(), 'ip' => $profile->getIp(), 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime(), 'status_code' => $profile->getStatusCode(), ]; $data = serialize($data); if (\function_exists('gzencode')) { $data = gzencode($data, 3); } if (false === file_put_contents($file, $data, \LOCK_EX)) { return false; } if (!$profileIndexed) { // Add to index if (false === $file = fopen($this->getIndexFilename(), 'a')) { return false; } fputcsv($file, [ $profile->getToken(), $profile->getIp(), $profile->getMethod(), $profile->getUrl(), $profile->getTime() ?: time(), $profile->getParentToken(), $profile->getStatusCode(), ]); fclose($file); if (1 === mt_rand(1, 10)) { $this->removeExpiredProfiles(); } } return true; } /** * Gets filename to store data, associated to the token. */ protected function getFilename(string $token): string { // Uses 4 last characters, because first are mostly the same. $folderA = substr($token, -2, 2); $folderB = substr($token, -4, 2); return $this->folder.'/'.$folderA.'/'.$folderB.'/'.$token; } /** * Gets the index filename. */ protected function getIndexFilename(): string { return $this->folder.'/index.csv'; } /** * Reads a line in the file, backward. * * This function automatically skips the empty lines and do not include the line return in result value. * * @param resource $file The file resource, with the pointer placed at the end of the line to read */ protected function readLineFromFile($file): mixed { $line = ''; $position = ftell($file); if (0 === $position) { return null; } while (true) { $chunkSize = min($position, 1024); $position -= $chunkSize; fseek($file, $position); if (0 === $chunkSize) { // bof reached break; } $buffer = fread($file, $chunkSize); if (false === ($upTo = strrpos($buffer, "\n"))) { $line = $buffer.$line; continue; } $position += $upTo; $line = substr($buffer, $upTo + 1).$line; fseek($file, max(0, $position), \SEEK_SET); if ('' !== $line) { break; } } return '' === $line ? null : $line; } /** * @return Profile */ protected function createProfileFromData(string $token, array $data, Profile $parent = null) { $profile = new Profile($token); $profile->setIp($data['ip']); $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); $profile->setStatusCode($data['status_code']); $profile->setCollectors($data['data']); if (!$parent && $data['parent']) { $parent = $this->read($data['parent']); } if ($parent) { $profile->setParent($parent); } foreach ($data['children'] as $token) { if (null !== $childProfile = $this->doRead($token, $profile)) { $profile->addChild($childProfile); } } return $profile; } private function doRead($token, Profile $profile = null): ?Profile { if (!$token || !file_exists($file = $this->getFilename($token))) { return null; } $h = fopen($file, 'r'); flock($h, \LOCK_SH); $data = stream_get_contents($h); flock($h, \LOCK_UN); fclose($h); if (\function_exists('gzdecode')) { $data = @gzdecode($data) ?: $data; } if (!$data = unserialize($data)) { return null; } return $this->createProfileFromData($token, $data, $profile); } private function removeExpiredProfiles(): void { $minimalProfileTimestamp = time() - 2 * 86400; $file = $this->getIndexFilename(); $handle = fopen($file, 'r'); if ($offset = is_file($file.'.offset') ? (int) file_get_contents($file.'.offset') : 0) { fseek($handle, $offset); } while ($line = fgets($handle)) { $values = str_getcsv($line); if (7 !== \count($values)) { // skip invalid lines $offset += \strlen($line); continue; } [$csvToken, , , , $csvTime] = $values; if ($csvTime >= $minimalProfileTimestamp) { break; } @unlink($this->getFilename($csvToken)); $offset += \strlen($line); } fclose($handle); file_put_contents($file.'.offset', $offset); } } Debug/FileLinkFormatter.php 0000644 00000006620 15111167612 0011671 0 ustar 00 <?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\HttpKernel\Debug; use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; /** * Formats debug file links. * * @author Jérémy Romey <jeremy@free-agent.fr> * * @final */ class FileLinkFormatter { private array|false $fileLinkFormat; private ?RequestStack $requestStack = null; private ?string $baseDir = null; private \Closure|string|null $urlFormat; /** * @param string|\Closure $urlFormat the URL format, or a closure that returns it on-demand */ public function __construct(string|array $fileLinkFormat = null, RequestStack $requestStack = null, string $baseDir = null, string|\Closure $urlFormat = null) { $fileLinkFormat ??= $_ENV['SYMFONY_IDE'] ?? $_SERVER['SYMFONY_IDE'] ?? ''; if (!\is_array($f = $fileLinkFormat)) { $f = (ErrorRendererInterface::IDE_LINK_FORMATS[$f] ?? $f) ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l'; $i = strpos($f, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f); $fileLinkFormat = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, \PREG_SPLIT_DELIM_CAPTURE); } $this->fileLinkFormat = $fileLinkFormat; $this->requestStack = $requestStack; $this->baseDir = $baseDir; $this->urlFormat = $urlFormat; } /** * @return string|false */ public function format(string $file, int $line): string|bool { if ($fmt = $this->getFileLinkFormat()) { for ($i = 1; isset($fmt[$i]); ++$i) { if (str_starts_with($file, $k = $fmt[$i++])) { $file = substr_replace($file, $fmt[$i], 0, \strlen($k)); break; } } return strtr($fmt[0], ['%f' => $file, '%l' => $line]); } return false; } /** * @internal */ public function __sleep(): array { $this->fileLinkFormat = $this->getFileLinkFormat(); return ['fileLinkFormat']; } /** * @internal */ public static function generateUrlFormat(UrlGeneratorInterface $router, string $routeName, string $queryString): ?string { try { return $router->generate($routeName).$queryString; } catch (\Throwable) { return null; } } private function getFileLinkFormat(): array|false { if ($this->fileLinkFormat) { return $this->fileLinkFormat; } if ($this->requestStack && $this->baseDir && $this->urlFormat) { $request = $this->requestStack->getMainRequest(); if ($request instanceof Request && (!$this->urlFormat instanceof \Closure || $this->urlFormat = ($this->urlFormat)())) { return [ $request->getSchemeAndHttpHost().$this->urlFormat, $this->baseDir.\DIRECTORY_SEPARATOR, '', ]; } } return false; } } Debug/TraceableEventDispatcher.php 0000644 00000006576 15111167612 0013215 0 ustar 00 <?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\HttpKernel\Debug; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher as BaseTraceableEventDispatcher; use Symfony\Component\HttpKernel\KernelEvents; /** * Collects some data about event listeners. * * This event dispatcher delegates the dispatching to another one. * * @author Fabien Potencier <fabien@symfony.com> */ class TraceableEventDispatcher extends BaseTraceableEventDispatcher { /** * @return void */ protected function beforeDispatch(string $eventName, object $event) { switch ($eventName) { case KernelEvents::REQUEST: $event->getRequest()->attributes->set('_stopwatch_token', substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6)); $this->stopwatch->openSection(); break; case KernelEvents::VIEW: case KernelEvents::RESPONSE: // stop only if a controller has been executed if ($this->stopwatch->isStarted('controller')) { $this->stopwatch->stop('controller'); } break; case KernelEvents::TERMINATE: $sectionId = $event->getRequest()->attributes->get('_stopwatch_token'); if (null === $sectionId) { break; } // There is a very special case when using built-in AppCache class as kernel wrapper, in the case // of an ESI request leading to a `stale` response [B] inside a `fresh` cached response [A]. // In this case, `$token` contains the [B] debug token, but the open `stopwatch` section ID // is equal to the [A] debug token. Trying to reopen section with the [B] token throws an exception // which must be caught. try { $this->stopwatch->openSection($sectionId); } catch (\LogicException) { } break; } } /** * @return void */ protected function afterDispatch(string $eventName, object $event) { switch ($eventName) { case KernelEvents::CONTROLLER_ARGUMENTS: $this->stopwatch->start('controller', 'section'); break; case KernelEvents::RESPONSE: $sectionId = $event->getRequest()->attributes->get('_stopwatch_token'); if (null === $sectionId) { break; } $this->stopwatch->stopSection($sectionId); break; case KernelEvents::TERMINATE: // In the special case described in the `preDispatch` method above, the `$token` section // does not exist, then closing it throws an exception which must be caught. $sectionId = $event->getRequest()->attributes->get('_stopwatch_token'); if (null === $sectionId) { break; } try { $this->stopwatch->stopSection($sectionId); } catch (\LogicException) { } break; } } } Debug/ErrorHandlerConfigurator.php 0000644 00000007215 15111167612 0013263 0 ustar 00 <?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\HttpKernel\Debug; use Psr\Log\LoggerInterface; use Symfony\Component\ErrorHandler\ErrorHandler; /** * Configures the error handler. * * @final * * @internal */ class ErrorHandlerConfigurator { private ?LoggerInterface $logger; private ?LoggerInterface $deprecationLogger; private array|int|null $levels; private ?int $throwAt; private bool $scream; private bool $scope; /** * @param array|int|null $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants * @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value * @param bool $scream Enables/disables screaming mode, where even silenced errors are logged * @param bool $scope Enables/disables scoping mode */ public function __construct(LoggerInterface $logger = null, array|int|null $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, bool $scope = true, LoggerInterface $deprecationLogger = null) { $this->logger = $logger; $this->levels = $levels ?? \E_ALL; $this->throwAt = \is_int($throwAt) ? $throwAt : (null === $throwAt ? null : ($throwAt ? \E_ALL : null)); $this->scream = $scream; $this->scope = $scope; $this->deprecationLogger = $deprecationLogger; } /** * Configures the error handler. */ public function configure(ErrorHandler $handler): void { if ($this->logger || $this->deprecationLogger) { $this->setDefaultLoggers($handler); if (\is_array($this->levels)) { $levels = 0; foreach ($this->levels as $type => $log) { $levels |= $type; } } else { $levels = $this->levels; } if ($this->scream) { $handler->screamAt($levels); } if ($this->scope) { $handler->scopeAt($levels & ~\E_USER_DEPRECATED & ~\E_DEPRECATED); } else { $handler->scopeAt(0, true); } $this->logger = $this->deprecationLogger = $this->levels = null; } if (null !== $this->throwAt) { $handler->throwAt($this->throwAt, true); } } private function setDefaultLoggers(ErrorHandler $handler): void { if (\is_array($this->levels)) { $levelsDeprecatedOnly = []; $levelsWithoutDeprecated = []; foreach ($this->levels as $type => $log) { if (\E_DEPRECATED == $type || \E_USER_DEPRECATED == $type) { $levelsDeprecatedOnly[$type] = $log; } else { $levelsWithoutDeprecated[$type] = $log; } } } else { $levelsDeprecatedOnly = $this->levels & (\E_DEPRECATED | \E_USER_DEPRECATED); $levelsWithoutDeprecated = $this->levels & ~\E_DEPRECATED & ~\E_USER_DEPRECATED; } $defaultLoggerLevels = $this->levels; if ($this->deprecationLogger && $levelsDeprecatedOnly) { $handler->setDefaultLogger($this->deprecationLogger, $levelsDeprecatedOnly); $defaultLoggerLevels = $levelsWithoutDeprecated; } if ($this->logger && $defaultLoggerLevels) { $handler->setDefaultLogger($this->logger, $defaultLoggerLevels); } } } Exception/NotAcceptableHttpException.php 0000644 00000001131 15111167612 0014433 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class NotAcceptableHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(406, $message, $previous, $headers, $code); } } Exception/LockedHttpException.php 0000644 00000001126 15111167612 0013134 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Peter Dietrich <xosofox@gmail.com> */ class LockedHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(423, $message, $previous, $headers, $code); } } Exception/ServiceUnavailableHttpException.php 0000644 00000001532 15111167612 0015500 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class ServiceUnavailableHttpException extends HttpException { /** * @param int|string|null $retryAfter The number of seconds or HTTP-date after which the request may be retried */ public function __construct(int|string $retryAfter = null, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { if ($retryAfter) { $headers['Retry-After'] = $retryAfter; } parent::__construct(503, $message, $previous, $headers, $code); } } Exception/UnprocessableEntityHttpException.php 0000644 00000001150 15111167612 0015732 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Steve Hutchins <hutchinsteve@gmail.com> */ class UnprocessableEntityHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(422, $message, $previous, $headers, $code); } } Exception/InvalidMetadataException.php 0000644 00000000534 15111167612 0014124 0 ustar 00 <?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\HttpKernel\Exception; class InvalidMetadataException extends \LogicException { } Exception/NotFoundHttpException.php 0000644 00000001133 15111167612 0013465 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Fabien Potencier <fabien@symfony.com> */ class NotFoundHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(404, $message, $previous, $headers, $code); } } Exception/MethodNotAllowedHttpException.php 0000644 00000001367 15111167612 0015153 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Kris Wallsmith <kris@symfony.com> */ class MethodNotAllowedHttpException extends HttpException { /** * @param string[] $allow An array of allowed methods */ public function __construct(array $allow, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { $headers['Allow'] = strtoupper(implode(', ', $allow)); parent::__construct(405, $message, $previous, $headers, $code); } } Exception/LengthRequiredHttpException.php 0000644 00000001132 15111167612 0014652 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class LengthRequiredHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(411, $message, $previous, $headers, $code); } } Exception/HttpException.php 0000644 00000002102 15111167612 0012005 0 ustar 00 <?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\HttpKernel\Exception; /** * HttpException. * * @author Kris Wallsmith <kris@symfony.com> */ class HttpException extends \RuntimeException implements HttpExceptionInterface { private int $statusCode; private array $headers; public function __construct(int $statusCode, string $message = '', \Throwable $previous = null, array $headers = [], int $code = 0) { $this->statusCode = $statusCode; $this->headers = $headers; parent::__construct($message, $code, $previous); } public function getStatusCode(): int { return $this->statusCode; } public function getHeaders(): array { return $this->headers; } /** * @return void */ public function setHeaders(array $headers) { $this->headers = $headers; } } Exception/BadRequestHttpException.php 0000644 00000001126 15111167612 0013772 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class BadRequestHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(400, $message, $previous, $headers, $code); } } Exception/AccessDeniedHttpException.php 0000644 00000001215 15111167612 0014244 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Fabien Potencier <fabien@symfony.com> * @author Christophe Coevoet <stof@notk.org> */ class AccessDeniedHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(403, $message, $previous, $headers, $code); } } Exception/UnexpectedSessionUsageException.php 0000644 00000000640 15111167612 0015530 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Mathias Arlaud <mathias.arlaud@gmail.com> */ class UnexpectedSessionUsageException extends \LogicException { } Exception/PreconditionFailedHttpException.php 0000644 00000001136 15111167612 0015476 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class PreconditionFailedHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(412, $message, $previous, $headers, $code); } } Exception/ConflictHttpException.php 0000644 00000001124 15111167612 0013472 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class ConflictHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(409, $message, $previous, $headers, $code); } } Exception/error_log 0000644 00000024414 15111167612 0010425 0 ustar 00 [19-Nov-2025 14:36:42 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php on line 17 [19-Nov-2025 14:39:30 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php:18 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php on line 18 [19-Nov-2025 14:44:41 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php on line 17 [19-Nov-2025 14:51:41 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ConflictHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ConflictHttpException.php on line 17 [19-Nov-2025 14:53:39 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php on line 17 [19-Nov-2025 14:55:41 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/LockedHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/LockedHttpException.php on line 17 [19-Nov-2025 14:59:46 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php on line 17 [19-Nov-2025 15:01:53 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/PreconditionFailedHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/PreconditionFailedHttpException.php on line 17 [19-Nov-2025 15:02:51 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php on line 17 [19-Nov-2025 15:05:55 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php on line 19 [19-Nov-2025 15:07:58 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/GoneHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/GoneHttpException.php on line 17 [19-Nov-2025 15:08:53 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php on line 17 [19-Nov-2025 15:13:53 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/LengthRequiredHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/LengthRequiredHttpException.php on line 17 [19-Nov-2025 15:18:10 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/NotAcceptableHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/NotAcceptableHttpException.php on line 17 [19-Nov-2025 15:20:14 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php on line 19 [19-Nov-2025 15:26:22 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php on line 17 [19-Nov-2025 15:30:30 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Exception\HttpExceptionInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/HttpException.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/HttpException.php on line 19 [19-Nov-2025 22:56:50 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php:18 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php on line 18 [19-Nov-2025 22:56:57 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/NotFoundHttpException.php on line 17 [19-Nov-2025 22:59:54 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php on line 17 [19-Nov-2025 23:03:14 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/BadRequestHttpException.php on line 17 [19-Nov-2025 23:08:11 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ConflictHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ConflictHttpException.php on line 17 [19-Nov-2025 23:14:25 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php on line 17 [19-Nov-2025 23:15:27 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/LockedHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/LockedHttpException.php on line 17 [19-Nov-2025 23:34:04 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Exception\HttpExceptionInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/HttpException.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/HttpException.php on line 19 [19-Nov-2025 23:38:01 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php:17 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php on line 17 [19-Nov-2025 23:38:45 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Exception\HttpException" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php on line 19 Exception/GoneHttpException.php 0000644 00000001120 15111167612 0012615 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class GoneHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(410, $message, $previous, $headers, $code); } } Exception/ControllerDoesNotReturnResponseException.php 0000644 00000004363 15111167612 0017437 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Grégoire Pineau <lyrixx@lyrixx.info> */ class ControllerDoesNotReturnResponseException extends \LogicException { public function __construct(string $message, callable $controller, string $file, int $line) { parent::__construct($message); if (!$controllerDefinition = $this->parseControllerDefinition($controller)) { return; } $this->file = $controllerDefinition['file']; $this->line = $controllerDefinition['line']; $r = new \ReflectionProperty(\Exception::class, 'trace'); $r->setValue($this, array_merge([ [ 'line' => $line, 'file' => $file, ], ], $this->getTrace())); } private function parseControllerDefinition(callable $controller): ?array { if (\is_string($controller) && str_contains($controller, '::')) { $controller = explode('::', $controller); } if (\is_array($controller)) { try { $r = new \ReflectionMethod($controller[0], $controller[1]); return [ 'file' => $r->getFileName(), 'line' => $r->getEndLine(), ]; } catch (\ReflectionException) { return null; } } if ($controller instanceof \Closure) { $r = new \ReflectionFunction($controller); return [ 'file' => $r->getFileName(), 'line' => $r->getEndLine(), ]; } if (\is_object($controller)) { $r = new \ReflectionClass($controller); try { $line = $r->getMethod('__invoke')->getEndLine(); } catch (\ReflectionException) { $line = $r->getEndLine(); } return [ 'file' => $r->getFileName(), 'line' => $line, ]; } return null; } } Exception/PreconditionRequiredHttpException.php 0000644 00000001216 15111167612 0016071 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> * * @see http://tools.ietf.org/html/rfc6585 */ class PreconditionRequiredHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(428, $message, $previous, $headers, $code); } } Exception/UnauthorizedHttpException.php 0000644 00000001361 15111167612 0014415 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class UnauthorizedHttpException extends HttpException { /** * @param string $challenge WWW-Authenticate challenge string */ public function __construct(string $challenge, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { $headers['WWW-Authenticate'] = $challenge; parent::__construct(401, $message, $previous, $headers, $code); } } Exception/ResolverNotFoundException.php 0000644 00000001573 15111167612 0014357 0 ustar 00 <?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\HttpKernel\Exception; class ResolverNotFoundException extends \RuntimeException { /** * @param string[] $alternatives */ public function __construct(string $name, array $alternatives = []) { $msg = sprintf('You have requested a non-existent resolver "%s".', $name); if ($alternatives) { if (1 === \count($alternatives)) { $msg .= ' Did you mean this: "'; } else { $msg .= ' Did you mean one of these: "'; } $msg .= implode('", "', $alternatives).'"?'; } parent::__construct($msg); } } Exception/TooManyRequestsHttpException.php 0000644 00000001605 15111167612 0015057 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> * * @see http://tools.ietf.org/html/rfc6585 */ class TooManyRequestsHttpException extends HttpException { /** * @param int|string|null $retryAfter The number of seconds or HTTP-date after which the request may be retried */ public function __construct(int|string $retryAfter = null, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { if ($retryAfter) { $headers['Retry-After'] = $retryAfter; } parent::__construct(429, $message, $previous, $headers, $code); } } Exception/UnsupportedMediaTypeHttpException.php 0000644 00000001140 15111167612 0016061 0 ustar 00 <?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\HttpKernel\Exception; /** * @author Ben Ramsey <ben@benramsey.com> */ class UnsupportedMediaTypeHttpException extends HttpException { public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(415, $message, $previous, $headers, $code); } } Exception/HttpExceptionInterface.php 0000644 00000001156 15111167612 0013636 0 ustar 00 <?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\HttpKernel\Exception; /** * Interface for HTTP error exceptions. * * @author Kris Wallsmith <kris@symfony.com> */ interface HttpExceptionInterface extends \Throwable { /** * Returns the status code. */ public function getStatusCode(): int; /** * Returns response headers. */ public function getHeaders(): array; } Attribute/AsController.php 0000644 00000000703 15111167612 0011630 0 ustar 00 <?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\HttpKernel\Attribute; /** * Service tag to autoconfigure controllers. */ #[\Attribute(\Attribute::TARGET_CLASS)] class AsController { public function __construct() { } } Attribute/ValueResolver.php 0000644 00000001221 15111167612 0012013 0 ustar 00 <?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\HttpKernel\Attribute; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; #[\Attribute(\Attribute::TARGET_PARAMETER | \Attribute::IS_REPEATABLE)] class ValueResolver { /** * @param class-string<ValueResolverInterface>|string $resolver */ public function __construct( public string $resolver, public bool $disabled = false, ) { } } Attribute/WithLogLevel.php 0000644 00000001355 15111167612 0011572 0 ustar 00 <?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\HttpKernel\Attribute; use Psr\Log\LogLevel; /** * @author Dejan Angelov <angelovdejan@protonmail.com> */ #[\Attribute(\Attribute::TARGET_CLASS)] final class WithLogLevel { /** * @param LogLevel::* $level */ public function __construct(public readonly string $level) { if (!\defined('Psr\Log\LogLevel::'.strtoupper($this->level))) { throw new \InvalidArgumentException(sprintf('Invalid log level "%s".', $this->level)); } } } Attribute/MapDateTime.php 0000644 00000001376 15111167612 0011362 0 ustar 00 <?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\HttpKernel\Attribute; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DateTimeValueResolver; /** * Controller parameter tag to configure DateTime arguments. */ #[\Attribute(\Attribute::TARGET_PARAMETER)] class MapDateTime extends ValueResolver { public function __construct( public readonly ?string $format = null, bool $disabled = false, string $resolver = DateTimeValueResolver::class, ) { parent::__construct($resolver, $disabled); } } Attribute/WithHttpStatus.php 0000644 00000001143 15111167612 0012177 0 ustar 00 <?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\HttpKernel\Attribute; /** * @author Dejan Angelov <angelovdejan@protonmail.com> */ #[\Attribute(\Attribute::TARGET_CLASS)] class WithHttpStatus { /** * @param array<string, string> $headers */ public function __construct( public readonly int $statusCode, public readonly array $headers = [], ) { } } Attribute/MapQueryParameter.php 0000644 00000002153 15111167612 0012626 0 ustar 00 <?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\HttpKernel\Attribute; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\QueryParameterValueResolver; /** * Can be used to pass a query parameter to a controller argument. * * @author Ruud Kamphuis <ruud@ticketswap.com> */ #[\Attribute(\Attribute::TARGET_PARAMETER)] final class MapQueryParameter extends ValueResolver { /** * @see https://php.net/filter.filters.validate for filter, flags and options * * @param string|null $name The name of the query parameter. If null, the name of the argument in the controller will be used. */ public function __construct( public ?string $name = null, public ?int $filter = null, public int $flags = 0, public array $options = [], string $resolver = QueryParameterValueResolver::class, ) { parent::__construct($resolver); } } Attribute/error_log 0000644 00000010472 15111167612 0010431 0 ustar 00 [19-Nov-2025 15:58:41 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php on line 22 [19-Nov-2025 16:00:48 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php on line 24 [19-Nov-2025 16:06:32 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryString.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryString.php on line 24 [19-Nov-2025 16:11:44 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapDateTime.php:20 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapDateTime.php on line 20 [19-Nov-2025 17:31:35 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapDateTime.php:20 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapDateTime.php on line 20 [19-Nov-2025 17:32:39 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php on line 24 [19-Nov-2025 17:37:51 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php on line 22 [19-Nov-2025 17:42:05 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryString.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryString.php on line 24 [19-Nov-2025 22:56:52 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php on line 24 [19-Nov-2025 23:29:53 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php on line 22 [19-Nov-2025 23:30:59 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapDateTime.php:20 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapDateTime.php on line 20 [19-Nov-2025 23:46:26 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Attribute\ValueResolver" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryString.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Attribute/MapQueryString.php on line 24 Attribute/Cache.php 0000644 00000004511 15111167612 0010225 0 ustar 00 <?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\HttpKernel\Attribute; /** * Describes the default HTTP cache headers on controllers. * * @author Fabien Potencier <fabien@symfony.com> */ #[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_FUNCTION)] final class Cache { public function __construct( /** * The expiration date as a valid date for the strtotime() function. */ public ?string $expires = null, /** * The number of seconds that the response is considered fresh by a private * cache like a web browser. */ public int|string|null $maxage = null, /** * The number of seconds that the response is considered fresh by a public * cache like a reverse proxy cache. */ public int|string|null $smaxage = null, /** * Whether the response is public or not. */ public ?bool $public = null, /** * Whether or not the response must be revalidated. */ public bool $mustRevalidate = false, /** * Additional "Vary:"-headers. */ public array $vary = [], /** * An expression to compute the Last-Modified HTTP header. */ public ?string $lastModified = null, /** * An expression to compute the ETag HTTP header. */ public ?string $etag = null, /** * max-stale Cache-Control header * It can be expressed in seconds or with a relative time format (1 day, 2 weeks, ...). */ public int|string|null $maxStale = null, /** * stale-while-revalidate Cache-Control header * It can be expressed in seconds or with a relative time format (1 day, 2 weeks, ...). */ public int|string|null $staleWhileRevalidate = null, /** * stale-if-error Cache-Control header * It can be expressed in seconds or with a relative time format (1 day, 2 weeks, ...). */ public int|string|null $staleIfError = null, ) { } } Attribute/MapRequestPayload.php 0000644 00000002176 15111167612 0012627 0 ustar 00 <?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\HttpKernel\Attribute; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\Validator\Constraints\GroupSequence; /** * Controller parameter tag to map the request content to typed object and validate it. * * @author Konstantin Myakshin <molodchick@gmail.com> */ #[\Attribute(\Attribute::TARGET_PARAMETER)] class MapRequestPayload extends ValueResolver { public ArgumentMetadata $metadata; public function __construct( public readonly array|string|null $acceptFormat = null, public readonly array $serializationContext = [], public readonly string|GroupSequence|array|null $validationGroups = null, string $resolver = RequestPayloadValueResolver::class, ) { parent::__construct($resolver); } } Attribute/AsTargetedValueResolver.php 0000644 00000001012 15111167612 0013755 0 ustar 00 <?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\HttpKernel\Attribute; /** * Service tag to autoconfigure targeted value resolvers. */ #[\Attribute(\Attribute::TARGET_CLASS)] class AsTargetedValueResolver { public function __construct( public readonly ?string $name = null, ) { } } Attribute/MapQueryString.php 0000644 00000002107 15111167612 0012153 0 ustar 00 <?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\HttpKernel\Attribute; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\Validator\Constraints\GroupSequence; /** * Controller parameter tag to map the query string of the request to typed object and validate it. * * @author Konstantin Myakshin <molodchick@gmail.com> */ #[\Attribute(\Attribute::TARGET_PARAMETER)] class MapQueryString extends ValueResolver { public ArgumentMetadata $metadata; public function __construct( public readonly array $serializationContext = [], public readonly string|GroupSequence|array|null $validationGroups = null, string $resolver = RequestPayloadValueResolver::class, ) { parent::__construct($resolver); } } composer.json 0000644 00000005174 15111167612 0007276 0 ustar 00 { "name": "symfony/http-kernel", "type": "library", "description": "Provides a structured process for converting a Request into a Response", "keywords": [], "homepage": "https://symfony.com", "license": "MIT", "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "require": { "php": ">=8.1", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.3", "symfony/event-dispatcher": "^5.4|^6.0", "symfony/http-foundation": "^6.3.4", "symfony/polyfill-ctype": "^1.8", "psr/log": "^1|^2|^3" }, "require-dev": { "symfony/browser-kit": "^5.4|^6.0", "symfony/clock": "^6.2", "symfony/config": "^6.1", "symfony/console": "^5.4|^6.0", "symfony/css-selector": "^5.4|^6.0", "symfony/dependency-injection": "^6.3.4", "symfony/dom-crawler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/finder": "^5.4|^6.0", "symfony/http-client-contracts": "^2.5|^3", "symfony/process": "^5.4|^6.0", "symfony/property-access": "^5.4.5|^6.0.5", "symfony/routing": "^5.4|^6.0", "symfony/serializer": "^6.3", "symfony/stopwatch": "^5.4|^6.0", "symfony/translation": "^5.4|^6.0", "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^5.4|^6.0", "symfony/validator": "^6.3", "symfony/var-exporter": "^6.2", "psr/cache": "^1.0|^2.0|^3.0", "twig/twig": "^2.13|^3.0.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "conflict": { "symfony/browser-kit": "<5.4", "symfony/cache": "<5.4", "symfony/config": "<6.1", "symfony/console": "<5.4", "symfony/form": "<5.4", "symfony/dependency-injection": "<6.3.4", "symfony/doctrine-bridge": "<5.4", "symfony/http-client": "<5.4", "symfony/http-client-contracts": "<2.5", "symfony/mailer": "<5.4", "symfony/messenger": "<5.4", "symfony/translation": "<5.4", "symfony/translation-contracts": "<2.5", "symfony/twig-bridge": "<5.4", "symfony/validator": "<5.4", "symfony/var-dumper": "<6.3", "twig/twig": "<2.13" }, "autoload": { "psr-4": { "Symfony\\Component\\HttpKernel\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "minimum-stability": "dev" } DataCollector/DataCollectorInterface.php 0000644 00000001600 15111167612 0014334 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Contracts\Service\ResetInterface; /** * DataCollectorInterface. * * @author Fabien Potencier <fabien@symfony.com> */ interface DataCollectorInterface extends ResetInterface { /** * Collects data for the given Request and Response. * * @return void */ public function collect(Request $request, Response $response, \Throwable $exception = null); /** * Returns the name of the collector. * * @return string */ public function getName(); } DataCollector/TimeDataCollector.php 0000644 00000006556 15111167612 0013351 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\Stopwatch\StopwatchEvent; /** * @author Fabien Potencier <fabien@symfony.com> * * @final */ class TimeDataCollector extends DataCollector implements LateDataCollectorInterface { private ?KernelInterface $kernel; private ?Stopwatch $stopwatch; public function __construct(KernelInterface $kernel = null, Stopwatch $stopwatch = null) { $this->kernel = $kernel; $this->stopwatch = $stopwatch; $this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0]; } public function collect(Request $request, Response $response, \Throwable $exception = null): void { if (null !== $this->kernel) { $startTime = $this->kernel->getStartTime(); } else { $startTime = $request->server->get('REQUEST_TIME_FLOAT'); } $this->data = [ 'token' => $request->attributes->get('_stopwatch_token'), 'start_time' => $startTime * 1000, 'events' => [], 'stopwatch_installed' => class_exists(Stopwatch::class, false), ]; } public function reset(): void { $this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0]; $this->stopwatch?->reset(); } public function lateCollect(): void { if (null !== $this->stopwatch && isset($this->data['token'])) { $this->setEvents($this->stopwatch->getSectionEvents($this->data['token'])); } unset($this->data['token']); } /** * @param StopwatchEvent[] $events The request events */ public function setEvents(array $events): void { foreach ($events as $event) { $event->ensureStopped(); } $this->data['events'] = $events; } /** * @return StopwatchEvent[] */ public function getEvents(): array { return $this->data['events']; } /** * Gets the request elapsed time. */ public function getDuration(): float { if (!isset($this->data['events']['__section__'])) { return 0; } $lastEvent = $this->data['events']['__section__']; return $lastEvent->getOrigin() + $lastEvent->getDuration() - $this->getStartTime(); } /** * Gets the initialization time. * * This is the time spent until the beginning of the request handling. */ public function getInitTime(): float { if (!isset($this->data['events']['__section__'])) { return 0; } return $this->data['events']['__section__']->getOrigin() - $this->getStartTime(); } public function getStartTime(): float { return $this->data['start_time']; } public function isStopwatchInstalled(): bool { return $this->data['stopwatch_installed']; } public function getName(): string { return 'time'; } } DataCollector/ConfigDataCollector.php 0000644 00000016271 15111167612 0013653 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\VarDumper\Caster\ClassStub; /** * @author Fabien Potencier <fabien@symfony.com> * * @final */ class ConfigDataCollector extends DataCollector implements LateDataCollectorInterface { private KernelInterface $kernel; /** * Sets the Kernel associated with this Request. */ public function setKernel(KernelInterface $kernel = null): void { if (1 > \func_num_args()) { trigger_deprecation('symfony/http-kernel', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); } $this->kernel = $kernel; } public function collect(Request $request, Response $response, \Throwable $exception = null): void { $eom = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE); $eol = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE); $this->data = [ 'token' => $response->headers->get('X-Debug-Token'), 'symfony_version' => Kernel::VERSION, 'symfony_minor_version' => sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION), 'symfony_lts' => 4 === Kernel::MINOR_VERSION, 'symfony_state' => $this->determineSymfonyState(), 'symfony_eom' => $eom->format('F Y'), 'symfony_eol' => $eol->format('F Y'), 'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a', 'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a', 'php_version' => \PHP_VERSION, 'php_architecture' => \PHP_INT_SIZE * 8, 'php_intl_locale' => class_exists(\Locale::class, false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a', 'php_timezone' => date_default_timezone_get(), 'xdebug_enabled' => \extension_loaded('xdebug'), 'apcu_enabled' => \extension_loaded('apcu') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOL), 'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL), 'bundles' => [], 'sapi_name' => \PHP_SAPI, ]; if (isset($this->kernel)) { foreach ($this->kernel->getBundles() as $name => $bundle) { $this->data['bundles'][$name] = new ClassStub($bundle::class); } } if (preg_match('~^(\d+(?:\.\d+)*)(.+)?$~', $this->data['php_version'], $matches) && isset($matches[2])) { $this->data['php_version'] = $matches[1]; $this->data['php_version_extra'] = $matches[2]; } } public function reset(): void { $this->data = []; } public function lateCollect(): void { $this->data = $this->cloneVar($this->data); } /** * Gets the token. */ public function getToken(): ?string { return $this->data['token']; } /** * Gets the Symfony version. */ public function getSymfonyVersion(): string { return $this->data['symfony_version']; } /** * Returns the state of the current Symfony release * as one of: unknown, dev, stable, eom, eol. */ public function getSymfonyState(): string { return $this->data['symfony_state']; } /** * Returns the minor Symfony version used (without patch numbers of extra * suffix like "RC", "beta", etc.). */ public function getSymfonyMinorVersion(): string { return $this->data['symfony_minor_version']; } public function isSymfonyLts(): bool { return $this->data['symfony_lts']; } /** * Returns the human readable date when this Symfony version ends its * maintenance period. */ public function getSymfonyEom(): string { return $this->data['symfony_eom']; } /** * Returns the human readable date when this Symfony version reaches its * "end of life" and won't receive bugs or security fixes. */ public function getSymfonyEol(): string { return $this->data['symfony_eol']; } /** * Gets the PHP version. */ public function getPhpVersion(): string { return $this->data['php_version']; } /** * Gets the PHP version extra part. */ public function getPhpVersionExtra(): ?string { return $this->data['php_version_extra'] ?? null; } public function getPhpArchitecture(): int { return $this->data['php_architecture']; } public function getPhpIntlLocale(): string { return $this->data['php_intl_locale']; } public function getPhpTimezone(): string { return $this->data['php_timezone']; } /** * Gets the environment. */ public function getEnv(): string { return $this->data['env']; } /** * Returns true if the debug is enabled. * * @return bool|string true if debug is enabled, false otherwise or a string if no kernel was set */ public function isDebug(): bool|string { return $this->data['debug']; } /** * Returns true if the Xdebug is enabled. */ public function hasXdebug(): bool { return $this->data['xdebug_enabled']; } /** * Returns true if the function xdebug_info is available. */ public function hasXdebugInfo(): bool { return \function_exists('xdebug_info'); } /** * Returns true if APCu is enabled. */ public function hasApcu(): bool { return $this->data['apcu_enabled']; } /** * Returns true if Zend OPcache is enabled. */ public function hasZendOpcache(): bool { return $this->data['zend_opcache_enabled']; } public function getBundles() { return $this->data['bundles']; } /** * Gets the PHP SAPI name. */ public function getSapiName(): string { return $this->data['sapi_name']; } public function getName(): string { return 'config'; } private function determineSymfonyState(): string { $now = new \DateTimeImmutable(); $eom = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE)->modify('last day of this month'); $eol = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE)->modify('last day of this month'); if ($now > $eol) { $versionState = 'eol'; } elseif ($now > $eom) { $versionState = 'eom'; } elseif ('' !== Kernel::EXTRA_VERSION) { $versionState = 'dev'; } else { $versionState = 'stable'; } return $versionState; } } DataCollector/EventDataCollector.php 0000644 00000010422 15111167612 0013517 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Service\ResetInterface; /** * @author Fabien Potencier <fabien@symfony.com> * * @see TraceableEventDispatcher * * @final */ class EventDataCollector extends DataCollector implements LateDataCollectorInterface { /** @var iterable<EventDispatcherInterface> */ private iterable $dispatchers; private ?Request $currentRequest = null; /** * @param iterable<EventDispatcherInterface>|EventDispatcherInterface|null $dispatchers */ public function __construct( iterable|EventDispatcherInterface $dispatchers = null, private ?RequestStack $requestStack = null, private string $defaultDispatcher = 'event_dispatcher', ) { if ($dispatchers instanceof EventDispatcherInterface) { $dispatchers = [$this->defaultDispatcher => $dispatchers]; } $this->dispatchers = $dispatchers ?? []; $this->requestStack = $requestStack; } public function collect(Request $request, Response $response, \Throwable $exception = null): void { $this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null; $this->data = []; } public function reset(): void { $this->data = []; foreach ($this->dispatchers as $dispatcher) { if ($dispatcher instanceof ResetInterface) { $dispatcher->reset(); } } } public function lateCollect(): void { foreach ($this->dispatchers as $name => $dispatcher) { if (!$dispatcher instanceof TraceableEventDispatcher) { continue; } $this->setCalledListeners($dispatcher->getCalledListeners($this->currentRequest), $name); $this->setNotCalledListeners($dispatcher->getNotCalledListeners($this->currentRequest), $name); $this->setOrphanedEvents($dispatcher->getOrphanedEvents($this->currentRequest), $name); } $this->data = $this->cloneVar($this->data); } public function getData(): array|Data { return $this->data; } /** * @see TraceableEventDispatcher */ public function setCalledListeners(array $listeners, string $dispatcher = null): void { $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] = $listeners; } /** * @see TraceableEventDispatcher */ public function getCalledListeners(string $dispatcher = null): array|Data { return $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] ?? []; } /** * @see TraceableEventDispatcher */ public function setNotCalledListeners(array $listeners, string $dispatcher = null): void { $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] = $listeners; } /** * @see TraceableEventDispatcher */ public function getNotCalledListeners(string $dispatcher = null): array|Data { return $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] ?? []; } /** * @param array $events An array of orphaned events * * @see TraceableEventDispatcher */ public function setOrphanedEvents(array $events, string $dispatcher = null): void { $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] = $events; } /** * @see TraceableEventDispatcher */ public function getOrphanedEvents(string $dispatcher = null): array|Data { return $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] ?? []; } public function getName(): string { return 'events'; } } DataCollector/RouterDataCollector.php 0000644 00000004551 15111167612 0013724 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ControllerEvent; /** * @author Fabien Potencier <fabien@symfony.com> */ class RouterDataCollector extends DataCollector { /** * @var \SplObjectStorage<Request, callable> */ protected $controllers; public function __construct() { $this->reset(); } /** * @final */ public function collect(Request $request, Response $response, \Throwable $exception = null): void { if ($response instanceof RedirectResponse) { $this->data['redirect'] = true; $this->data['url'] = $response->getTargetUrl(); if ($this->controllers->contains($request)) { $this->data['route'] = $this->guessRoute($request, $this->controllers[$request]); } } unset($this->controllers[$request]); } /** * @return void */ public function reset() { $this->controllers = new \SplObjectStorage(); $this->data = [ 'redirect' => false, 'url' => null, 'route' => null, ]; } /** * @return string */ protected function guessRoute(Request $request, string|object|array $controller) { return 'n/a'; } /** * Remembers the controller associated to each request. * * @return void */ public function onKernelController(ControllerEvent $event) { $this->controllers[$event->getRequest()] = $event->getController(); } /** * @return bool Whether this request will result in a redirect */ public function getRedirect(): bool { return $this->data['redirect']; } public function getTargetUrl(): ?string { return $this->data['url']; } public function getTargetRoute(): ?string { return $this->data['route']; } public function getName(): string { return 'router'; } } DataCollector/error_log 0000644 00000017104 15111167612 0011205 0 ustar 00 [19-Nov-2025 12:04:28 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php:32 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php on line 32 [19-Nov-2025 12:04:30 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php on line 25 [19-Nov-2025 12:04:38 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php on line 25 [19-Nov-2025 12:05:01 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php on line 22 [19-Nov-2025 12:06:04 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php on line 25 [19-Nov-2025 12:07:06 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php on line 22 [19-Nov-2025 12:08:10 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php:32 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php on line 32 [19-Nov-2025 12:11:20 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php:29 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php on line 29 [19-Nov-2025 12:15:26 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php on line 22 [19-Nov-2025 12:21:46 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php on line 23 [19-Nov-2025 18:07:10 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php:32 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php on line 32 [19-Nov-2025 18:07:40 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php on line 25 [19-Nov-2025 18:07:46 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php on line 25 [19-Nov-2025 18:08:02 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php on line 22 [19-Nov-2025 18:09:59 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php on line 25 [19-Nov-2025 18:11:16 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php:32 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php on line 32 [19-Nov-2025 18:15:00 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php:29 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php on line 29 [19-Nov-2025 18:17:36 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php on line 22 [19-Nov-2025 18:20:02 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php on line 22 [19-Nov-2025 18:21:33 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DataCollector\DataCollector" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php on line 23 DataCollector/DumpDataCollector.php 0000644 00000025373 15111167612 0013356 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; use Symfony\Component\VarDumper\Dumper\DataDumperInterface; use Symfony\Component\VarDumper\Dumper\HtmlDumper; use Symfony\Component\VarDumper\Server\Connection; /** * @author Nicolas Grekas <p@tchwork.com> * * @final */ class DumpDataCollector extends DataCollector implements DataDumperInterface { private ?Stopwatch $stopwatch = null; private string|FileLinkFormatter|false $fileLinkFormat; private int $dataCount = 0; private bool $isCollected = true; private int $clonesCount = 0; private int $clonesIndex = 0; private array $rootRefs; private string $charset; private ?RequestStack $requestStack; private DataDumperInterface|Connection|null $dumper; private mixed $sourceContextProvider; public function __construct(Stopwatch $stopwatch = null, string|FileLinkFormatter $fileLinkFormat = null, string $charset = null, RequestStack $requestStack = null, DataDumperInterface|Connection $dumper = null) { $fileLinkFormat = $fileLinkFormat ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); $this->stopwatch = $stopwatch; $this->fileLinkFormat = $fileLinkFormat instanceof FileLinkFormatter && false === $fileLinkFormat->format('', 0) ? false : $fileLinkFormat; $this->charset = $charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8'; $this->requestStack = $requestStack; $this->dumper = $dumper; // All clones share these properties by reference: $this->rootRefs = [ &$this->data, &$this->dataCount, &$this->isCollected, &$this->clonesCount, ]; $this->sourceContextProvider = $dumper instanceof Connection && isset($dumper->getContextProviders()['source']) ? $dumper->getContextProviders()['source'] : new SourceContextProvider($this->charset); } public function __clone() { $this->clonesIndex = ++$this->clonesCount; } public function dump(Data $data): ?string { $this->stopwatch?->start('dump'); ['name' => $name, 'file' => $file, 'line' => $line, 'file_excerpt' => $fileExcerpt] = $this->sourceContextProvider->getContext(); if (!$this->dumper || $this->dumper instanceof Connection && !$this->dumper->write($data)) { $this->isCollected = false; } $context = $data->getContext(); $label = $context['label'] ?? ''; unset($context['label']); $data = $data->withContext($context); if ($this->dumper && !$this->dumper instanceof Connection) { $this->doDump($this->dumper, $data, $name, $file, $line, $label); } if (!$this->dataCount) { $this->data = []; } $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt', 'label'); ++$this->dataCount; $this->stopwatch?->stop('dump'); return null; } public function collect(Request $request, Response $response, \Throwable $exception = null): void { if (!$this->dataCount) { $this->data = []; } // Sub-requests and programmatic calls stay in the collected profile. if ($this->dumper || ($this->requestStack && $this->requestStack->getMainRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) { return; } // In all other conditions that remove the web debug toolbar, dumps are written on the output. if (!$this->requestStack || !$response->headers->has('X-Debug-Token') || $response->isRedirection() || ($response->headers->has('Content-Type') && !str_contains($response->headers->get('Content-Type') ?? '', 'html')) || 'html' !== $request->getRequestFormat() || false === strripos($response->getContent(), '</body>') ) { if ($response->headers->has('Content-Type') && str_contains($response->headers->get('Content-Type') ?? '', 'html')) { $dumper = new HtmlDumper('php://output', $this->charset); $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } else { $dumper = new CliDumper('php://output', $this->charset); if (method_exists($dumper, 'setDisplayOptions')) { $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } } foreach ($this->data as $dump) { $this->doDump($dumper, $dump['data'], $dump['name'], $dump['file'], $dump['line'], $dump['label'] ?? ''); } } } public function reset(): void { $this->stopwatch?->reset(); $this->data = []; $this->dataCount = 0; $this->isCollected = true; $this->clonesCount = 0; $this->clonesIndex = 0; } /** * @internal */ public function __sleep(): array { if (!$this->dataCount) { $this->data = []; } if ($this->clonesCount !== $this->clonesIndex) { return []; } $this->data[] = $this->fileLinkFormat; $this->data[] = $this->charset; $this->dataCount = 0; $this->isCollected = true; return parent::__sleep(); } /** * @internal */ public function __wakeup() { parent::__wakeup(); $charset = array_pop($this->data); $fileLinkFormat = array_pop($this->data); $this->dataCount = \count($this->data); foreach ($this->data as $dump) { if (!\is_string($dump['name']) || !\is_string($dump['file']) || !\is_int($dump['line'])) { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } } self::__construct($this->stopwatch, \is_string($fileLinkFormat) || $fileLinkFormat instanceof FileLinkFormatter ? $fileLinkFormat : null, \is_string($charset) ? $charset : null); } public function getDumpsCount(): int { return $this->dataCount; } public function getDumps(string $format, int $maxDepthLimit = -1, int $maxItemsPerDepth = -1): array { $data = fopen('php://memory', 'r+'); if ('html' === $format) { $dumper = new HtmlDumper($data, $this->charset); $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } else { throw new \InvalidArgumentException(sprintf('Invalid dump format: "%s".', $format)); } $dumps = []; if (!$this->dataCount) { return $this->data = []; } foreach ($this->data as $dump) { $dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth)); $dump['data'] = stream_get_contents($data, -1, 0); ftruncate($data, 0); rewind($data); $dumps[] = $dump; } return $dumps; } public function getName(): string { return 'dump'; } public function __destruct() { if (0 === $this->clonesCount-- && !$this->isCollected && $this->dataCount) { $this->clonesCount = 0; $this->isCollected = true; $h = headers_list(); $i = \count($h); array_unshift($h, 'Content-Type: '.\ini_get('default_mimetype')); while (0 !== stripos($h[$i], 'Content-Type:')) { --$i; } if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && stripos($h[$i], 'html')) { $dumper = new HtmlDumper('php://output', $this->charset); $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } else { $dumper = new CliDumper('php://output', $this->charset); if (method_exists($dumper, 'setDisplayOptions')) { $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } } foreach ($this->data as $i => $dump) { $this->data[$i] = null; $this->doDump($dumper, $dump['data'], $dump['name'], $dump['file'], $dump['line'], $dump['label'] ?? ''); } $this->data = []; $this->dataCount = 0; } } private function doDump(DataDumperInterface $dumper, Data $data, string $name, string $file, int $line, string $label): void { if ($dumper instanceof CliDumper) { $contextDumper = function ($name, $file, $line, $fmt, $label) { $this->line = '' !== $label ? $this->style('meta', $label).' in ' : ''; if ($this instanceof HtmlDumper) { if ($file) { $s = $this->style('meta', '%s'); $f = strip_tags($this->style('', $file)); $name = strip_tags($this->style('', $name)); if ($fmt && $link = \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line)) { $name = sprintf('<a href="%s" title="%s">'.$s.'</a>', strip_tags($this->style('', $link)), $f, $name); } else { $name = sprintf('<abbr title="%s">'.$s.'</abbr>', $f, $name); } } else { $name = $this->style('meta', $name); } $this->line .= $name.' on line '.$this->style('meta', $line).':'; } else { $this->line .= $this->style('meta', $name).' on line '.$this->style('meta', $line).':'; } $this->dumpLine(0); }; $contextDumper = $contextDumper->bindTo($dumper, $dumper); $contextDumper($name, $file, $line, $this->fileLinkFormat, $label); } else { $cloner = new VarCloner(); $dumper->dump($cloner->cloneVar(('' !== $label ? $label.' in ' : '').$name.' on line '.$line.':')); } $dumper->dump($data); } } DataCollector/LateDataCollectorInterface.php 0000644 00000001041 15111167612 0015141 0 ustar 00 <?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\HttpKernel\DataCollector; /** * LateDataCollectorInterface. * * @author Fabien Potencier <fabien@symfony.com> */ interface LateDataCollectorInterface { /** * Collects data as late as possible. * * @return void */ public function lateCollect(); } DataCollector/LoggerDataCollector.php 0000644 00000025412 15111167612 0013662 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; /** * @author Fabien Potencier <fabien@symfony.com> * * @final */ class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface { private DebugLoggerInterface $logger; private ?string $containerPathPrefix; private ?Request $currentRequest = null; private ?RequestStack $requestStack; private ?array $processedLogs = null; public function __construct(object $logger = null, string $containerPathPrefix = null, RequestStack $requestStack = null) { if ($logger instanceof DebugLoggerInterface) { $this->logger = $logger; } $this->containerPathPrefix = $containerPathPrefix; $this->requestStack = $requestStack; } public function collect(Request $request, Response $response, \Throwable $exception = null): void { $this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null; } public function reset(): void { if (isset($this->logger)) { $this->logger->clear(); } $this->data = []; } public function lateCollect(): void { if (isset($this->logger)) { $containerDeprecationLogs = $this->getContainerDeprecationLogs(); $this->data = $this->computeErrorsCount($containerDeprecationLogs); // get compiler logs later (only when they are needed) to improve performance $this->data['compiler_logs'] = []; $this->data['compiler_logs_filepath'] = $this->containerPathPrefix.'Compiler.log'; $this->data['logs'] = $this->sanitizeLogs(array_merge($this->logger->getLogs($this->currentRequest), $containerDeprecationLogs)); $this->data = $this->cloneVar($this->data); } $this->currentRequest = null; } public function getLogs() { return $this->data['logs'] ?? []; } public function getProcessedLogs() { if (null !== $this->processedLogs) { return $this->processedLogs; } $rawLogs = $this->getLogs(); if ([] === $rawLogs) { return $this->processedLogs = $rawLogs; } $logs = []; foreach ($this->getLogs()->getValue() as $rawLog) { $rawLogData = $rawLog->getValue(); if ($rawLogData['priority']->getValue() > 300) { $logType = 'error'; } elseif (isset($rawLogData['scream']) && false === $rawLogData['scream']->getValue()) { $logType = 'deprecation'; } elseif (isset($rawLogData['scream']) && true === $rawLogData['scream']->getValue()) { $logType = 'silenced'; } else { $logType = 'regular'; } $logs[] = [ 'type' => $logType, 'errorCount' => $rawLog['errorCount'] ?? 1, 'timestamp' => $rawLogData['timestamp_rfc3339']->getValue(), 'priority' => $rawLogData['priority']->getValue(), 'priorityName' => $rawLogData['priorityName']->getValue(), 'channel' => $rawLogData['channel']->getValue(), 'message' => $rawLogData['message'], 'context' => $rawLogData['context'], ]; } // sort logs from oldest to newest usort($logs, static fn ($logA, $logB) => $logA['timestamp'] <=> $logB['timestamp']); return $this->processedLogs = $logs; } public function getFilters() { $filters = [ 'channel' => [], 'priority' => [ 'Debug' => 100, 'Info' => 200, 'Notice' => 250, 'Warning' => 300, 'Error' => 400, 'Critical' => 500, 'Alert' => 550, 'Emergency' => 600, ], ]; $allChannels = []; foreach ($this->getProcessedLogs() as $log) { if ('' === trim($log['channel'] ?? '')) { continue; } $allChannels[] = $log['channel']; } $channels = array_unique($allChannels); sort($channels); $filters['channel'] = $channels; return $filters; } public function getPriorities() { return $this->data['priorities'] ?? []; } public function countErrors() { return $this->data['error_count'] ?? 0; } public function countDeprecations() { return $this->data['deprecation_count'] ?? 0; } public function countWarnings() { return $this->data['warning_count'] ?? 0; } public function countScreams() { return $this->data['scream_count'] ?? 0; } public function getCompilerLogs() { return $this->cloneVar($this->getContainerCompilerLogs($this->data['compiler_logs_filepath'] ?? null)); } public function getName(): string { return 'logger'; } private function getContainerDeprecationLogs(): array { if (null === $this->containerPathPrefix || !is_file($file = $this->containerPathPrefix.'Deprecations.log')) { return []; } if ('' === $logContent = trim(file_get_contents($file))) { return []; } $bootTime = filemtime($file); $logs = []; foreach (unserialize($logContent) as $log) { $log['context'] = ['exception' => new SilencedErrorContext($log['type'], $log['file'], $log['line'], $log['trace'], $log['count'])]; $log['timestamp'] = $bootTime; $log['timestamp_rfc3339'] = (new \DateTimeImmutable())->setTimestamp($bootTime)->format(\DateTimeInterface::RFC3339_EXTENDED); $log['priority'] = 100; $log['priorityName'] = 'DEBUG'; $log['channel'] = null; $log['scream'] = false; unset($log['type'], $log['file'], $log['line'], $log['trace'], $log['trace'], $log['count']); $logs[] = $log; } return $logs; } private function getContainerCompilerLogs(string $compilerLogsFilepath = null): array { if (!is_file($compilerLogsFilepath)) { return []; } $logs = []; foreach (file($compilerLogsFilepath, \FILE_IGNORE_NEW_LINES) as $log) { $log = explode(': ', $log, 2); if (!isset($log[1]) || !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $log[0])) { $log = ['Unknown Compiler Pass', implode(': ', $log)]; } $logs[$log[0]][] = ['message' => $log[1]]; } return $logs; } private function sanitizeLogs(array $logs): array { $sanitizedLogs = []; $silencedLogs = []; foreach ($logs as $log) { if (!$this->isSilencedOrDeprecationErrorLog($log)) { $sanitizedLogs[] = $log; continue; } $message = '_'.$log['message']; $exception = $log['context']['exception']; if ($exception instanceof SilencedErrorContext) { if (isset($silencedLogs[$h = spl_object_hash($exception)])) { continue; } $silencedLogs[$h] = true; if (!isset($sanitizedLogs[$message])) { $sanitizedLogs[$message] = $log + [ 'errorCount' => 0, 'scream' => true, ]; } $sanitizedLogs[$message]['errorCount'] += $exception->count; continue; } $errorId = hash('xxh128', "{$exception->getSeverity()}/{$exception->getLine()}/{$exception->getFile()}\0{$message}", true); if (isset($sanitizedLogs[$errorId])) { ++$sanitizedLogs[$errorId]['errorCount']; } else { $log += [ 'errorCount' => 1, 'scream' => false, ]; $sanitizedLogs[$errorId] = $log; } } return array_values($sanitizedLogs); } private function isSilencedOrDeprecationErrorLog(array $log): bool { if (!isset($log['context']['exception'])) { return false; } $exception = $log['context']['exception']; if ($exception instanceof SilencedErrorContext) { return true; } if ($exception instanceof \ErrorException && \in_array($exception->getSeverity(), [\E_DEPRECATED, \E_USER_DEPRECATED], true)) { return true; } return false; } private function computeErrorsCount(array $containerDeprecationLogs): array { $silencedLogs = []; $count = [ 'error_count' => $this->logger->countErrors($this->currentRequest), 'deprecation_count' => 0, 'warning_count' => 0, 'scream_count' => 0, 'priorities' => [], ]; foreach ($this->logger->getLogs($this->currentRequest) as $log) { if (isset($count['priorities'][$log['priority']])) { ++$count['priorities'][$log['priority']]['count']; } else { $count['priorities'][$log['priority']] = [ 'count' => 1, 'name' => $log['priorityName'], ]; } if ('WARNING' === $log['priorityName']) { ++$count['warning_count']; } if ($this->isSilencedOrDeprecationErrorLog($log)) { $exception = $log['context']['exception']; if ($exception instanceof SilencedErrorContext) { if (isset($silencedLogs[$h = spl_object_hash($exception)])) { continue; } $silencedLogs[$h] = true; $count['scream_count'] += $exception->count; } else { ++$count['deprecation_count']; } } } foreach ($containerDeprecationLogs as $deprecationLog) { $count['deprecation_count'] += $deprecationLog['context']['exception']->count; } ksort($count['priorities']); return $count; } } DataCollector/MemoryDataCollector.php 0000644 00000004251 15111167612 0013711 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * @author Fabien Potencier <fabien@symfony.com> * * @final */ class MemoryDataCollector extends DataCollector implements LateDataCollectorInterface { public function __construct() { $this->reset(); } public function collect(Request $request, Response $response, \Throwable $exception = null): void { $this->updateMemoryUsage(); } public function reset(): void { $this->data = [ 'memory' => 0, 'memory_limit' => $this->convertToBytes(\ini_get('memory_limit')), ]; } public function lateCollect(): void { $this->updateMemoryUsage(); } public function getMemory(): int { return $this->data['memory']; } public function getMemoryLimit(): int|float { return $this->data['memory_limit']; } public function updateMemoryUsage(): void { $this->data['memory'] = memory_get_peak_usage(true); } public function getName(): string { return 'memory'; } private function convertToBytes(string $memoryLimit): int|float { if ('-1' === $memoryLimit) { return -1; } $memoryLimit = strtolower($memoryLimit); $max = strtolower(ltrim($memoryLimit, '+')); if (str_starts_with($max, '0x')) { $max = \intval($max, 16); } elseif (str_starts_with($max, '0')) { $max = \intval($max, 8); } else { $max = (int) $max; } switch (substr($memoryLimit, -1)) { case 't': $max *= 1024; // no break case 'g': $max *= 1024; // no break case 'm': $max *= 1024; // no break case 'k': $max *= 1024; } return $max; } } DataCollector/ExceptionDataCollector.php 0000644 00000003201 15111167612 0014371 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\ErrorHandler\Exception\FlattenException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * @author Fabien Potencier <fabien@symfony.com> * * @final */ class ExceptionDataCollector extends DataCollector { public function collect(Request $request, Response $response, \Throwable $exception = null): void { if (null !== $exception) { $this->data = [ 'exception' => FlattenException::createWithDataRepresentation($exception), ]; } } public function reset(): void { $this->data = []; } public function hasException(): bool { return isset($this->data['exception']); } public function getException(): \Exception|FlattenException { return $this->data['exception']; } public function getMessage(): string { return $this->data['exception']->getMessage(); } public function getCode(): int { return $this->data['exception']->getCode(); } public function getStatusCode(): int { return $this->data['exception']->getStatusCode(); } public function getTrace(): array { return $this->data['exception']->getTrace(); } public function getName(): string { return 'exception'; } } DataCollector/RequestDataCollector.php 0000644 00000040304 15111167612 0014070 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\VarDumper\Cloner\Data; /** * @author Fabien Potencier <fabien@symfony.com> * * @final */ class RequestDataCollector extends DataCollector implements EventSubscriberInterface, LateDataCollectorInterface { /** * @var \SplObjectStorage<Request, callable> */ private \SplObjectStorage $controllers; private array $sessionUsages = []; private ?RequestStack $requestStack; public function __construct(RequestStack $requestStack = null) { $this->controllers = new \SplObjectStorage(); $this->requestStack = $requestStack; } public function collect(Request $request, Response $response, \Throwable $exception = null): void { // attributes are serialized and as they can be anything, they need to be converted to strings. $attributes = []; $route = ''; foreach ($request->attributes->all() as $key => $value) { if ('_route' === $key) { $route = \is_object($value) ? $value->getPath() : $value; $attributes[$key] = $route; } else { $attributes[$key] = $value; } } $content = $request->getContent(); $sessionMetadata = []; $sessionAttributes = []; $flashes = []; if ($request->hasSession()) { $session = $request->getSession(); if ($session->isStarted()) { $sessionMetadata['Created'] = date(\DATE_RFC822, $session->getMetadataBag()->getCreated()); $sessionMetadata['Last used'] = date(\DATE_RFC822, $session->getMetadataBag()->getLastUsed()); $sessionMetadata['Lifetime'] = $session->getMetadataBag()->getLifetime(); $sessionAttributes = $session->all(); $flashes = $session->getFlashBag()->peekAll(); } } $statusCode = $response->getStatusCode(); $responseCookies = []; foreach ($response->headers->getCookies() as $cookie) { $responseCookies[$cookie->getName()] = $cookie; } $dotenvVars = []; foreach (explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? '') as $name) { if ('' !== $name && isset($_ENV[$name])) { $dotenvVars[$name] = $_ENV[$name]; } } $this->data = [ 'method' => $request->getMethod(), 'format' => $request->getRequestFormat(), 'content_type' => $response->headers->get('Content-Type', 'text/html'), 'status_text' => Response::$statusTexts[$statusCode] ?? '', 'status_code' => $statusCode, 'request_query' => $request->query->all(), 'request_request' => $request->request->all(), 'request_files' => $request->files->all(), 'request_headers' => $request->headers->all(), 'request_server' => $request->server->all(), 'request_cookies' => $request->cookies->all(), 'request_attributes' => $attributes, 'route' => $route, 'response_headers' => $response->headers->all(), 'response_cookies' => $responseCookies, 'session_metadata' => $sessionMetadata, 'session_attributes' => $sessionAttributes, 'session_usages' => array_values($this->sessionUsages), 'stateless_check' => $this->requestStack?->getMainRequest()?->attributes->get('_stateless') ?? false, 'flashes' => $flashes, 'path_info' => $request->getPathInfo(), 'controller' => 'n/a', 'locale' => $request->getLocale(), 'dotenv_vars' => $dotenvVars, ]; if (isset($this->data['request_headers']['php-auth-pw'])) { $this->data['request_headers']['php-auth-pw'] = '******'; } if (isset($this->data['request_server']['PHP_AUTH_PW'])) { $this->data['request_server']['PHP_AUTH_PW'] = '******'; } if (isset($this->data['request_request']['_password'])) { $encodedPassword = rawurlencode($this->data['request_request']['_password']); $content = str_replace('_password='.$encodedPassword, '_password=******', $content); $this->data['request_request']['_password'] = '******'; } $this->data['content'] = $content; foreach ($this->data as $key => $value) { if (!\is_array($value)) { continue; } if ('request_headers' === $key || 'response_headers' === $key) { $this->data[$key] = array_map(fn ($v) => isset($v[0]) && !isset($v[1]) ? $v[0] : $v, $value); } } if (isset($this->controllers[$request])) { $this->data['controller'] = $this->parseController($this->controllers[$request]); unset($this->controllers[$request]); } if ($request->attributes->has('_redirected') && $redirectCookie = $request->cookies->get('sf_redirect')) { $this->data['redirect'] = json_decode($redirectCookie, true); $response->headers->clearCookie('sf_redirect'); } if ($response->isRedirect()) { $response->headers->setCookie(new Cookie( 'sf_redirect', json_encode([ 'token' => $response->headers->get('x-debug-token'), 'route' => $request->attributes->get('_route', 'n/a'), 'method' => $request->getMethod(), 'controller' => $this->parseController($request->attributes->get('_controller')), 'status_code' => $statusCode, 'status_text' => Response::$statusTexts[$statusCode], ]), 0, '/', null, $request->isSecure(), true, false, 'lax' )); } $this->data['identifier'] = $this->data['route'] ?: (\is_array($this->data['controller']) ? $this->data['controller']['class'].'::'.$this->data['controller']['method'].'()' : $this->data['controller']); if ($response->headers->has('x-previous-debug-token')) { $this->data['forward_token'] = $response->headers->get('x-previous-debug-token'); } } public function lateCollect(): void { $this->data = $this->cloneVar($this->data); } public function reset(): void { $this->data = []; $this->controllers = new \SplObjectStorage(); $this->sessionUsages = []; } public function getMethod() { return $this->data['method']; } public function getPathInfo() { return $this->data['path_info']; } /** * @return ParameterBag */ public function getRequestRequest() { return new ParameterBag($this->data['request_request']->getValue()); } /** * @return ParameterBag */ public function getRequestQuery() { return new ParameterBag($this->data['request_query']->getValue()); } /** * @return ParameterBag */ public function getRequestFiles() { return new ParameterBag($this->data['request_files']->getValue()); } /** * @return ParameterBag */ public function getRequestHeaders() { return new ParameterBag($this->data['request_headers']->getValue()); } /** * @return ParameterBag */ public function getRequestServer(bool $raw = false) { return new ParameterBag($this->data['request_server']->getValue($raw)); } /** * @return ParameterBag */ public function getRequestCookies(bool $raw = false) { return new ParameterBag($this->data['request_cookies']->getValue($raw)); } /** * @return ParameterBag */ public function getRequestAttributes() { return new ParameterBag($this->data['request_attributes']->getValue()); } /** * @return ParameterBag */ public function getResponseHeaders() { return new ParameterBag($this->data['response_headers']->getValue()); } /** * @return ParameterBag */ public function getResponseCookies() { return new ParameterBag($this->data['response_cookies']->getValue()); } public function getSessionMetadata() { return $this->data['session_metadata']->getValue(); } public function getSessionAttributes() { return $this->data['session_attributes']->getValue(); } public function getStatelessCheck() { return $this->data['stateless_check']; } public function getSessionUsages() { return $this->data['session_usages']; } public function getFlashes() { return $this->data['flashes']->getValue(); } public function getContent() { return $this->data['content']; } /** * @return bool */ public function isJsonRequest() { return 1 === preg_match('{^application/(?:\w+\++)*json$}i', $this->data['request_headers']['content-type']); } /** * @return string|null */ public function getPrettyJson() { $decoded = json_decode($this->getContent()); return \JSON_ERROR_NONE === json_last_error() ? json_encode($decoded, \JSON_PRETTY_PRINT) : null; } public function getContentType() { return $this->data['content_type']; } public function getStatusText() { return $this->data['status_text']; } public function getStatusCode() { return $this->data['status_code']; } public function getFormat() { return $this->data['format']; } public function getLocale() { return $this->data['locale']; } /** * @return ParameterBag */ public function getDotenvVars() { return new ParameterBag($this->data['dotenv_vars']->getValue()); } /** * Gets the route name. * * The _route request attributes is automatically set by the Router Matcher. */ public function getRoute(): string { return $this->data['route']; } public function getIdentifier() { return $this->data['identifier']; } /** * Gets the route parameters. * * The _route_params request attributes is automatically set by the RouterListener. */ public function getRouteParams(): array { return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params']->getValue() : []; } /** * Gets the parsed controller. * * @return array|string|Data The controller as a string or array of data * with keys 'class', 'method', 'file' and 'line' */ public function getController(): array|string|Data { return $this->data['controller']; } /** * Gets the previous request attributes. * * @return array|Data|false A legacy array of data from the previous redirection response * or false otherwise */ public function getRedirect(): array|Data|false { return $this->data['redirect'] ?? false; } public function getForwardToken() { return $this->data['forward_token'] ?? null; } public function onKernelController(ControllerEvent $event): void { $this->controllers[$event->getRequest()] = $event->getController(); } public function onKernelResponse(ResponseEvent $event): void { if (!$event->isMainRequest()) { return; } if ($event->getRequest()->cookies->has('sf_redirect')) { $event->getRequest()->attributes->set('_redirected', true); } } public static function getSubscribedEvents(): array { return [ KernelEvents::CONTROLLER => 'onKernelController', KernelEvents::RESPONSE => 'onKernelResponse', ]; } public function getName(): string { return 'request'; } public function collectSessionUsage(): void { $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); $traceEndIndex = \count($trace) - 1; for ($i = $traceEndIndex; $i > 0; --$i) { if (null !== ($class = $trace[$i]['class'] ?? null) && (is_subclass_of($class, SessionInterface::class) || is_subclass_of($class, SessionBagInterface::class))) { $traceEndIndex = $i; break; } } if ((\count($trace) - 1) === $traceEndIndex) { return; } // Remove part of the backtrace that belongs to session only array_splice($trace, 0, $traceEndIndex); // Merge identical backtraces generated by internal call reports $name = sprintf('%s:%s', $trace[1]['class'] ?? $trace[0]['file'], $trace[0]['line']); if (!\array_key_exists($name, $this->sessionUsages)) { $this->sessionUsages[$name] = [ 'name' => $name, 'file' => $trace[0]['file'], 'line' => $trace[0]['line'], 'trace' => $trace, ]; } } /** * @return array|string An array of controller data or a simple string */ private function parseController(array|object|string|null $controller): array|string { if (\is_string($controller) && str_contains($controller, '::')) { $controller = explode('::', $controller); } if (\is_array($controller)) { try { $r = new \ReflectionMethod($controller[0], $controller[1]); return [ 'class' => \is_object($controller[0]) ? get_debug_type($controller[0]) : $controller[0], 'method' => $controller[1], 'file' => $r->getFileName(), 'line' => $r->getStartLine(), ]; } catch (\ReflectionException) { if (\is_callable($controller)) { // using __call or __callStatic return [ 'class' => \is_object($controller[0]) ? get_debug_type($controller[0]) : $controller[0], 'method' => $controller[1], 'file' => 'n/a', 'line' => 'n/a', ]; } } } if ($controller instanceof \Closure) { $r = new \ReflectionFunction($controller); $controller = [ 'class' => $r->getName(), 'method' => null, 'file' => $r->getFileName(), 'line' => $r->getStartLine(), ]; if (str_contains($r->name, '{closure}')) { return $controller; } $controller['method'] = $r->name; if ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) { $controller['class'] = $class->name; } else { return $r->name; } return $controller; } if (\is_object($controller)) { $r = new \ReflectionClass($controller); return [ 'class' => $r->getName(), 'method' => null, 'file' => $r->getFileName(), 'line' => $r->getStartLine(), ]; } return \is_string($controller) ? $controller : 'n/a'; } } DataCollector/AjaxDataCollector.php 0000644 00000001477 15111167612 0013333 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * @author Bart van den Burg <bart@burgov.nl> * * @final */ class AjaxDataCollector extends DataCollector { public function collect(Request $request, Response $response, \Throwable $exception = null): void { // all collecting is done client side } public function reset(): void { // all collecting is done client side } public function getName(): string { return 'ajax'; } } DataCollector/DataCollector.php 0000644 00000005017 15111167612 0012521 0 ustar 00 <?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\HttpKernel\DataCollector; use Symfony\Component\VarDumper\Caster\CutStub; use Symfony\Component\VarDumper\Caster\ReflectionCaster; use Symfony\Component\VarDumper\Cloner\ClonerInterface; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\Stub; use Symfony\Component\VarDumper\Cloner\VarCloner; /** * DataCollector. * * Children of this class must store the collected data in the data property. * * @author Fabien Potencier <fabien@symfony.com> * @author Bernhard Schussek <bschussek@symfony.com> */ abstract class DataCollector implements DataCollectorInterface { /** * @var array|Data */ protected $data = []; private ClonerInterface $cloner; /** * Converts the variable into a serializable Data instance. * * This array can be displayed in the template using * the VarDumper component. */ protected function cloneVar(mixed $var): Data { if ($var instanceof Data) { return $var; } if (!isset($this->cloner)) { $this->cloner = new VarCloner(); $this->cloner->setMaxItems(-1); $this->cloner->addCasters($this->getCasters()); } return $this->cloner->cloneVar($var); } /** * @return callable[] The casters to add to the cloner */ protected function getCasters() { $casters = [ '*' => function ($v, array $a, Stub $s, $isNested) { if (!$v instanceof Stub) { foreach ($a as $k => $v) { if (\is_object($v) && !$v instanceof \DateTimeInterface && !$v instanceof Stub) { $a[$k] = new CutStub($v); } } } return $a; }, ] + ReflectionCaster::UNSET_CLOSURE_FILE_INFO; return $casters; } public function __sleep(): array { return ['data']; } public function __wakeup() { } /** * @internal to prevent implementing \Serializable */ final protected function serialize(): void { } /** * @internal to prevent implementing \Serializable */ final protected function unserialize(string $data): void { } } HttpKernelInterface.php 0000644 00000002672 15111167612 0011166 0 ustar 00 <?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\HttpKernel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * HttpKernelInterface handles a Request to convert it to a Response. * * @author Fabien Potencier <fabien@symfony.com> */ interface HttpKernelInterface { public const MAIN_REQUEST = 1; public const SUB_REQUEST = 2; /** * @deprecated since symfony/http-kernel 5.3, use MAIN_REQUEST instead. * To ease the migration, this constant won't be removed until Symfony 7.0. */ public const MASTER_REQUEST = self::MAIN_REQUEST; /** * Handles a Request to convert it to a Response. * * When $catch is true, the implementation must catch all exceptions * and do its best to convert them to a Response instance. * * @param int $type The type of the request * (one of HttpKernelInterface::MAIN_REQUEST or HttpKernelInterface::SUB_REQUEST) * @param bool $catch Whether to catch exceptions or not * * @throws \Exception When an Exception occurs during processing */ public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true): Response; } KernelInterface.php 0000644 00000007176 15111167612 0010332 0 ustar 00 <?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\HttpKernel; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\Bundle\BundleInterface; /** * The Kernel is the heart of the Symfony system. * * It manages an environment made of application kernel and bundles. * * @author Fabien Potencier <fabien@symfony.com> */ interface KernelInterface extends HttpKernelInterface { /** * Returns an array of bundles to register. * * @return iterable<mixed, BundleInterface> */ public function registerBundles(): iterable; /** * Loads the container configuration. * * @return void */ public function registerContainerConfiguration(LoaderInterface $loader); /** * Boots the current kernel. * * @return void */ public function boot(); /** * Shutdowns the kernel. * * This method is mainly useful when doing functional testing. * * @return void */ public function shutdown(); /** * Gets the registered bundle instances. * * @return array<string, BundleInterface> */ public function getBundles(): array; /** * Returns a bundle. * * @throws \InvalidArgumentException when the bundle is not enabled */ public function getBundle(string $name): BundleInterface; /** * Returns the file path for a given bundle resource. * * A Resource can be a file or a directory. * * The resource name must follow the following pattern: * * "@BundleName/path/to/a/file.something" * * where BundleName is the name of the bundle * and the remaining part is the relative path in the bundle. * * @throws \InvalidArgumentException if the file cannot be found or the name is not valid * @throws \RuntimeException if the name contains invalid/unsafe characters */ public function locateResource(string $name): string; /** * Gets the environment. */ public function getEnvironment(): string; /** * Checks if debug mode is enabled. */ public function isDebug(): bool; /** * Gets the project dir (path of the project's composer file). */ public function getProjectDir(): string; /** * Gets the current container. */ public function getContainer(): ContainerInterface; /** * Gets the request start time (not available if debug is disabled). */ public function getStartTime(): float; /** * Gets the cache directory. * * Since Symfony 5.2, the cache directory should be used for caches that are written at runtime. * For caches and artifacts that can be warmed at compile-time and deployed as read-only, * use the new "build directory" returned by the {@see getBuildDir()} method. */ public function getCacheDir(): string; /** * Returns the build directory. * * This directory should be used to store build artifacts, and can be read-only at runtime. * Caches written at runtime should be stored in the "cache directory" ({@see KernelInterface::getCacheDir()}). */ public function getBuildDir(): string; /** * Gets the log directory. */ public function getLogDir(): string; /** * Gets the charset of the application. */ public function getCharset(): string; } Log/DebugLoggerInterface.php 0000644 00000002050 15111167612 0012003 0 ustar 00 <?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\HttpKernel\Log; use Symfony\Component\HttpFoundation\Request; /** * DebugLoggerInterface. * * @author Fabien Potencier <fabien@symfony.com> */ interface DebugLoggerInterface { /** * Returns an array of logs. * * @return array<array{ * channel: ?string, * context: array<string, mixed>, * message: string, * priority: int, * priorityName: string, * timestamp: int, * timestamp_rfc3339: string, * }> */ public function getLogs(Request $request = null); /** * Returns the number of errors. * * @return int */ public function countErrors(Request $request = null); /** * Removes all log records. * * @return void */ public function clear(); } Log/Logger.php 0000644 00000013571 15111167612 0007225 0 ustar 00 <?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\HttpKernel\Log; use Psr\Log\AbstractLogger; use Psr\Log\InvalidArgumentException; use Psr\Log\LogLevel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; /** * Minimalist PSR-3 logger designed to write in stderr or any other stream. * * @author Kévin Dunglas <dunglas@gmail.com> */ class Logger extends AbstractLogger implements DebugLoggerInterface { private const LEVELS = [ LogLevel::DEBUG => 0, LogLevel::INFO => 1, LogLevel::NOTICE => 2, LogLevel::WARNING => 3, LogLevel::ERROR => 4, LogLevel::CRITICAL => 5, LogLevel::ALERT => 6, LogLevel::EMERGENCY => 7, ]; private const PRIORITIES = [ LogLevel::DEBUG => 100, LogLevel::INFO => 200, LogLevel::NOTICE => 250, LogLevel::WARNING => 300, LogLevel::ERROR => 400, LogLevel::CRITICAL => 500, LogLevel::ALERT => 550, LogLevel::EMERGENCY => 600, ]; private int $minLevelIndex; private \Closure $formatter; private bool $debug = false; private array $logs = []; private array $errorCount = []; /** @var resource|null */ private $handle; /** * @param string|resource|null $output */ public function __construct(string $minLevel = null, $output = null, callable $formatter = null, private readonly ?RequestStack $requestStack = null) { if (null === $minLevel) { $minLevel = null === $output || 'php://stdout' === $output || 'php://stderr' === $output ? LogLevel::ERROR : LogLevel::WARNING; if (isset($_ENV['SHELL_VERBOSITY']) || isset($_SERVER['SHELL_VERBOSITY'])) { $minLevel = match ((int) ($_ENV['SHELL_VERBOSITY'] ?? $_SERVER['SHELL_VERBOSITY'])) { -1 => LogLevel::ERROR, 1 => LogLevel::NOTICE, 2 => LogLevel::INFO, 3 => LogLevel::DEBUG, default => $minLevel, }; } } if (!isset(self::LEVELS[$minLevel])) { throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $minLevel)); } $this->minLevelIndex = self::LEVELS[$minLevel]; $this->formatter = null !== $formatter ? $formatter(...) : $this->format(...); if ($output && false === $this->handle = \is_resource($output) ? $output : @fopen($output, 'a')) { throw new InvalidArgumentException(sprintf('Unable to open "%s".', $output)); } } public function enableDebug(): void { $this->debug = true; } public function log($level, $message, array $context = []): void { if (!isset(self::LEVELS[$level])) { throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level)); } if (self::LEVELS[$level] < $this->minLevelIndex) { return; } $formatter = $this->formatter; if ($this->handle) { @fwrite($this->handle, $formatter($level, $message, $context).\PHP_EOL); } else { error_log($formatter($level, $message, $context, false)); } if ($this->debug && $this->requestStack) { $this->record($level, $message, $context); } } public function getLogs(Request $request = null): array { if ($request) { return $this->logs[spl_object_id($request)] ?? []; } return array_merge(...array_values($this->logs)); } public function countErrors(Request $request = null): int { if ($request) { return $this->errorCount[spl_object_id($request)] ?? 0; } return array_sum($this->errorCount); } public function clear(): void { $this->logs = []; $this->errorCount = []; } private function format(string $level, string $message, array $context, bool $prefixDate = true): string { if (str_contains($message, '{')) { $replacements = []; foreach ($context as $key => $val) { if (null === $val || \is_scalar($val) || $val instanceof \Stringable) { $replacements["{{$key}}"] = $val; } elseif ($val instanceof \DateTimeInterface) { $replacements["{{$key}}"] = $val->format(\DateTimeInterface::RFC3339); } elseif (\is_object($val)) { $replacements["{{$key}}"] = '[object '.$val::class.']'; } else { $replacements["{{$key}}"] = '['.\gettype($val).']'; } } $message = strtr($message, $replacements); } $log = sprintf('[%s] %s', $level, $message); if ($prefixDate) { $log = date(\DateTimeInterface::RFC3339).' '.$log; } return $log; } private function record($level, $message, array $context): void { $request = $this->requestStack->getCurrentRequest(); $key = $request ? spl_object_id($request) : ''; $this->logs[$key][] = [ 'channel' => null, 'context' => $context, 'message' => $message, 'priority' => self::PRIORITIES[$level], 'priorityName' => $level, 'timestamp' => time(), 'timestamp_rfc3339' => date(\DATE_RFC3339_EXTENDED), ]; $this->errorCount[$key] ??= 0; switch ($level) { case LogLevel::ERROR: case LogLevel::CRITICAL: case LogLevel::ALERT: case LogLevel::EMERGENCY: ++$this->errorCount[$key]; } } } Log/error_log 0000644 00000001150 15111167612 0007200 0 ustar 00 [19-Nov-2025 13:24:18 UTC] PHP Fatal error: Uncaught Error: Class "Psr\Log\AbstractLogger" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Log/Logger.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Log/Logger.php on line 25 [19-Nov-2025 19:44:11 UTC] PHP Fatal error: Uncaught Error: Class "Psr\Log\AbstractLogger" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Log/Logger.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Log/Logger.php on line 25 TerminableInterface.php 0000644 00000001651 15111167612 0011164 0 ustar 00 <?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\HttpKernel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Terminable extends the Kernel request/response cycle with dispatching a post * response event after sending the response and before shutting down the kernel. * * @author Jordi Boggiano <j.boggiano@seld.be> * @author Pierre Minnieur <pierre.minnieur@sensiolabs.de> */ interface TerminableInterface { /** * Terminates a request/response cycle. * * Should be called after sending the response and before shutting down the kernel. * * @return void */ public function terminate(Request $request, Response $response); } HttpKernelBrowser.php 0000644 00000013433 15111167612 0010706 0 ustar 00 <?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\HttpKernel; use Symfony\Component\BrowserKit\AbstractBrowser; use Symfony\Component\BrowserKit\CookieJar; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\Request as DomRequest; use Symfony\Component\BrowserKit\Response as DomResponse; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Simulates a browser and makes requests to an HttpKernel instance. * * @author Fabien Potencier <fabien@symfony.com> * * @method Request getRequest() * @method Response getResponse() */ class HttpKernelBrowser extends AbstractBrowser { protected $kernel; private bool $catchExceptions = true; /** * @param array $server The server parameters (equivalent of $_SERVER) */ public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) { // These class properties must be set before calling the parent constructor, as it may depend on it. $this->kernel = $kernel; $this->followRedirects = false; parent::__construct($server, $history, $cookieJar); } /** * Sets whether to catch exceptions when the kernel is handling a request. * * @return void */ public function catchExceptions(bool $catchExceptions) { $this->catchExceptions = $catchExceptions; } /** * @param Request $request * * @return Response */ protected function doRequest(object $request) { $response = $this->kernel->handle($request, HttpKernelInterface::MAIN_REQUEST, $this->catchExceptions); if ($this->kernel instanceof TerminableInterface) { $this->kernel->terminate($request, $response); } return $response; } /** * @param Request $request * * @return string */ protected function getScript(object $request) { $kernel = var_export(serialize($this->kernel), true); $request = var_export(serialize($request), true); $errorReporting = error_reporting(); $requires = ''; foreach (get_declared_classes() as $class) { if (str_starts_with($class, 'ComposerAutoloaderInit')) { $r = new \ReflectionClass($class); $file = \dirname($r->getFileName(), 2).'/autoload.php'; if (file_exists($file)) { $requires .= 'require_once '.var_export($file, true).";\n"; } } } if (!$requires) { throw new \RuntimeException('Composer autoloader not found.'); } $code = <<<EOF <?php error_reporting($errorReporting); $requires \$kernel = unserialize($kernel); \$request = unserialize($request); EOF; return $code.$this->getHandleScript(); } /** * @return string */ protected function getHandleScript() { return <<<'EOF' $response = $kernel->handle($request); if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) { $kernel->terminate($request, $response); } echo serialize($response); EOF; } protected function filterRequest(DomRequest $request): Request { $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $server = $request->getServer(), $request->getContent()); if (!isset($server['HTTP_ACCEPT'])) { $httpRequest->headers->remove('Accept'); } foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) { $httpRequest->files->set($key, $value); } return $httpRequest; } /** * Filters an array of files. * * This method created test instances of UploadedFile so that the move() * method can be called on those instances. * * If the size of a file is greater than the allowed size (from php.ini) then * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE. * * @see UploadedFile */ protected function filterFiles(array $files): array { $filtered = []; foreach ($files as $key => $value) { if (\is_array($value)) { $filtered[$key] = $this->filterFiles($value); } elseif ($value instanceof UploadedFile) { if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) { $filtered[$key] = new UploadedFile( '', $value->getClientOriginalName(), $value->getClientMimeType(), \UPLOAD_ERR_INI_SIZE, true ); } else { $filtered[$key] = new UploadedFile( $value->getPathname(), $value->getClientOriginalName(), $value->getClientMimeType(), $value->getError(), true ); } } } return $filtered; } /** * @param Response $response */ protected function filterResponse(object $response): DomResponse { // this is needed to support StreamedResponse ob_start(); $response->sendContent(); $content = ob_get_clean(); return new DomResponse($content, $response->getStatusCode(), $response->headers->all()); } } error_log 0000644 00000010504 15111167612 0006462 0 ustar 00 [18-Nov-2025 22:06:08 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\BrowserKit\AbstractBrowser" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernelBrowser.php:31 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernelBrowser.php on line 31 [19-Nov-2025 01:41:30 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpClientKernel.php:32 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpClientKernel.php on line 32 [19-Nov-2025 01:42:30 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/KernelInterface.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/KernelInterface.php on line 25 [19-Nov-2025 05:10:41 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\BrowserKit\AbstractBrowser" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernelBrowser.php:31 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernelBrowser.php on line 31 [19-Nov-2025 16:24:32 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernel.php:52 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernel.php on line 52 [19-Nov-2025 23:56:22 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernel.php:52 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernel.php on line 52 [20-Nov-2025 12:28:15 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\KernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Kernel.php:56 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Kernel.php on line 56 [20-Nov-2025 15:43:28 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\KernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Kernel.php:56 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Kernel.php on line 56 [24-Nov-2025 10:06:27 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\BrowserKit\AbstractBrowser" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernelBrowser.php:31 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernelBrowser.php on line 31 [24-Nov-2025 10:09:07 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\KernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Kernel.php:56 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Kernel.php on line 56 [24-Nov-2025 10:14:42 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/KernelInterface.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/KernelInterface.php on line 25 [24-Nov-2025 10:18:29 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpClientKernel.php:32 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpClientKernel.php on line 32 [24-Nov-2025 11:52:21 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernel.php:52 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpKernel.php on line 52 KernelEvents.php 0000644 00000010056 15111167613 0007666 0 ustar 00 <?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\HttpKernel; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\Event\TerminateEvent; use Symfony\Component\HttpKernel\Event\ViewEvent; /** * Contains all events thrown in the HttpKernel component. * * @author Bernhard Schussek <bschussek@gmail.com> */ final class KernelEvents { /** * The REQUEST event occurs at the very beginning of request * dispatching. * * This event allows you to create a response for a request before any * other code in the framework is executed. * * @Event("Symfony\Component\HttpKernel\Event\RequestEvent") */ public const REQUEST = 'kernel.request'; /** * The EXCEPTION event occurs when an uncaught exception appears. * * This event allows you to create a response for a thrown exception or * to modify the thrown exception. * * @Event("Symfony\Component\HttpKernel\Event\ExceptionEvent") */ public const EXCEPTION = 'kernel.exception'; /** * The CONTROLLER event occurs once a controller was found for * handling a request. * * This event allows you to change the controller that will handle the * request. * * @Event("Symfony\Component\HttpKernel\Event\ControllerEvent") */ public const CONTROLLER = 'kernel.controller'; /** * The CONTROLLER_ARGUMENTS event occurs once controller arguments have been resolved. * * This event allows you to change the arguments that will be passed to * the controller. * * @Event("Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent") */ public const CONTROLLER_ARGUMENTS = 'kernel.controller_arguments'; /** * The VIEW event occurs when the return value of a controller * is not a Response instance. * * This event allows you to create a response for the return value of the * controller. * * @Event("Symfony\Component\HttpKernel\Event\ViewEvent") */ public const VIEW = 'kernel.view'; /** * The RESPONSE event occurs once a response was created for * replying to a request. * * This event allows you to modify or replace the response that will be * replied. * * @Event("Symfony\Component\HttpKernel\Event\ResponseEvent") */ public const RESPONSE = 'kernel.response'; /** * The FINISH_REQUEST event occurs when a response was generated for a request. * * This event allows you to reset the global and environmental state of * the application, when it was changed during the request. * * @Event("Symfony\Component\HttpKernel\Event\FinishRequestEvent") */ public const FINISH_REQUEST = 'kernel.finish_request'; /** * The TERMINATE event occurs once a response was sent. * * This event allows you to run expensive post-response jobs. * * @Event("Symfony\Component\HttpKernel\Event\TerminateEvent") */ public const TERMINATE = 'kernel.terminate'; /** * Event aliases. * * These aliases can be consumed by RegisterListenersPass. */ public const ALIASES = [ ControllerArgumentsEvent::class => self::CONTROLLER_ARGUMENTS, ControllerEvent::class => self::CONTROLLER, ResponseEvent::class => self::RESPONSE, FinishRequestEvent::class => self::FINISH_REQUEST, RequestEvent::class => self::REQUEST, ViewEvent::class => self::VIEW, ExceptionEvent::class => self::EXCEPTION, TerminateEvent::class => self::TERMINATE, ]; } CacheWarmer/CacheWarmerAggregate.php 0000644 00000010774 15111167613 0013441 0 ustar 00 <?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\HttpKernel\CacheWarmer; use Symfony\Component\Console\Style\SymfonyStyle; /** * Aggregates several cache warmers into a single one. * * @author Fabien Potencier <fabien@symfony.com> * * @final */ class CacheWarmerAggregate implements CacheWarmerInterface { private iterable $warmers; private bool $debug; private ?string $deprecationLogsFilepath; private bool $optionalsEnabled = false; private bool $onlyOptionalsEnabled = false; /** * @param iterable<mixed, CacheWarmerInterface> $warmers */ public function __construct(iterable $warmers = [], bool $debug = false, string $deprecationLogsFilepath = null) { $this->warmers = $warmers; $this->debug = $debug; $this->deprecationLogsFilepath = $deprecationLogsFilepath; } public function enableOptionalWarmers(): void { $this->optionalsEnabled = true; } public function enableOnlyOptionalWarmers(): void { $this->onlyOptionalsEnabled = $this->optionalsEnabled = true; } public function warmUp(string $cacheDir, SymfonyStyle $io = null): array { if ($collectDeprecations = $this->debug && !\defined('PHPUNIT_COMPOSER_INSTALL')) { $collectedLogs = []; $previousHandler = set_error_handler(function ($type, $message, $file, $line) use (&$collectedLogs, &$previousHandler) { if (\E_USER_DEPRECATED !== $type && \E_DEPRECATED !== $type) { return $previousHandler ? $previousHandler($type, $message, $file, $line) : false; } if (isset($collectedLogs[$message])) { ++$collectedLogs[$message]['count']; return null; } $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 3); // Clean the trace by removing first frames added by the error handler itself. for ($i = 0; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) { $backtrace = \array_slice($backtrace, 1 + $i); break; } } $collectedLogs[$message] = [ 'type' => $type, 'message' => $message, 'file' => $file, 'line' => $line, 'trace' => $backtrace, 'count' => 1, ]; return null; }); } $preload = []; try { foreach ($this->warmers as $warmer) { if (!$this->optionalsEnabled && $warmer->isOptional()) { continue; } if ($this->onlyOptionalsEnabled && !$warmer->isOptional()) { continue; } $start = microtime(true); foreach ((array) $warmer->warmUp($cacheDir) as $item) { if (is_dir($item) || (str_starts_with($item, \dirname($cacheDir)) && !is_file($item))) { throw new \LogicException(sprintf('"%s::warmUp()" should return a list of files or classes but "%s" is none of them.', $warmer::class, $item)); } $preload[] = $item; } if ($io?->isDebug()) { $io->info(sprintf('"%s" completed in %0.2fms.', $warmer::class, 1000 * (microtime(true) - $start))); } } } finally { if ($collectDeprecations) { restore_error_handler(); if (is_file($this->deprecationLogsFilepath)) { $previousLogs = unserialize(file_get_contents($this->deprecationLogsFilepath)); if (\is_array($previousLogs)) { $collectedLogs = array_merge($previousLogs, $collectedLogs); } } file_put_contents($this->deprecationLogsFilepath, serialize(array_values($collectedLogs))); } } return array_values(array_unique($preload)); } public function isOptional(): bool { return false; } } CacheWarmer/CacheWarmerInterface.php 0000644 00000001404 15111167613 0013441 0 ustar 00 <?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\HttpKernel\CacheWarmer; /** * Interface for classes able to warm up the cache. * * @author Fabien Potencier <fabien@symfony.com> */ interface CacheWarmerInterface extends WarmableInterface { /** * Checks whether this warmer is optional or not. * * Optional warmers can be ignored on certain conditions. * * A warmer should return true if the cache can be * generated incrementally and on-demand. * * @return bool */ public function isOptional(); } CacheWarmer/CacheWarmer.php 0000644 00000001622 15111167613 0011622 0 ustar 00 <?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\HttpKernel\CacheWarmer; /** * Abstract cache warmer that knows how to write a file to the cache. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class CacheWarmer implements CacheWarmerInterface { /** * @return void */ protected function writeCacheFile(string $file, $content) { $tmpFile = @tempnam(\dirname($file), basename($file)); if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) { @chmod($file, 0666 & ~umask()); return; } throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file)); } } CacheWarmer/error_log 0000644 00000002214 15111167613 0010643 0 ustar 00 [19-Nov-2025 18:14:26 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php on line 23 [19-Nov-2025 18:16:05 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php on line 19 [19-Nov-2025 18:22:53 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php on line 19 CacheWarmer/WarmableInterface.php 0000644 00000001144 15111167613 0013013 0 ustar 00 <?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\HttpKernel\CacheWarmer; /** * Interface for classes that support warming their cache. * * @author Fabien Potencier <fabien@symfony.com> */ interface WarmableInterface { /** * Warms up the cache. * * @return string[] A list of classes or files to preload on PHP 7.4+ */ public function warmUp(string $cacheDir); } HttpCache/Esi.php 0000644 00000006362 15111167613 0007651 0 ustar 00 <?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\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Esi implements the ESI capabilities to Request and Response instances. * * For more information, read the following W3C notes: * * * ESI Language Specification 1.0 (http://www.w3.org/TR/esi-lang) * * * Edge Architecture Specification (http://www.w3.org/TR/edge-arch) * * @author Fabien Potencier <fabien@symfony.com> */ class Esi extends AbstractSurrogate { public function getName(): string { return 'esi'; } /** * @return void */ public function addSurrogateControl(Response $response) { if (str_contains($response->getContent(), '<esi:include')) { $response->headers->set('Surrogate-Control', 'content="ESI/1.0"'); } } public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string { $html = sprintf('<esi:include src="%s"%s%s />', $uri, $ignoreErrors ? ' onerror="continue"' : '', $alt ? sprintf(' alt="%s"', $alt) : '' ); if (!empty($comment)) { return sprintf("<esi:comment text=\"%s\" />\n%s", $comment, $html); } return $html; } public function process(Request $request, Response $response): Response { $type = $response->headers->get('Content-Type'); if (empty($type)) { $type = 'text/html'; } $parts = explode(';', $type); if (!\in_array($parts[0], $this->contentTypes)) { return $response; } // we don't use a proper XML parser here as we can have ESI tags in a plain text response $content = $response->getContent(); $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#s', '', $content); $content = preg_replace('#<esi\:comment[^>]+>#s', '', $content); $boundary = self::generateBodyEvalBoundary(); $chunks = preg_split('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', $content, -1, \PREG_SPLIT_DELIM_CAPTURE); $i = 1; while (isset($chunks[$i])) { $options = []; preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $chunks[$i], $matches, \PREG_SET_ORDER); foreach ($matches as $set) { $options[$set[1]] = $set[2]; } if (!isset($options['src'])) { throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); } $chunks[$i] = $boundary.$options['src']."\n".($options['alt'] ?? '')."\n".('continue' === ($options['onerror'] ?? ''))."\n"; $i += 2; } $content = $boundary.implode('', $chunks).$boundary; $response->setContent($content); $response->headers->set('X-Body-Eval', 'ESI'); // remove ESI/1.0 from the Surrogate-Control header $this->removeFromControl($response); return $response; } } HttpCache/SubRequestHandler.php 0000644 00000007521 15111167613 0012527 0 ustar 00 <?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\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\IpUtils; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * @author Nicolas Grekas <p@tchwork.com> * * @internal */ class SubRequestHandler { public static function handle(HttpKernelInterface $kernel, Request $request, int $type, bool $catch): Response { // save global state related to trusted headers and proxies $trustedProxies = Request::getTrustedProxies(); $trustedHeaderSet = Request::getTrustedHeaderSet(); // remove untrusted values $remoteAddr = $request->server->get('REMOTE_ADDR'); if (!$remoteAddr || !IpUtils::checkIp($remoteAddr, $trustedProxies)) { $trustedHeaders = [ 'FORWARDED' => $trustedHeaderSet & Request::HEADER_FORWARDED, 'X_FORWARDED_FOR' => $trustedHeaderSet & Request::HEADER_X_FORWARDED_FOR, 'X_FORWARDED_HOST' => $trustedHeaderSet & Request::HEADER_X_FORWARDED_HOST, 'X_FORWARDED_PROTO' => $trustedHeaderSet & Request::HEADER_X_FORWARDED_PROTO, 'X_FORWARDED_PORT' => $trustedHeaderSet & Request::HEADER_X_FORWARDED_PORT, 'X_FORWARDED_PREFIX' => $trustedHeaderSet & Request::HEADER_X_FORWARDED_PREFIX, ]; foreach (array_filter($trustedHeaders) as $name => $key) { $request->headers->remove($name); $request->server->remove('HTTP_'.$name); } } // compute trusted values, taking any trusted proxies into account $trustedIps = []; $trustedValues = []; foreach (array_reverse($request->getClientIps()) as $ip) { $trustedIps[] = $ip; $trustedValues[] = sprintf('for="%s"', $ip); } if ($ip !== $remoteAddr) { $trustedIps[] = $remoteAddr; $trustedValues[] = sprintf('for="%s"', $remoteAddr); } // set trusted values, reusing as much as possible the global trusted settings if (Request::HEADER_FORWARDED & $trustedHeaderSet) { $trustedValues[0] .= sprintf(';host="%s";proto=%s', $request->getHttpHost(), $request->getScheme()); $request->headers->set('Forwarded', $v = implode(', ', $trustedValues)); $request->server->set('HTTP_FORWARDED', $v); } if (Request::HEADER_X_FORWARDED_FOR & $trustedHeaderSet) { $request->headers->set('X-Forwarded-For', $v = implode(', ', $trustedIps)); $request->server->set('HTTP_X_FORWARDED_FOR', $v); } elseif (!(Request::HEADER_FORWARDED & $trustedHeaderSet)) { Request::setTrustedProxies($trustedProxies, $trustedHeaderSet | Request::HEADER_X_FORWARDED_FOR); $request->headers->set('X-Forwarded-For', $v = implode(', ', $trustedIps)); $request->server->set('HTTP_X_FORWARDED_FOR', $v); } // fix the client IP address by setting it to 127.0.0.1, // which is the core responsibility of this method $request->server->set('REMOTE_ADDR', '127.0.0.1'); // ensure 127.0.0.1 is set as trusted proxy if (!IpUtils::checkIp('127.0.0.1', $trustedProxies)) { Request::setTrustedProxies(array_merge($trustedProxies, ['127.0.0.1']), Request::getTrustedHeaderSet()); } try { return $kernel->handle($request, $type, $catch); } finally { // restore global state Request::setTrustedProxies($trustedProxies, $trustedHeaderSet); } } } HttpCache/ResponseCacheStrategyInterface.php 0000644 00000002037 15111167613 0015212 0 ustar 00 <?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * This code is partially based on the Rack-Cache library by Ryan Tomayko, * which is released under the MIT license. * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Response; /** * ResponseCacheStrategyInterface implementations know how to compute the * Response cache HTTP header based on the different response cache headers. * * @author Fabien Potencier <fabien@symfony.com> */ interface ResponseCacheStrategyInterface { /** * Adds a Response. * * @return void */ public function add(Response $response); /** * Updates the Response HTTP headers based on the embedded Responses. * * @return void */ public function update(Response $response); } HttpCache/HttpCache.php 0000644 00000065540 15111167613 0010777 0 ustar 00 <?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. */ /* * This code is partially based on the Rack-Cache library by Ryan Tomayko, * which is released under the MIT license. * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) */ namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\TerminableInterface; /** * Cache provides HTTP caching. * * @author Fabien Potencier <fabien@symfony.com> */ class HttpCache implements HttpKernelInterface, TerminableInterface { public const BODY_EVAL_BOUNDARY_LENGTH = 24; private HttpKernelInterface $kernel; private StoreInterface $store; private Request $request; private ?SurrogateInterface $surrogate; private ?ResponseCacheStrategyInterface $surrogateCacheStrategy = null; private array $options = []; private array $traces = []; /** * Constructor. * * The available options are: * * * debug If true, exceptions are thrown when things go wrong. Otherwise, the cache * will try to carry on and deliver a meaningful response. * * * trace_level May be one of 'none', 'short' and 'full'. For 'short', a concise trace of the * main request will be added as an HTTP header. 'full' will add traces for all * requests (including ESI subrequests). (default: 'full' if in debug; 'none' otherwise) * * * trace_header Header name to use for traces. (default: X-Symfony-Cache) * * * default_ttl The number of seconds that a cache entry should be considered * fresh when no explicit freshness information is provided in * a response. Explicit Cache-Control or Expires headers * override this value. (default: 0) * * * private_headers Set of request headers that trigger "private" cache-control behavior * on responses that don't explicitly state whether the response is * public or private via a Cache-Control directive. (default: Authorization and Cookie) * * * skip_response_headers Set of response headers that are never cached even if a response is cacheable (public). * (default: Set-Cookie) * * * allow_reload Specifies whether the client can force a cache reload by including a * Cache-Control "no-cache" directive in the request. Set it to ``true`` * for compliance with RFC 2616. (default: false) * * * allow_revalidate Specifies whether the client can force a cache revalidate by including * a Cache-Control "max-age=0" directive in the request. Set it to ``true`` * for compliance with RFC 2616. (default: false) * * * stale_while_revalidate Specifies the default number of seconds (the granularity is the second as the * Response TTL precision is a second) during which the cache can immediately return * a stale response while it revalidates it in the background (default: 2). * This setting is overridden by the stale-while-revalidate HTTP Cache-Control * extension (see RFC 5861). * * * stale_if_error Specifies the default number of seconds (the granularity is the second) during which * the cache can serve a stale response when an error is encountered (default: 60). * This setting is overridden by the stale-if-error HTTP Cache-Control extension * (see RFC 5861). * * * terminate_on_cache_hit Specifies if the kernel.terminate event should be dispatched even when the cache * was hit (default: true). * Unless your application needs to process events on cache hits, it is recommended * to set this to false to avoid having to bootstrap the Symfony framework on a cache hit. */ public function __construct(HttpKernelInterface $kernel, StoreInterface $store, SurrogateInterface $surrogate = null, array $options = []) { $this->store = $store; $this->kernel = $kernel; $this->surrogate = $surrogate; // needed in case there is a fatal error because the backend is too slow to respond register_shutdown_function($this->store->cleanup(...)); $this->options = array_merge([ 'debug' => false, 'default_ttl' => 0, 'private_headers' => ['Authorization', 'Cookie'], 'skip_response_headers' => ['Set-Cookie'], 'allow_reload' => false, 'allow_revalidate' => false, 'stale_while_revalidate' => 2, 'stale_if_error' => 60, 'trace_level' => 'none', 'trace_header' => 'X-Symfony-Cache', 'terminate_on_cache_hit' => true, ], $options); if (!isset($options['trace_level'])) { $this->options['trace_level'] = $this->options['debug'] ? 'full' : 'none'; } } /** * Gets the current store. */ public function getStore(): StoreInterface { return $this->store; } /** * Returns an array of events that took place during processing of the last request. */ public function getTraces(): array { return $this->traces; } private function addTraces(Response $response): void { $traceString = null; if ('full' === $this->options['trace_level']) { $traceString = $this->getLog(); } if ('short' === $this->options['trace_level'] && $masterId = array_key_first($this->traces)) { $traceString = implode('/', $this->traces[$masterId]); } if (null !== $traceString) { $response->headers->add([$this->options['trace_header'] => $traceString]); } } /** * Returns a log message for the events of the last request processing. */ public function getLog(): string { $log = []; foreach ($this->traces as $request => $traces) { $log[] = sprintf('%s: %s', $request, implode(', ', $traces)); } return implode('; ', $log); } /** * Gets the Request instance associated with the main request. */ public function getRequest(): Request { return $this->request; } /** * Gets the Kernel instance. */ public function getKernel(): HttpKernelInterface { return $this->kernel; } /** * Gets the Surrogate instance. * * @throws \LogicException */ public function getSurrogate(): SurrogateInterface { return $this->surrogate; } public function handle(Request $request, int $type = HttpKernelInterface::MAIN_REQUEST, bool $catch = true): Response { // FIXME: catch exceptions and implement a 500 error page here? -> in Varnish, there is a built-in error page mechanism if (HttpKernelInterface::MAIN_REQUEST === $type) { $this->traces = []; // Keep a clone of the original request for surrogates so they can access it. // We must clone here to get a separate instance because the application will modify the request during // the application flow (we know it always does because we do ourselves by setting REMOTE_ADDR to 127.0.0.1 // and adding the X-Forwarded-For header, see HttpCache::forward()). $this->request = clone $request; if (null !== $this->surrogate) { $this->surrogateCacheStrategy = $this->surrogate->createCacheStrategy(); } } $this->traces[$this->getTraceKey($request)] = []; if (!$request->isMethodSafe()) { $response = $this->invalidate($request, $catch); } elseif ($request->headers->has('expect') || !$request->isMethodCacheable()) { $response = $this->pass($request, $catch); } elseif ($this->options['allow_reload'] && $request->isNoCache()) { /* If allow_reload is configured and the client requests "Cache-Control: no-cache", reload the cache by fetching a fresh response and caching it (if possible). */ $this->record($request, 'reload'); $response = $this->fetch($request, $catch); } else { $response = $this->lookup($request, $catch); } $this->restoreResponseBody($request, $response); if (HttpKernelInterface::MAIN_REQUEST === $type) { $this->addTraces($response); } if (null !== $this->surrogate) { if (HttpKernelInterface::MAIN_REQUEST === $type) { $this->surrogateCacheStrategy->update($response); } else { $this->surrogateCacheStrategy->add($response); } } $response->prepare($request); $response->isNotModified($request); return $response; } /** * @return void */ public function terminate(Request $request, Response $response) { // Do not call any listeners in case of a cache hit. // This ensures identical behavior as if you had a separate // reverse caching proxy such as Varnish and the like. if ($this->options['terminate_on_cache_hit']) { trigger_deprecation('symfony/http-kernel', '6.2', 'Setting "terminate_on_cache_hit" to "true" is deprecated and will be changed to "false" in Symfony 7.0.'); } elseif (\in_array('fresh', $this->traces[$this->getTraceKey($request)] ?? [], true)) { return; } if ($this->getKernel() instanceof TerminableInterface) { $this->getKernel()->terminate($request, $response); } } /** * Forwards the Request to the backend without storing the Response in the cache. * * @param bool $catch Whether to process exceptions */ protected function pass(Request $request, bool $catch = false): Response { $this->record($request, 'pass'); return $this->forward($request, $catch); } /** * Invalidates non-safe methods (like POST, PUT, and DELETE). * * @param bool $catch Whether to process exceptions * * @throws \Exception * * @see RFC2616 13.10 */ protected function invalidate(Request $request, bool $catch = false): Response { $response = $this->pass($request, $catch); // invalidate only when the response is successful if ($response->isSuccessful() || $response->isRedirect()) { try { $this->store->invalidate($request); // As per the RFC, invalidate Location and Content-Location URLs if present foreach (['Location', 'Content-Location'] as $header) { if ($uri = $response->headers->get($header)) { $subRequest = Request::create($uri, 'get', [], [], [], $request->server->all()); $this->store->invalidate($subRequest); } } $this->record($request, 'invalidate'); } catch (\Exception $e) { $this->record($request, 'invalidate-failed'); if ($this->options['debug']) { throw $e; } } } return $response; } /** * Lookups a Response from the cache for the given Request. * * When a matching cache entry is found and is fresh, it uses it as the * response without forwarding any request to the backend. When a matching * cache entry is found but is stale, it attempts to "validate" the entry with * the backend using conditional GET. When no matching cache entry is found, * it triggers "miss" processing. * * @param bool $catch Whether to process exceptions * * @throws \Exception */ protected function lookup(Request $request, bool $catch = false): Response { try { $entry = $this->store->lookup($request); } catch (\Exception $e) { $this->record($request, 'lookup-failed'); if ($this->options['debug']) { throw $e; } return $this->pass($request, $catch); } if (null === $entry) { $this->record($request, 'miss'); return $this->fetch($request, $catch); } if (!$this->isFreshEnough($request, $entry)) { $this->record($request, 'stale'); return $this->validate($request, $entry, $catch); } if ($entry->headers->hasCacheControlDirective('no-cache')) { return $this->validate($request, $entry, $catch); } $this->record($request, 'fresh'); $entry->headers->set('Age', $entry->getAge()); return $entry; } /** * Validates that a cache entry is fresh. * * The original request is used as a template for a conditional * GET request with the backend. * * @param bool $catch Whether to process exceptions */ protected function validate(Request $request, Response $entry, bool $catch = false): Response { $subRequest = clone $request; // send no head requests because we want content if ('HEAD' === $request->getMethod()) { $subRequest->setMethod('GET'); } // add our cached last-modified validator if ($entry->headers->has('Last-Modified')) { $subRequest->headers->set('If-Modified-Since', $entry->headers->get('Last-Modified')); } // Add our cached etag validator to the environment. // We keep the etags from the client to handle the case when the client // has a different private valid entry which is not cached here. $cachedEtags = $entry->getEtag() ? [$entry->getEtag()] : []; $requestEtags = $request->getETags(); if ($etags = array_unique(array_merge($cachedEtags, $requestEtags))) { $subRequest->headers->set('If-None-Match', implode(', ', $etags)); } $response = $this->forward($subRequest, $catch, $entry); if (304 == $response->getStatusCode()) { $this->record($request, 'valid'); // return the response and not the cache entry if the response is valid but not cached $etag = $response->getEtag(); if ($etag && \in_array($etag, $requestEtags) && !\in_array($etag, $cachedEtags)) { return $response; } $entry = clone $entry; $entry->headers->remove('Date'); foreach (['Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified'] as $name) { if ($response->headers->has($name)) { $entry->headers->set($name, $response->headers->get($name)); } } $response = $entry; } else { $this->record($request, 'invalid'); } if ($response->isCacheable()) { $this->store($request, $response); } return $response; } /** * Unconditionally fetches a fresh response from the backend and * stores it in the cache if is cacheable. * * @param bool $catch Whether to process exceptions */ protected function fetch(Request $request, bool $catch = false): Response { $subRequest = clone $request; // send no head requests because we want content if ('HEAD' === $request->getMethod()) { $subRequest->setMethod('GET'); } // avoid that the backend sends no content $subRequest->headers->remove('If-Modified-Since'); $subRequest->headers->remove('If-None-Match'); $response = $this->forward($subRequest, $catch); if ($response->isCacheable()) { $this->store($request, $response); } return $response; } /** * Forwards the Request to the backend and returns the Response. * * All backend requests (cache passes, fetches, cache validations) * run through this method. * * @param bool $catch Whether to catch exceptions or not * @param Response|null $entry A Response instance (the stale entry if present, null otherwise) * * @return Response */ protected function forward(Request $request, bool $catch = false, Response $entry = null) { $this->surrogate?->addSurrogateCapability($request); // always a "master" request (as the real master request can be in cache) $response = SubRequestHandler::handle($this->kernel, $request, HttpKernelInterface::MAIN_REQUEST, $catch); /* * Support stale-if-error given on Responses or as a config option. * RFC 7234 summarizes in Section 4.2.4 (but also mentions with the individual * Cache-Control directives) that * * A cache MUST NOT generate a stale response if it is prohibited by an * explicit in-protocol directive (e.g., by a "no-store" or "no-cache" * cache directive, a "must-revalidate" cache-response-directive, or an * applicable "s-maxage" or "proxy-revalidate" cache-response-directive; * see Section 5.2.2). * * https://tools.ietf.org/html/rfc7234#section-4.2.4 * * We deviate from this in one detail, namely that we *do* serve entries in the * stale-if-error case even if they have a `s-maxage` Cache-Control directive. */ if (null !== $entry && \in_array($response->getStatusCode(), [500, 502, 503, 504]) && !$entry->headers->hasCacheControlDirective('no-cache') && !$entry->mustRevalidate() ) { if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) { $age = $this->options['stale_if_error']; } /* * stale-if-error gives the (extra) time that the Response may be used *after* it has become stale. * So we compare the time the $entry has been sitting in the cache already with the * time it was fresh plus the allowed grace period. */ if ($entry->getAge() <= $entry->getMaxAge() + $age) { $this->record($request, 'stale-if-error'); return $entry; } } /* RFC 7231 Sect. 7.1.1.2 says that a server that does not have a reasonably accurate clock MUST NOT send a "Date" header, although it MUST send one in most other cases except for 1xx or 5xx responses where it MAY do so. Anyway, a client that received a message without a "Date" header MUST add it. */ if (!$response->headers->has('Date')) { $response->setDate(\DateTimeImmutable::createFromFormat('U', time())); } $this->processResponseBody($request, $response); if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { $response->setPrivate(); } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { $response->setTtl($this->options['default_ttl']); } return $response; } /** * Checks whether the cache entry is "fresh enough" to satisfy the Request. */ protected function isFreshEnough(Request $request, Response $entry): bool { if (!$entry->isFresh()) { return $this->lock($request, $entry); } if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) { return $maxAge > 0 && $maxAge >= $entry->getAge(); } return true; } /** * Locks a Request during the call to the backend. * * @return bool true if the cache entry can be returned even if it is staled, false otherwise */ protected function lock(Request $request, Response $entry): bool { // try to acquire a lock to call the backend $lock = $this->store->lock($request); if (true === $lock) { // we have the lock, call the backend return false; } // there is already another process calling the backend // May we serve a stale response? if ($this->mayServeStaleWhileRevalidate($entry)) { $this->record($request, 'stale-while-revalidate'); return true; } // wait for the lock to be released if ($this->waitForLock($request)) { // replace the current entry with the fresh one $new = $this->lookup($request); $entry->headers = $new->headers; $entry->setContent($new->getContent()); $entry->setStatusCode($new->getStatusCode()); $entry->setProtocolVersion($new->getProtocolVersion()); foreach ($new->headers->getCookies() as $cookie) { $entry->headers->setCookie($cookie); } } else { // backend is slow as hell, send a 503 response (to avoid the dog pile effect) $entry->setStatusCode(503); $entry->setContent('503 Service Unavailable'); $entry->headers->set('Retry-After', 10); } return true; } /** * Writes the Response to the cache. * * @return void * * @throws \Exception */ protected function store(Request $request, Response $response) { try { $restoreHeaders = []; foreach ($this->options['skip_response_headers'] as $header) { if (!$response->headers->has($header)) { continue; } $restoreHeaders[$header] = $response->headers->all($header); $response->headers->remove($header); } $this->store->write($request, $response); $this->record($request, 'store'); $response->headers->set('Age', $response->getAge()); } catch (\Exception $e) { $this->record($request, 'store-failed'); if ($this->options['debug']) { throw $e; } } finally { foreach ($restoreHeaders as $header => $values) { $response->headers->set($header, $values); } } // now that the response is cached, release the lock $this->store->unlock($request); } /** * Restores the Response body. */ private function restoreResponseBody(Request $request, Response $response): void { if ($response->headers->has('X-Body-Eval')) { \assert(self::BODY_EVAL_BOUNDARY_LENGTH === 24); ob_start(); $content = $response->getContent(); $boundary = substr($content, 0, 24); $j = strpos($content, $boundary, 24); echo substr($content, 24, $j - 24); $i = $j + 24; while (false !== $j = strpos($content, $boundary, $i)) { [$uri, $alt, $ignoreErrors, $part] = explode("\n", substr($content, $i, $j - $i), 4); $i = $j + 24; echo $this->surrogate->handle($this, $uri, $alt, $ignoreErrors); echo $part; } $response->setContent(ob_get_clean()); $response->headers->remove('X-Body-Eval'); if (!$response->headers->has('Transfer-Encoding')) { $response->headers->set('Content-Length', \strlen($response->getContent())); } } elseif ($response->headers->has('X-Body-File')) { // Response does not include possibly dynamic content (ESI, SSI), so we need // not handle the content for HEAD requests if (!$request->isMethod('HEAD')) { $response->setContent(file_get_contents($response->headers->get('X-Body-File'))); } } else { return; } $response->headers->remove('X-Body-File'); } /** * @return void */ protected function processResponseBody(Request $request, Response $response) { if ($this->surrogate?->needsParsing($response)) { $this->surrogate->process($request, $response); } } /** * Checks if the Request includes authorization or other sensitive information * that should cause the Response to be considered private by default. */ private function isPrivateRequest(Request $request): bool { foreach ($this->options['private_headers'] as $key) { $key = strtolower(str_replace('HTTP_', '', $key)); if ('cookie' === $key) { if (\count($request->cookies->all())) { return true; } } elseif ($request->headers->has($key)) { return true; } } return false; } /** * Records that an event took place. */ private function record(Request $request, string $event): void { $this->traces[$this->getTraceKey($request)][] = $event; } /** * Calculates the key we use in the "trace" array for a given request. */ private function getTraceKey(Request $request): string { $path = $request->getPathInfo(); if ($qs = $request->getQueryString()) { $path .= '?'.$qs; } return $request->getMethod().' '.$path; } /** * Checks whether the given (cached) response may be served as "stale" when a revalidation * is currently in progress. */ private function mayServeStaleWhileRevalidate(Response $entry): bool { $timeout = $entry->headers->getCacheControlDirective('stale-while-revalidate'); $timeout ??= $this->options['stale_while_revalidate']; $age = $entry->getAge(); $maxAge = $entry->getMaxAge() ?? 0; $ttl = $maxAge - $age; return abs($ttl) < $timeout; } /** * Waits for the store to release a locked entry. */ private function waitForLock(Request $request): bool { $wait = 0; while ($this->store->isLocked($request) && $wait < 100) { usleep(50000); ++$wait; } return $wait < 100; } } HttpCache/Store.php 0000644 00000034561 15111167613 0010227 0 ustar 00 <?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * This code is partially based on the Rack-Cache library by Ryan Tomayko, * which is released under the MIT license. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Store implements all the logic for storing cache metadata (Request and Response headers). * * @author Fabien Potencier <fabien@symfony.com> */ class Store implements StoreInterface { protected $root; /** @var \SplObjectStorage<Request, string> */ private \SplObjectStorage $keyCache; /** @var array<string, resource> */ private array $locks = []; private array $options; /** * Constructor. * * The available options are: * * * private_headers Set of response headers that should not be stored * when a response is cached. (default: Set-Cookie) * * @throws \RuntimeException */ public function __construct(string $root, array $options = []) { $this->root = $root; if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) { throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root)); } $this->keyCache = new \SplObjectStorage(); $this->options = array_merge([ 'private_headers' => ['Set-Cookie'], ], $options); } /** * Cleanups storage. * * @return void */ public function cleanup() { // unlock everything foreach ($this->locks as $lock) { flock($lock, \LOCK_UN); fclose($lock); } $this->locks = []; } /** * Tries to lock the cache for a given Request, without blocking. * * @return bool|string true if the lock is acquired, the path to the current lock otherwise */ public function lock(Request $request): bool|string { $key = $this->getCacheKey($request); if (!isset($this->locks[$key])) { $path = $this->getPath($key); if (!is_dir(\dirname($path)) && false === @mkdir(\dirname($path), 0777, true) && !is_dir(\dirname($path))) { return $path; } $h = fopen($path, 'c'); if (!flock($h, \LOCK_EX | \LOCK_NB)) { fclose($h); return $path; } $this->locks[$key] = $h; } return true; } /** * Releases the lock for the given Request. * * @return bool False if the lock file does not exist or cannot be unlocked, true otherwise */ public function unlock(Request $request): bool { $key = $this->getCacheKey($request); if (isset($this->locks[$key])) { flock($this->locks[$key], \LOCK_UN); fclose($this->locks[$key]); unset($this->locks[$key]); return true; } return false; } public function isLocked(Request $request): bool { $key = $this->getCacheKey($request); if (isset($this->locks[$key])) { return true; // shortcut if lock held by this process } if (!is_file($path = $this->getPath($key))) { return false; } $h = fopen($path, 'r'); flock($h, \LOCK_EX | \LOCK_NB, $wouldBlock); flock($h, \LOCK_UN); // release the lock we just acquired fclose($h); return (bool) $wouldBlock; } /** * Locates a cached Response for the Request provided. */ public function lookup(Request $request): ?Response { $key = $this->getCacheKey($request); if (!$entries = $this->getMetadata($key)) { return null; } // find a cached entry that matches the request. $match = null; foreach ($entries as $entry) { if ($this->requestsMatch(isset($entry[1]['vary'][0]) ? implode(', ', $entry[1]['vary']) : '', $request->headers->all(), $entry[0])) { $match = $entry; break; } } if (null === $match) { return null; } $headers = $match[1]; if (file_exists($path = $this->getPath($headers['x-content-digest'][0]))) { return $this->restoreResponse($headers, $path); } // TODO the metaStore referenced an entity that doesn't exist in // the entityStore. We definitely want to return nil but we should // also purge the entry from the meta-store when this is detected. return null; } /** * Writes a cache entry to the store for the given Request and Response. * * Existing entries are read and any that match the response are removed. This * method calls write with the new list of cache entries. * * @throws \RuntimeException */ public function write(Request $request, Response $response): string { $key = $this->getCacheKey($request); $storedEnv = $this->persistRequest($request); if ($response->headers->has('X-Body-File')) { // Assume the response came from disk, but at least perform some safeguard checks if (!$response->headers->has('X-Content-Digest')) { throw new \RuntimeException('A restored response must have the X-Content-Digest header.'); } $digest = $response->headers->get('X-Content-Digest'); if ($this->getPath($digest) !== $response->headers->get('X-Body-File')) { throw new \RuntimeException('X-Body-File and X-Content-Digest do not match.'); } // Everything seems ok, omit writing content to disk } else { $digest = $this->generateContentDigest($response); $response->headers->set('X-Content-Digest', $digest); if (!$this->save($digest, $response->getContent(), false)) { throw new \RuntimeException('Unable to store the entity.'); } if (!$response->headers->has('Transfer-Encoding')) { $response->headers->set('Content-Length', \strlen($response->getContent())); } } // read existing cache entries, remove non-varying, and add this one to the list $entries = []; $vary = $response->headers->get('vary'); foreach ($this->getMetadata($key) as $entry) { if (!isset($entry[1]['vary'][0])) { $entry[1]['vary'] = ['']; } if ($entry[1]['vary'][0] != $vary || !$this->requestsMatch($vary ?? '', $entry[0], $storedEnv)) { $entries[] = $entry; } } $headers = $this->persistResponse($response); unset($headers['age']); foreach ($this->options['private_headers'] as $h) { unset($headers[strtolower($h)]); } array_unshift($entries, [$storedEnv, $headers]); if (!$this->save($key, serialize($entries))) { throw new \RuntimeException('Unable to store the metadata.'); } return $key; } /** * Returns content digest for $response. */ protected function generateContentDigest(Response $response): string { return 'en'.hash('xxh128', $response->getContent()); } /** * Invalidates all cache entries that match the request. * * @return void * * @throws \RuntimeException */ public function invalidate(Request $request) { $modified = false; $key = $this->getCacheKey($request); $entries = []; foreach ($this->getMetadata($key) as $entry) { $response = $this->restoreResponse($entry[1]); if ($response->isFresh()) { $response->expire(); $modified = true; $entries[] = [$entry[0], $this->persistResponse($response)]; } else { $entries[] = $entry; } } if ($modified && !$this->save($key, serialize($entries))) { throw new \RuntimeException('Unable to store the metadata.'); } } /** * Determines whether two Request HTTP header sets are non-varying based on * the vary response header value provided. * * @param string|null $vary A Response vary header * @param array $env1 A Request HTTP header array * @param array $env2 A Request HTTP header array */ private function requestsMatch(?string $vary, array $env1, array $env2): bool { if (empty($vary)) { return true; } foreach (preg_split('/[\s,]+/', $vary) as $header) { $key = str_replace('_', '-', strtolower($header)); $v1 = $env1[$key] ?? null; $v2 = $env2[$key] ?? null; if ($v1 !== $v2) { return false; } } return true; } /** * Gets all data associated with the given key. * * Use this method only if you know what you are doing. */ private function getMetadata(string $key): array { if (!$entries = $this->load($key)) { return []; } return unserialize($entries) ?: []; } /** * Purges data for the given URL. * * This method purges both the HTTP and the HTTPS version of the cache entry. * * @return bool true if the URL exists with either HTTP or HTTPS scheme and has been purged, false otherwise */ public function purge(string $url): bool { $http = preg_replace('#^https:#', 'http:', $url); $https = preg_replace('#^http:#', 'https:', $url); $purgedHttp = $this->doPurge($http); $purgedHttps = $this->doPurge($https); return $purgedHttp || $purgedHttps; } /** * Purges data for the given URL. */ private function doPurge(string $url): bool { $key = $this->getCacheKey(Request::create($url)); if (isset($this->locks[$key])) { flock($this->locks[$key], \LOCK_UN); fclose($this->locks[$key]); unset($this->locks[$key]); } if (is_file($path = $this->getPath($key))) { unlink($path); return true; } return false; } /** * Loads data for the given key. */ private function load(string $key): ?string { $path = $this->getPath($key); return is_file($path) && false !== ($contents = @file_get_contents($path)) ? $contents : null; } /** * Save data for the given key. */ private function save(string $key, string $data, bool $overwrite = true): bool { $path = $this->getPath($key); if (!$overwrite && file_exists($path)) { return true; } if (isset($this->locks[$key])) { $fp = $this->locks[$key]; @ftruncate($fp, 0); @fseek($fp, 0); $len = @fwrite($fp, $data); if (\strlen($data) !== $len) { @ftruncate($fp, 0); return false; } } else { if (!is_dir(\dirname($path)) && false === @mkdir(\dirname($path), 0777, true) && !is_dir(\dirname($path))) { return false; } $tmpFile = tempnam(\dirname($path), basename($path)); if (false === $fp = @fopen($tmpFile, 'w')) { @unlink($tmpFile); return false; } @fwrite($fp, $data); @fclose($fp); if ($data != file_get_contents($tmpFile)) { @unlink($tmpFile); return false; } if (false === @rename($tmpFile, $path)) { @unlink($tmpFile); return false; } } @chmod($path, 0666 & ~umask()); return true; } /** * @return string */ public function getPath(string $key) { return $this->root.\DIRECTORY_SEPARATOR.substr($key, 0, 2).\DIRECTORY_SEPARATOR.substr($key, 2, 2).\DIRECTORY_SEPARATOR.substr($key, 4, 2).\DIRECTORY_SEPARATOR.substr($key, 6); } /** * Generates a cache key for the given Request. * * This method should return a key that must only depend on a * normalized version of the request URI. * * If the same URI can have more than one representation, based on some * headers, use a Vary header to indicate them, and each representation will * be stored independently under the same cache key. */ protected function generateCacheKey(Request $request): string { return 'md'.hash('sha256', $request->getUri()); } /** * Returns a cache key for the given Request. */ private function getCacheKey(Request $request): string { if (isset($this->keyCache[$request])) { return $this->keyCache[$request]; } return $this->keyCache[$request] = $this->generateCacheKey($request); } /** * Persists the Request HTTP headers. */ private function persistRequest(Request $request): array { return $request->headers->all(); } /** * Persists the Response HTTP headers. */ private function persistResponse(Response $response): array { $headers = $response->headers->all(); $headers['X-Status'] = [$response->getStatusCode()]; return $headers; } /** * Restores a Response from the HTTP headers and body. */ private function restoreResponse(array $headers, string $path = null): ?Response { $status = $headers['X-Status'][0]; unset($headers['X-Status']); $content = null; if (null !== $path) { $headers['X-Body-File'] = [$path]; unset($headers['x-body-file']); if ($headers['X-Body-Eval'] ?? $headers['x-body-eval'] ?? false) { $content = file_get_contents($path); \assert(HttpCache::BODY_EVAL_BOUNDARY_LENGTH === 24); if (48 > \strlen($content) || substr($content, -24) !== substr($content, 0, 24)) { return null; } } } return new Response($content, $status, $headers); } } HttpCache/SurrogateInterface.php 0000644 00000004155 15111167613 0012723 0 ustar 00 <?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\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; interface SurrogateInterface { /** * Returns surrogate name. */ public function getName(): string; /** * Returns a new cache strategy instance. */ public function createCacheStrategy(): ResponseCacheStrategyInterface; /** * Checks that at least one surrogate has Surrogate capability. */ public function hasSurrogateCapability(Request $request): bool; /** * Adds Surrogate-capability to the given Request. * * @return void */ public function addSurrogateCapability(Request $request); /** * Adds HTTP headers to specify that the Response needs to be parsed for Surrogate. * * This method only adds an Surrogate HTTP header if the Response has some Surrogate tags. * * @return void */ public function addSurrogateControl(Response $response); /** * Checks that the Response needs to be parsed for Surrogate tags. */ public function needsParsing(Response $response): bool; /** * Renders a Surrogate tag. * * @param string|null $alt An alternate URI * @param string $comment A comment to add as an esi:include tag */ public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string; /** * Replaces a Response Surrogate tags with the included resource content. */ public function process(Request $request, Response $response): Response; /** * Handles a Surrogate from the cache. * * @param string $alt An alternative URI * * @throws \RuntimeException * @throws \Exception */ public function handle(HttpCache $cache, string $uri, string $alt, bool $ignoreErrors): string; } HttpCache/ResponseCacheStrategy.php 0000644 00000022072 15111167613 0013372 0 ustar 00 <?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\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Response; /** * ResponseCacheStrategy knows how to compute the Response cache HTTP header * based on the different response cache headers. * * This implementation changes the main response TTL to the smallest TTL received * or force validation if one of the surrogates has validation cache strategy. * * @author Fabien Potencier <fabien@symfony.com> */ class ResponseCacheStrategy implements ResponseCacheStrategyInterface { /** * Cache-Control headers that are sent to the final response if they appear in ANY of the responses. */ private const OVERRIDE_DIRECTIVES = ['private', 'no-cache', 'no-store', 'no-transform', 'must-revalidate', 'proxy-revalidate']; /** * Cache-Control headers that are sent to the final response if they appear in ALL of the responses. */ private const INHERIT_DIRECTIVES = ['public', 'immutable']; private int $embeddedResponses = 0; private bool $isNotCacheableResponseEmbedded = false; private int $age = 0; private \DateTimeInterface|null|false $lastModified = null; private array $flagDirectives = [ 'no-cache' => null, 'no-store' => null, 'no-transform' => null, 'must-revalidate' => null, 'proxy-revalidate' => null, 'public' => null, 'private' => null, 'immutable' => null, ]; private array $ageDirectives = [ 'max-age' => null, 's-maxage' => null, 'expires' => null, ]; /** * @return void */ public function add(Response $response) { ++$this->embeddedResponses; foreach (self::OVERRIDE_DIRECTIVES as $directive) { if ($response->headers->hasCacheControlDirective($directive)) { $this->flagDirectives[$directive] = true; } } foreach (self::INHERIT_DIRECTIVES as $directive) { if (false !== $this->flagDirectives[$directive]) { $this->flagDirectives[$directive] = $response->headers->hasCacheControlDirective($directive); } } $age = $response->getAge(); $this->age = max($this->age, $age); if ($this->willMakeFinalResponseUncacheable($response)) { $this->isNotCacheableResponseEmbedded = true; return; } $isHeuristicallyCacheable = $response->headers->hasCacheControlDirective('public'); $maxAge = $response->headers->hasCacheControlDirective('max-age') ? (int) $response->headers->getCacheControlDirective('max-age') : null; $this->storeRelativeAgeDirective('max-age', $maxAge, $age, $isHeuristicallyCacheable); $sharedMaxAge = $response->headers->hasCacheControlDirective('s-maxage') ? (int) $response->headers->getCacheControlDirective('s-maxage') : $maxAge; $this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $age, $isHeuristicallyCacheable); $expires = $response->getExpires(); $expires = null !== $expires ? (int) $expires->format('U') - (int) $response->getDate()->format('U') : null; $this->storeRelativeAgeDirective('expires', $expires >= 0 ? $expires : null, 0, $isHeuristicallyCacheable); if (false !== $this->lastModified) { $lastModified = $response->getLastModified(); $this->lastModified = $lastModified ? max($this->lastModified, $lastModified) : false; } } /** * @return void */ public function update(Response $response) { // if we have no embedded Response, do nothing if (0 === $this->embeddedResponses) { return; } // Remove Etag since it cannot be merged from embedded responses. $response->setEtag(null); $this->add($response); $response->headers->set('Age', $this->age); if ($this->isNotCacheableResponseEmbedded) { $response->setLastModified(null); if ($this->flagDirectives['no-store']) { $response->headers->set('Cache-Control', 'no-cache, no-store, must-revalidate'); } else { $response->headers->set('Cache-Control', 'no-cache, must-revalidate'); } return; } $response->setLastModified($this->lastModified ?: null); $flags = array_filter($this->flagDirectives); if (isset($flags['must-revalidate'])) { $flags['no-cache'] = true; } $response->headers->set('Cache-Control', implode(', ', array_keys($flags))); $maxAge = null; if (is_numeric($this->ageDirectives['max-age'])) { $maxAge = $this->ageDirectives['max-age'] + $this->age; $response->headers->addCacheControlDirective('max-age', $maxAge); } if (is_numeric($this->ageDirectives['s-maxage'])) { $sMaxage = $this->ageDirectives['s-maxage'] + $this->age; if ($maxAge !== $sMaxage) { $response->headers->addCacheControlDirective('s-maxage', $sMaxage); } } if (is_numeric($this->ageDirectives['expires'])) { $date = clone $response->getDate(); $date = $date->modify('+'.($this->ageDirectives['expires'] + $this->age).' seconds'); $response->setExpires($date); } } /** * RFC2616, Section 13.4. * * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4 */ private function willMakeFinalResponseUncacheable(Response $response): bool { // RFC2616: A response received with a status code of 200, 203, 300, 301 or 410 // MAY be stored by a cache […] unless a cache-control directive prohibits caching. if ($response->headers->hasCacheControlDirective('no-cache') || $response->headers->hasCacheControlDirective('no-store') ) { return true; } // Etag headers cannot be merged, they render the response uncacheable // by default (except if the response also has max-age etc.). if (null === $response->getEtag() && \in_array($response->getStatusCode(), [200, 203, 300, 301, 410])) { return false; } // RFC2616: A response received with any other status code (e.g. status codes 302 and 307) // MUST NOT be returned in a reply to a subsequent request unless there are // cache-control directives or another header(s) that explicitly allow it. $cacheControl = ['max-age', 's-maxage', 'must-revalidate', 'proxy-revalidate', 'public', 'private']; foreach ($cacheControl as $key) { if ($response->headers->hasCacheControlDirective($key)) { return false; } } if ($response->headers->has('Expires')) { return false; } return true; } /** * Store lowest max-age/s-maxage/expires for the final response. * * The response might have been stored in cache a while ago. To keep things comparable, * we have to subtract the age so that the value is normalized for an age of 0. * * If the value is lower than the currently stored value, we update the value, to keep a rolling * minimal value of each instruction. * * If the value is NULL and the isHeuristicallyCacheable parameter is false, the directive will * not be set on the final response. In this case, not all responses had the directive set and no * value can be found that satisfies the requirements of all responses. The directive will be dropped * from the final response. * * If the isHeuristicallyCacheable parameter is true, however, the current response has been marked * as cacheable in a public (shared) cache, but did not provide an explicit lifetime that would serve * as an upper bound. In this case, we can proceed and possibly keep the directive on the final response. */ private function storeRelativeAgeDirective(string $directive, ?int $value, int $age, bool $isHeuristicallyCacheable): void { if (null === $value) { if ($isHeuristicallyCacheable) { /* * See https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2 * This particular response does not require maximum lifetime; heuristics might be applied. * Other responses, however, might have more stringent requirements on maximum lifetime. * So, return early here so that the final response can have the more limiting value set. */ return; } $this->ageDirectives[$directive] = false; } if (false !== $this->ageDirectives[$directive]) { $value -= $age; $this->ageDirectives[$directive] = null !== $this->ageDirectives[$directive] ? min($this->ageDirectives[$directive], $value) : $value; } } } HttpCache/error_log 0000644 00000010426 15111167613 0010331 0 ustar 00 [19-Nov-2025 15:58:05 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpCache\SurrogateInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php on line 24 [19-Nov-2025 16:01:53 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpCache\ResponseCacheStrategyInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php on line 25 [19-Nov-2025 16:08:42 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\HttpCache\AbstractSurrogate" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Ssi.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Ssi.php on line 22 [19-Nov-2025 16:09:38 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\HttpCache\AbstractSurrogate" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Esi.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Esi.php on line 28 [19-Nov-2025 16:17:23 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpCache\StoreInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Store.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Store.php on line 25 [19-Nov-2025 17:57:23 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/HttpCache.php:30 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/HttpCache.php on line 30 [19-Nov-2025 20:35:50 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpCache\SurrogateInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php on line 24 [19-Nov-2025 20:50:32 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpCache\ResponseCacheStrategyInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php on line 25 [19-Nov-2025 21:10:01 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\HttpCache\AbstractSurrogate" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Esi.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Esi.php on line 28 [19-Nov-2025 21:10:16 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\HttpCache\AbstractSurrogate" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Ssi.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Ssi.php on line 22 [19-Nov-2025 21:14:34 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpCache\StoreInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Store.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/Store.php on line 25 [20-Nov-2025 00:46:05 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\HttpKernelInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/HttpCache.php:30 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/HttpCache/HttpCache.php on line 30 HttpCache/AbstractSurrogate.php 0000644 00000011221 15111167613 0012556 0 ustar 00 <?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\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Abstract class implementing Surrogate capabilities to Request and Response instances. * * @author Fabien Potencier <fabien@symfony.com> * @author Robin Chalas <robin.chalas@gmail.com> */ abstract class AbstractSurrogate implements SurrogateInterface { protected $contentTypes; /** * @deprecated since Symfony 6.3 */ protected $phpEscapeMap = [ ['<?', '<%', '<s', '<S'], ['<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'], ]; /** * @param array $contentTypes An array of content-type that should be parsed for Surrogate information * (default: text/html, text/xml, application/xhtml+xml, and application/xml) */ public function __construct(array $contentTypes = ['text/html', 'text/xml', 'application/xhtml+xml', 'application/xml']) { $this->contentTypes = $contentTypes; } /** * Returns a new cache strategy instance. */ public function createCacheStrategy(): ResponseCacheStrategyInterface { return new ResponseCacheStrategy(); } public function hasSurrogateCapability(Request $request): bool { if (null === $value = $request->headers->get('Surrogate-Capability')) { return false; } return str_contains($value, sprintf('%s/1.0', strtoupper($this->getName()))); } /** * @return void */ public function addSurrogateCapability(Request $request) { $current = $request->headers->get('Surrogate-Capability'); $new = sprintf('symfony="%s/1.0"', strtoupper($this->getName())); $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); } public function needsParsing(Response $response): bool { if (!$control = $response->headers->get('Surrogate-Control')) { return false; } $pattern = sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName())); return (bool) preg_match($pattern, $control); } public function handle(HttpCache $cache, string $uri, string $alt, bool $ignoreErrors): string { $subRequest = Request::create($uri, Request::METHOD_GET, [], $cache->getRequest()->cookies->all(), [], $cache->getRequest()->server->all()); try { $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); if (!$response->isSuccessful() && Response::HTTP_NOT_MODIFIED !== $response->getStatusCode()) { throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %d).', $subRequest->getUri(), $response->getStatusCode())); } return $response->getContent(); } catch (\Exception $e) { if ($alt) { return $this->handle($cache, $alt, '', $ignoreErrors); } if (!$ignoreErrors) { throw $e; } } return ''; } /** * Remove the Surrogate from the Surrogate-Control header. * * @return void */ protected function removeFromControl(Response $response) { if (!$response->headers->has('Surrogate-Control')) { return; } $value = $response->headers->get('Surrogate-Control'); $upperName = strtoupper($this->getName()); if (sprintf('content="%s/1.0"', $upperName) == $value) { $response->headers->remove('Surrogate-Control'); } elseif (preg_match(sprintf('#,\s*content="%s/1.0"#', $upperName), $value)) { $response->headers->set('Surrogate-Control', preg_replace(sprintf('#,\s*content="%s/1.0"#', $upperName), '', $value)); } elseif (preg_match(sprintf('#content="%s/1.0",\s*#', $upperName), $value)) { $response->headers->set('Surrogate-Control', preg_replace(sprintf('#content="%s/1.0",\s*#', $upperName), '', $value)); } } protected static function generateBodyEvalBoundary(): string { static $cookie; $cookie = hash('xxh128', $cookie ?? $cookie = random_bytes(16), true); $boundary = base64_encode($cookie); \assert(HttpCache::BODY_EVAL_BOUNDARY_LENGTH === \strlen($boundary)); return $boundary; } } HttpCache/Ssi.php 0000644 00000005034 15111167613 0007662 0 ustar 00 <?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\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Ssi implements the SSI capabilities to Request and Response instances. * * @author Sebastian Krebs <krebs.seb@gmail.com> */ class Ssi extends AbstractSurrogate { public function getName(): string { return 'ssi'; } /** * @return void */ public function addSurrogateControl(Response $response) { if (str_contains($response->getContent(), '<!--#include')) { $response->headers->set('Surrogate-Control', 'content="SSI/1.0"'); } } public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string { return sprintf('<!--#include virtual="%s" -->', $uri); } public function process(Request $request, Response $response): Response { $type = $response->headers->get('Content-Type'); if (empty($type)) { $type = 'text/html'; } $parts = explode(';', $type); if (!\in_array($parts[0], $this->contentTypes)) { return $response; } // we don't use a proper XML parser here as we can have SSI tags in a plain text response $content = $response->getContent(); $boundary = self::generateBodyEvalBoundary(); $chunks = preg_split('#<!--\#include\s+(.*?)\s*-->#', $content, -1, \PREG_SPLIT_DELIM_CAPTURE); $i = 1; while (isset($chunks[$i])) { $options = []; preg_match_all('/(virtual)="([^"]*?)"/', $chunks[$i], $matches, \PREG_SET_ORDER); foreach ($matches as $set) { $options[$set[1]] = $set[2]; } if (!isset($options['virtual'])) { throw new \RuntimeException('Unable to process an SSI tag without a "virtual" attribute.'); } $chunks[$i] = $boundary.$options['virtual']."\n\n\n"; $i += 2; } $content = $boundary.implode('', $chunks).$boundary; $response->setContent($content); $response->headers->set('X-Body-Eval', 'SSI'); // remove SSI/1.0 from the Surrogate-Control header $this->removeFromControl($response); return $response; } } HttpCache/StoreInterface.php 0000644 00000004264 15111167613 0012045 0 ustar 00 <?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * This code is partially based on the Rack-Cache library by Ryan Tomayko, * which is released under the MIT license. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\HttpKernel\HttpCache; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Interface implemented by HTTP cache stores. * * @author Fabien Potencier <fabien@symfony.com> */ interface StoreInterface { /** * Locates a cached Response for the Request provided. */ public function lookup(Request $request): ?Response; /** * Writes a cache entry to the store for the given Request and Response. * * Existing entries are read and any that match the response are removed. This * method calls write with the new list of cache entries. * * @return string The key under which the response is stored */ public function write(Request $request, Response $response): string; /** * Invalidates all cache entries that match the request. * * @return void */ public function invalidate(Request $request); /** * Locks the cache for a given Request. * * @return bool|string true if the lock is acquired, the path to the current lock otherwise */ public function lock(Request $request): bool|string; /** * Releases the lock for the given Request. * * @return bool False if the lock file does not exist or cannot be unlocked, true otherwise */ public function unlock(Request $request): bool; /** * Returns whether or not a lock exists. * * @return bool true if lock exists, false otherwise */ public function isLocked(Request $request): bool; /** * Purges data for the given URL. * * @return bool true if the URL exists and has been purged, false otherwise */ public function purge(string $url): bool; /** * Cleanups storage. * * @return void */ public function cleanup(); } DependencyInjection/FragmentRendererPass.php 0000644 00000004101 15111167613 0015255 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface; /** * Adds services tagged kernel.fragment_renderer as HTTP content rendering strategies. * * @author Fabien Potencier <fabien@symfony.com> */ class FragmentRendererPass implements CompilerPassInterface { /** * @return void */ public function process(ContainerBuilder $container) { if (!$container->hasDefinition('fragment.handler')) { return; } $definition = $container->getDefinition('fragment.handler'); $renderers = []; foreach ($container->findTaggedServiceIds('kernel.fragment_renderer', true) as $id => $tags) { $def = $container->getDefinition($id); $class = $container->getParameterBag()->resolveValue($def->getClass()); if (!$r = $container->getReflectionClass($class)) { throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } if (!$r->isSubclassOf(FragmentRendererInterface::class)) { throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, FragmentRendererInterface::class)); } foreach ($tags as $tag) { $renderers[$tag['alias']] = new Reference($id); } } $definition->replaceArgument(0, ServiceLocatorTagPass::register($container, $renderers)); } } DependencyInjection/RegisterControllerArgumentLocatorsPass.php 0000644 00000026113 15111167613 0021074 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DependencyInjection\Attribute\AutowireCallable; use Symfony\Component\DependencyInjection\Attribute\Target; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\VarExporter\ProxyHelper; /** * Creates the service-locators required by ServiceValueResolver. * * @author Nicolas Grekas <p@tchwork.com> */ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface { /** * @return void */ public function process(ContainerBuilder $container) { if (!$container->hasDefinition('argument_resolver.service') && !$container->hasDefinition('argument_resolver.not_tagged_controller')) { return; } $parameterBag = $container->getParameterBag(); $controllers = []; $publicAliases = []; foreach ($container->getAliases() as $id => $alias) { if ($alias->isPublic() && !$alias->isPrivate()) { $publicAliases[(string) $alias][] = $id; } } $emptyAutowireAttributes = class_exists(Autowire::class) ? null : []; foreach ($container->findTaggedServiceIds('controller.service_arguments', true) as $id => $tags) { $def = $container->getDefinition($id); $def->setPublic(true); $class = $def->getClass(); $autowire = $def->isAutowired(); $bindings = $def->getBindings(); // resolve service class, taking parent definitions into account while ($def instanceof ChildDefinition) { $def = $container->findDefinition($def->getParent()); $class = $class ?: $def->getClass(); $bindings += $def->getBindings(); } $class = $parameterBag->resolveValue($class); if (!$r = $container->getReflectionClass($class)) { throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } // get regular public methods $methods = []; $arguments = []; foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $r) { if ('setContainer' === $r->name) { continue; } if (!$r->isConstructor() && !$r->isDestructor() && !$r->isAbstract()) { $methods[strtolower($r->name)] = [$r, $r->getParameters()]; } } // validate and collect explicit per-actions and per-arguments service references foreach ($tags as $attributes) { if (!isset($attributes['action']) && !isset($attributes['argument']) && !isset($attributes['id'])) { $autowire = true; continue; } foreach (['action', 'argument', 'id'] as $k) { if (!isset($attributes[$k][0])) { throw new InvalidArgumentException(sprintf('Missing "%s" attribute on tag "controller.service_arguments" %s for service "%s".', $k, json_encode($attributes, \JSON_UNESCAPED_UNICODE), $id)); } } if (!isset($methods[$action = strtolower($attributes['action'])])) { throw new InvalidArgumentException(sprintf('Invalid "action" attribute on tag "controller.service_arguments" for service "%s": no public "%s()" method found on class "%s".', $id, $attributes['action'], $class)); } [$r, $parameters] = $methods[$action]; $found = false; foreach ($parameters as $p) { if ($attributes['argument'] === $p->name) { if (!isset($arguments[$r->name][$p->name])) { $arguments[$r->name][$p->name] = $attributes['id']; } $found = true; break; } } if (!$found) { throw new InvalidArgumentException(sprintf('Invalid "controller.service_arguments" tag for service "%s": method "%s()" has no "%s" argument on class "%s".', $id, $r->name, $attributes['argument'], $class)); } } foreach ($methods as [$r, $parameters]) { /** @var \ReflectionMethod $r */ // create a per-method map of argument-names to service/type-references $args = []; foreach ($parameters as $p) { /** @var \ReflectionParameter $p */ $type = preg_replace('/(^|[(|&])\\\\/', '\1', $target = ltrim(ProxyHelper::exportType($p) ?? '', '?')); $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; $autowireAttributes = $autowire ? $emptyAutowireAttributes : []; if (isset($arguments[$r->name][$p->name])) { $target = $arguments[$r->name][$p->name]; if ('?' !== $target[0]) { $invalidBehavior = ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE; } elseif ('' === $target = (string) substr($target, 1)) { throw new InvalidArgumentException(sprintf('A "controller.service_arguments" tag must have non-empty "id" attributes for service "%s".', $id)); } elseif ($p->allowsNull() && !$p->isOptional()) { $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; } } elseif (isset($bindings[$bindingName = $type.' $'.$name = Target::parseName($p)]) || isset($bindings[$bindingName = '$'.$name]) || isset($bindings[$bindingName = $type])) { $binding = $bindings[$bindingName]; [$bindingValue, $bindingId, , $bindingType, $bindingFile] = $binding->getValues(); $binding->setValues([$bindingValue, $bindingId, true, $bindingType, $bindingFile]); $args[$p->name] = $bindingValue; continue; } elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)) && (!$type || '\\' !== $target[0]))) { continue; } elseif (is_subclass_of($type, \UnitEnum::class)) { // do not attempt to register enum typed arguments if not already present in bindings continue; } elseif (!$p->allowsNull()) { $invalidBehavior = ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE; } if (Request::class === $type || SessionInterface::class === $type || Response::class === $type) { continue; } if ($autowireAttributes) { $attribute = $autowireAttributes[0]->newInstance(); $value = $parameterBag->resolveValue($attribute->value); if ($attribute instanceof AutowireCallable) { $value = $attribute->buildDefinition($value, $type, $p); } if ($value instanceof Reference) { $args[$p->name] = $type ? new TypedReference($value, $type, $invalidBehavior, $p->name) : new Reference($value, $invalidBehavior); } else { $args[$p->name] = new Reference('.value.'.$container->hash($value)); $container->register((string) $args[$p->name], 'mixed') ->setFactory('current') ->addArgument([$value]); } continue; } if ($type && !$p->isOptional() && !$p->allowsNull() && !class_exists($type) && !interface_exists($type, false)) { $message = sprintf('Cannot determine controller argument for "%s::%s()": the $%s argument is type-hinted with the non-existent class or interface: "%s".', $class, $r->name, $p->name, $type); // see if the type-hint lives in the same namespace as the controller if (0 === strncmp($type, $class, strrpos($class, '\\'))) { $message .= ' Did you forget to add a use statement?'; } $container->register($erroredId = '.errored.'.$container->hash($message), $type) ->addError($message); $args[$p->name] = new Reference($erroredId, ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE); } else { $target = preg_replace('/(^|[(|&])\\\\/', '\1', $target); $args[$p->name] = $type ? new TypedReference($target, $type, $invalidBehavior, Target::parseName($p)) : new Reference($target, $invalidBehavior); } } // register the maps as a per-method service-locators if ($args) { $controllers[$id.'::'.$r->name] = ServiceLocatorTagPass::register($container, $args); foreach ($publicAliases[$id] ?? [] as $alias) { $controllers[$alias.'::'.$r->name] = clone $controllers[$id.'::'.$r->name]; } } } } $controllerLocatorRef = ServiceLocatorTagPass::register($container, $controllers); if ($container->hasDefinition('argument_resolver.service')) { $container->getDefinition('argument_resolver.service') ->replaceArgument(0, $controllerLocatorRef); } if ($container->hasDefinition('argument_resolver.not_tagged_controller')) { $container->getDefinition('argument_resolver.not_tagged_controller') ->replaceArgument(0, $controllerLocatorRef); } $container->setAlias('argument_resolver.controller_locator', (string) $controllerLocatorRef); } } DependencyInjection/RegisterLocaleAwareServicesPass.php 0000644 00000002616 15111167613 0017424 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; /** * Register all services that have the "kernel.locale_aware" tag into the listener. * * @author Pierre Bobiet <pierrebobiet@gmail.com> */ class RegisterLocaleAwareServicesPass implements CompilerPassInterface { /** * @return void */ public function process(ContainerBuilder $container) { if (!$container->hasDefinition('locale_aware_listener')) { return; } $services = []; foreach ($container->findTaggedServiceIds('kernel.locale_aware') as $id => $tags) { $services[] = new Reference($id); } if (!$services) { $container->removeDefinition('locale_aware_listener'); return; } $container ->getDefinition('locale_aware_listener') ->setArgument(0, new IteratorArgument($services)) ; } } DependencyInjection/ConfigurableExtension.php 0000644 00000002400 15111167613 0015471 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; /** * This extension sub-class provides first-class integration with the * Config/Definition Component. * * You can use this as base class if * * a) you use the Config/Definition component for configuration, * b) your configuration class is named "Configuration", and * c) the configuration class resides in the DependencyInjection sub-folder. * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ abstract class ConfigurableExtension extends Extension { final public function load(array $configs, ContainerBuilder $container): void { $this->loadInternal($this->processConfiguration($this->getConfiguration($configs, $container), $configs), $container); } /** * Configures the passed container according to the merged configuration. * * @return void */ abstract protected function loadInternal(array $mergedConfig, ContainerBuilder $container); } DependencyInjection/LazyLoadingFragmentHandler.php 0000644 00000002672 15111167613 0016406 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Psr\Container\ContainerInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\Fragment\FragmentHandler; /** * Lazily loads fragment renderers from the dependency injection container. * * @author Fabien Potencier <fabien@symfony.com> */ class LazyLoadingFragmentHandler extends FragmentHandler { private ContainerInterface $container; /** * @var array<string, bool> */ private array $initialized = []; public function __construct(ContainerInterface $container, RequestStack $requestStack, bool $debug = false) { $this->container = $container; parent::__construct($requestStack, [], $debug); } public function render(string|ControllerReference $uri, string $renderer = 'inline', array $options = []): ?string { if (!isset($this->initialized[$renderer]) && $this->container->has($renderer)) { $this->addRenderer($this->container->get($renderer)); $this->initialized[$renderer] = true; } return parent::render($uri, $renderer, $options); } } DependencyInjection/ResettableServicePass.php 0000644 00000004176 15111167613 0015452 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Reference; /** * @author Alexander M. Turek <me@derrabus.de> */ class ResettableServicePass implements CompilerPassInterface { /** * @return void */ public function process(ContainerBuilder $container) { if (!$container->has('services_resetter')) { return; } $services = $methods = []; foreach ($container->findTaggedServiceIds('kernel.reset', true) as $id => $tags) { $services[$id] = new Reference($id, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE); foreach ($tags as $attributes) { if (!isset($attributes['method'])) { throw new RuntimeException(sprintf('Tag "kernel.reset" requires the "method" attribute to be set on service "%s".', $id)); } if (!isset($methods[$id])) { $methods[$id] = []; } if ('ignore' === ($attributes['on_invalid'] ?? null)) { $attributes['method'] = '?'.$attributes['method']; } $methods[$id][] = $attributes['method']; } } if (!$services) { $container->removeAlias('services_resetter'); $container->removeDefinition('services_resetter'); return; } $container->findDefinition('services_resetter') ->setArgument(0, new IteratorArgument($services)) ->setArgument(1, $methods); } } DependencyInjection/ServicesResetter.php 0000644 00000003340 15111167613 0014501 0 ustar 00 <?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\HttpKernel\DependencyInjection; use ProxyManager\Proxy\LazyLoadingInterface; use Symfony\Component\VarExporter\LazyObjectInterface; use Symfony\Contracts\Service\ResetInterface; /** * Resets provided services. * * @author Alexander M. Turek <me@derrabus.de> * @author Nicolas Grekas <p@tchwork.com> * * @internal */ class ServicesResetter implements ResetInterface { private \Traversable $resettableServices; private array $resetMethods; /** * @param \Traversable<string, object> $resettableServices * @param array<string, string|string[]> $resetMethods */ public function __construct(\Traversable $resettableServices, array $resetMethods) { $this->resettableServices = $resettableServices; $this->resetMethods = $resetMethods; } public function reset(): void { foreach ($this->resettableServices as $id => $service) { if ($service instanceof LazyObjectInterface && !$service->isLazyObjectInitialized(true)) { continue; } if ($service instanceof LazyLoadingInterface && !$service->isProxyInitialized()) { continue; } foreach ((array) $this->resetMethods[$id] as $resetMethod) { if ('?' === $resetMethod[0] && !method_exists($service, $resetMethod = substr($resetMethod, 1))) { continue; } $service->$resetMethod(); } } } } DependencyInjection/AddAnnotatedClassesToCachePass.php 0000644 00000010174 15111167613 0017125 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Composer\Autoload\ClassLoader; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\ErrorHandler\DebugClassLoader; use Symfony\Component\HttpKernel\Kernel; /** * Sets the classes to compile in the cache for the container. * * @author Fabien Potencier <fabien@symfony.com> */ class AddAnnotatedClassesToCachePass implements CompilerPassInterface { private Kernel $kernel; public function __construct(Kernel $kernel) { $this->kernel = $kernel; } /** * @return void */ public function process(ContainerBuilder $container) { $annotatedClasses = []; foreach ($container->getExtensions() as $extension) { if ($extension instanceof Extension) { $annotatedClasses[] = $extension->getAnnotatedClassesToCompile(); } } $annotatedClasses = array_merge($this->kernel->getAnnotatedClassesToCompile(), ...$annotatedClasses); $existingClasses = $this->getClassesInComposerClassMaps(); $annotatedClasses = $container->getParameterBag()->resolveValue($annotatedClasses); $this->kernel->setAnnotatedClassCache($this->expandClasses($annotatedClasses, $existingClasses)); } /** * Expands the given class patterns using a list of existing classes. * * @param array $patterns The class patterns to expand * @param array $classes The existing classes to match against the patterns */ private function expandClasses(array $patterns, array $classes): array { $expanded = []; // Explicit classes declared in the patterns are returned directly foreach ($patterns as $key => $pattern) { if (!str_ends_with($pattern, '\\') && !str_contains($pattern, '*')) { unset($patterns[$key]); $expanded[] = ltrim($pattern, '\\'); } } // Match patterns with the classes list $regexps = $this->patternsToRegexps($patterns); foreach ($classes as $class) { $class = ltrim($class, '\\'); if ($this->matchAnyRegexps($class, $regexps)) { $expanded[] = $class; } } return array_unique($expanded); } private function getClassesInComposerClassMaps(): array { $classes = []; foreach (spl_autoload_functions() as $function) { if (!\is_array($function)) { continue; } if ($function[0] instanceof DebugClassLoader) { $function = $function[0]->getClassLoader(); } if (\is_array($function) && $function[0] instanceof ClassLoader) { $classes += array_filter($function[0]->getClassMap()); } } return array_keys($classes); } private function patternsToRegexps(array $patterns): array { $regexps = []; foreach ($patterns as $pattern) { // Escape user input $regex = preg_quote(ltrim($pattern, '\\')); // Wildcards * and ** $regex = strtr($regex, ['\\*\\*' => '.*?', '\\*' => '[^\\\\]*?']); // If this class does not end by a slash, anchor the end if (!str_ends_with($regex, '\\')) { $regex .= '$'; } $regexps[] = '{^\\\\'.$regex.'}'; } return $regexps; } private function matchAnyRegexps(string $class, array $regexps): bool { $isTest = str_contains($class, 'Test'); foreach ($regexps as $regex) { if ($isTest && !str_contains($regex, 'Test')) { continue; } if (preg_match($regex, '\\'.$class)) { return true; } } return false; } } DependencyInjection/error_log 0000644 00000012317 15111167613 0012410 0 ustar 00 [19-Nov-2025 01:35:37 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/LoggerPass.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/LoggerPass.php on line 26 [19-Nov-2025 01:36:19 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php on line 22 [19-Nov-2025 01:38:26 UTC] PHP Fatal error: Trait "Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ControllerArgumentValueResolverPass.php on line 29 [19-Nov-2025 01:39:23 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/RegisterLocaleAwareServicesPass.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/RegisterLocaleAwareServicesPass.php on line 24 [19-Nov-2025 01:40:29 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php on line 22 [19-Nov-2025 01:44:38 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php:35 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php on line 35 [19-Nov-2025 01:45:32 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\DependencyInjection\Extension\Extension" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/Extension.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/Extension.php on line 21 [19-Nov-2025 01:47:35 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php on line 25 [19-Nov-2025 01:48:33 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ResettableServicePass.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ResettableServicePass.php on line 24 [19-Nov-2025 01:49:33 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Contracts\Service\ResetInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ServicesResetter.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ServicesResetter.php on line 26 [19-Nov-2025 01:51:40 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\DependencyInjection\Extension" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php on line 28 [19-Nov-2025 01:53:38 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\FragmentHandler" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php:24 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php on line 24 [19-Nov-2025 01:55:35 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php:26 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php on line 26 DependencyInjection/LoggerPass.php 0000644 00000002273 15111167613 0013252 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Log\Logger; /** * Registers the default logger if necessary. * * @author Kévin Dunglas <dunglas@gmail.com> */ class LoggerPass implements CompilerPassInterface { /** * @return void */ public function process(ContainerBuilder $container) { $container->setAlias(LoggerInterface::class, 'logger') ->setPublic(false); if ($container->has('logger')) { return; } $container->register('logger', Logger::class) ->setArguments([null, null, null, new Reference(RequestStack::class)]) ->setPublic(false); } } DependencyInjection/MergeExtensionConfigurationPass.php 0000644 00000002277 15111167613 0017523 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass as BaseMergeExtensionConfigurationPass; use Symfony\Component\DependencyInjection\ContainerBuilder; /** * Ensures certain extensions are always loaded. * * @author Kris Wallsmith <kris@symfony.com> */ class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass { private array $extensions; /** * @param string[] $extensions */ public function __construct(array $extensions) { $this->extensions = $extensions; } /** * @return void */ public function process(ContainerBuilder $container) { foreach ($this->extensions as $extension) { if (!\count($container->getExtensionConfig($extension))) { $container->loadFromExtension($extension, []); } } parent::process($container); } } DependencyInjection/Extension.php 0000644 00000002103 15111167613 0013150 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension; /** * Allow adding classes to the class cache. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class Extension extends BaseExtension { private array $annotatedClasses = []; /** * Gets the annotated classes to cache. */ public function getAnnotatedClassesToCompile(): array { return $this->annotatedClasses; } /** * Adds annotated classes to the class cache. * * @param array $annotatedClasses An array of class patterns * * @return void */ public function addAnnotatedClassesToCompile(array $annotatedClasses) { $this->annotatedClasses = array_merge($this->annotatedClasses, $annotatedClasses); } } DependencyInjection/ControllerArgumentValueResolverPass.php 0000644 00000006030 15111167613 0020373 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\Controller\ArgumentResolver\TraceableValueResolver; use Symfony\Component\Stopwatch\Stopwatch; /** * Gathers and configures the argument value resolvers. * * @author Iltar van der Berg <kjarli@gmail.com> */ class ControllerArgumentValueResolverPass implements CompilerPassInterface { use PriorityTaggedServiceTrait; /** * @return void */ public function process(ContainerBuilder $container) { if (!$container->hasDefinition('argument_resolver')) { return; } $definitions = $container->getDefinitions(); $namedResolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.targeted_value_resolver', 'name', needsIndexes: true), $container); $resolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.argument_value_resolver', 'name', needsIndexes: true), $container); foreach ($resolvers as $name => $resolver) { if ($definitions[(string) $resolver]->hasTag('controller.targeted_value_resolver')) { unset($resolvers[$name]); } else { $namedResolvers[$name] ??= clone $resolver; } } if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has('debug.stopwatch')) { foreach ($resolvers as $name => $resolver) { $resolvers[$name] = new Reference('.debug.value_resolver.'.$resolver); $container->register('.debug.value_resolver.'.$resolver, TraceableValueResolver::class) ->setArguments([$resolver, new Reference('debug.stopwatch')]); } foreach ($namedResolvers as $name => $resolver) { $namedResolvers[$name] = new Reference('.debug.value_resolver.'.$resolver); $container->register('.debug.value_resolver.'.$resolver, TraceableValueResolver::class) ->setArguments([$resolver, new Reference('debug.stopwatch')]); } } $container ->getDefinition('argument_resolver') ->replaceArgument(1, new IteratorArgument(array_values($resolvers))) ->setArgument(2, new ServiceLocatorArgument($namedResolvers)) ; } } DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php 0000644 00000005124 15111167613 0021563 0 ustar 00 <?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\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; /** * Removes empty service-locators registered for ServiceValueResolver. * * @author Nicolas Grekas <p@tchwork.com> */ class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface { /** * @return void */ public function process(ContainerBuilder $container) { $controllerLocator = $container->findDefinition('argument_resolver.controller_locator'); $controllers = $controllerLocator->getArgument(0); foreach ($controllers as $controller => $argumentRef) { $argumentLocator = $container->getDefinition((string) $argumentRef->getValues()[0]); if (!$argumentLocator->getArgument(0)) { // remove empty argument locators $reason = sprintf('Removing service-argument resolver for controller "%s": no corresponding services exist for the referenced types.', $controller); } else { // any methods listed for call-at-instantiation cannot be actions $reason = false; [$id, $action] = explode('::', $controller); if ($container->hasAlias($id)) { continue; } $controllerDef = $container->getDefinition($id); foreach ($controllerDef->getMethodCalls() as [$method]) { if (0 === strcasecmp($action, $method)) { $reason = sprintf('Removing method "%s" of service "%s" from controller candidates: the method is called at instantiation, thus cannot be an action.', $action, $id); break; } } if (!$reason) { // see Symfony\Component\HttpKernel\Controller\ContainerControllerResolver $controllers[$id.':'.$action] = $argumentRef; if ('__invoke' === $action) { $controllers[$id] = $argumentRef; } continue; } } unset($controllers[$controller]); $container->log($this, $reason); } $controllerLocator->replaceArgument(0, $controllers); } } HttpKernel.php 0000644 00000026105 15111167613 0007343 0 ustar 00 <?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\HttpKernel; use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\Event\TerminateEvent; use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; // Help opcache.preload discover always-needed symbols class_exists(ControllerArgumentsEvent::class); class_exists(ControllerEvent::class); class_exists(ExceptionEvent::class); class_exists(FinishRequestEvent::class); class_exists(RequestEvent::class); class_exists(ResponseEvent::class); class_exists(TerminateEvent::class); class_exists(ViewEvent::class); class_exists(KernelEvents::class); /** * HttpKernel notifies events to convert a Request object to a Response one. * * @author Fabien Potencier <fabien@symfony.com> */ class HttpKernel implements HttpKernelInterface, TerminableInterface { protected $dispatcher; protected $resolver; protected $requestStack; private ArgumentResolverInterface $argumentResolver; private bool $handleAllThrowables; public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverInterface $argumentResolver = null, bool $handleAllThrowables = false) { $this->dispatcher = $dispatcher; $this->resolver = $resolver; $this->requestStack = $requestStack ?? new RequestStack(); $this->argumentResolver = $argumentResolver ?? new ArgumentResolver(); $this->handleAllThrowables = $handleAllThrowables; } public function handle(Request $request, int $type = HttpKernelInterface::MAIN_REQUEST, bool $catch = true): Response { $request->headers->set('X-Php-Ob-Level', (string) ob_get_level()); $this->requestStack->push($request); $response = null; try { return $response = $this->handleRaw($request, $type); } catch (\Throwable $e) { if ($e instanceof \Error && !$this->handleAllThrowables) { throw $e; } if ($e instanceof RequestExceptionInterface) { $e = new BadRequestHttpException($e->getMessage(), $e); } if (false === $catch) { $this->finishRequest($request, $type); throw $e; } return $response = $this->handleThrowable($e, $request, $type); } finally { $this->requestStack->pop(); if ($response instanceof StreamedResponse && $callback = $response->getCallback()) { $requestStack = $this->requestStack; $response->setCallback(static function () use ($request, $callback, $requestStack) { $requestStack->push($request); try { $callback(); } finally { $requestStack->pop(); } }); } } } /** * @return void */ public function terminate(Request $request, Response $response) { $this->dispatcher->dispatch(new TerminateEvent($this, $request, $response), KernelEvents::TERMINATE); } /** * @internal */ public function terminateWithException(\Throwable $exception, Request $request = null): void { if (!$request ??= $this->requestStack->getMainRequest()) { throw $exception; } if ($pop = $request !== $this->requestStack->getMainRequest()) { $this->requestStack->push($request); } try { $response = $this->handleThrowable($exception, $request, self::MAIN_REQUEST); } finally { if ($pop) { $this->requestStack->pop(); } } $response->sendHeaders(); $response->sendContent(); $this->terminate($request, $response); } /** * Handles a request to convert it to a response. * * Exceptions are not caught. * * @throws \LogicException If one of the listener does not behave as expected * @throws NotFoundHttpException When controller cannot be found */ private function handleRaw(Request $request, int $type = self::MAIN_REQUEST): Response { // request $event = new RequestEvent($this, $request, $type); $this->dispatcher->dispatch($event, KernelEvents::REQUEST); if ($event->hasResponse()) { return $this->filterResponse($event->getResponse(), $request, $type); } // load controller if (false === $controller = $this->resolver->getController($request)) { throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())); } $event = new ControllerEvent($this, $controller, $request, $type); $this->dispatcher->dispatch($event, KernelEvents::CONTROLLER); $controller = $event->getController(); // controller arguments $arguments = $this->argumentResolver->getArguments($request, $controller, $event->getControllerReflector()); $event = new ControllerArgumentsEvent($this, $event, $arguments, $request, $type); $this->dispatcher->dispatch($event, KernelEvents::CONTROLLER_ARGUMENTS); $controller = $event->getController(); $arguments = $event->getArguments(); // call controller $response = $controller(...$arguments); // view if (!$response instanceof Response) { $event = new ViewEvent($this, $request, $type, $response, $event); $this->dispatcher->dispatch($event, KernelEvents::VIEW); if ($event->hasResponse()) { $response = $event->getResponse(); } else { $msg = sprintf('The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned %s.', $this->varToString($response)); // the user may have forgotten to return something if (null === $response) { $msg .= ' Did you forget to add a return statement somewhere in your controller?'; } throw new ControllerDoesNotReturnResponseException($msg, $controller, __FILE__, __LINE__ - 17); } } return $this->filterResponse($response, $request, $type); } /** * Filters a response object. * * @throws \RuntimeException if the passed object is not a Response instance */ private function filterResponse(Response $response, Request $request, int $type): Response { $event = new ResponseEvent($this, $request, $type, $response); $this->dispatcher->dispatch($event, KernelEvents::RESPONSE); $this->finishRequest($request, $type); return $event->getResponse(); } /** * Publishes the finish request event, then pop the request from the stack. * * Note that the order of the operations is important here, otherwise * operations such as {@link RequestStack::getParentRequest()} can lead to * weird results. */ private function finishRequest(Request $request, int $type): void { $this->dispatcher->dispatch(new FinishRequestEvent($this, $request, $type), KernelEvents::FINISH_REQUEST); } /** * Handles a throwable by trying to convert it to a Response. */ private function handleThrowable(\Throwable $e, Request $request, int $type): Response { $event = new ExceptionEvent($this, $request, $type, $e); $this->dispatcher->dispatch($event, KernelEvents::EXCEPTION); // a listener might have replaced the exception $e = $event->getThrowable(); if (!$event->hasResponse()) { $this->finishRequest($request, $type); throw $e; } $response = $event->getResponse(); // the developer asked for a specific status code if (!$event->isAllowingCustomResponseCode() && !$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) { // ensure that we actually have an error response if ($e instanceof HttpExceptionInterface) { // keep the HTTP status code and headers $response->setStatusCode($e->getStatusCode()); $response->headers->add($e->getHeaders()); } else { $response->setStatusCode(500); } } try { return $this->filterResponse($response, $request, $type); } catch (\Throwable $e) { if ($e instanceof \Error && !$this->handleAllThrowables) { throw $e; } return $response; } } /** * Returns a human-readable string for the specified variable. */ private function varToString(mixed $var): string { if (\is_object($var)) { return sprintf('an object of type %s', $var::class); } if (\is_array($var)) { $a = []; foreach ($var as $k => $v) { $a[] = sprintf('%s => ...', $k); } return sprintf('an array ([%s])', mb_substr(implode(', ', $a), 0, 255)); } if (\is_resource($var)) { return sprintf('a resource (%s)', get_resource_type($var)); } if (null === $var) { return 'null'; } if (false === $var) { return 'a boolean value (false)'; } if (true === $var) { return 'a boolean value (true)'; } if (\is_string($var)) { return sprintf('a string ("%s%s")', mb_substr($var, 0, 255), mb_strlen($var) > 255 ? '...' : ''); } if (is_numeric($var)) { return sprintf('a number (%s)', (string) $var); } return (string) $var; } } RebootableInterface.php 0000644 00000001456 15111167613 0011164 0 ustar 00 <?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\HttpKernel; /** * Allows the Kernel to be rebooted using a temporary cache directory. * * @author Nicolas Grekas <p@tchwork.com> */ interface RebootableInterface { /** * Reboots a kernel. * * The getBuildDir() method of a rebootable kernel should not be called * while building the container. Use the %kernel.build_dir% parameter instead. * * @param string|null $warmupDir pass null to reboot in the regular build directory * * @return void */ public function reboot(?string $warmupDir); } Event/ViewEvent.php 0000644 00000002665 15111167613 0010265 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Allows to create a response for the return value of a controller. * * Call setResponse() to set the response that will be returned for the * current request. The propagation of this event is stopped as soon as a * response is set. * * @author Bernhard Schussek <bschussek@gmail.com> */ final class ViewEvent extends RequestEvent { public readonly ?ControllerArgumentsEvent $controllerArgumentsEvent; private mixed $controllerResult; public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, mixed $controllerResult, ControllerArgumentsEvent $controllerArgumentsEvent = null) { parent::__construct($kernel, $request, $requestType); $this->controllerResult = $controllerResult; $this->controllerArgumentsEvent = $controllerArgumentsEvent; } public function getControllerResult(): mixed { return $this->controllerResult; } public function setControllerResult(mixed $controllerResult): void { $this->controllerResult = $controllerResult; } } Event/KernelEvent.php 0000644 00000003625 15111167613 0010570 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Contracts\EventDispatcher\Event; /** * Base class for events thrown in the HttpKernel component. * * @author Bernhard Schussek <bschussek@gmail.com> */ class KernelEvent extends Event { private HttpKernelInterface $kernel; private Request $request; private ?int $requestType; /** * @param int $requestType The request type the kernel is currently processing; one of * HttpKernelInterface::MAIN_REQUEST or HttpKernelInterface::SUB_REQUEST */ public function __construct(HttpKernelInterface $kernel, Request $request, ?int $requestType) { $this->kernel = $kernel; $this->request = $request; $this->requestType = $requestType; } /** * Returns the kernel in which this event was thrown. */ public function getKernel(): HttpKernelInterface { return $this->kernel; } /** * Returns the request the kernel is currently processing. */ public function getRequest(): Request { return $this->request; } /** * Returns the request type the kernel is currently processing. * * @return int One of HttpKernelInterface::MAIN_REQUEST and * HttpKernelInterface::SUB_REQUEST */ public function getRequestType(): int { return $this->requestType; } /** * Checks if this is the main request. */ public function isMainRequest(): bool { return HttpKernelInterface::MAIN_REQUEST === $this->requestType; } } Event/FinishRequestEvent.php 0000644 00000000705 15111167613 0012135 0 ustar 00 <?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\HttpKernel\Event; /** * Triggered whenever a request is fully processed. * * @author Benjamin Eberlei <kontakt@beberlei.de> */ final class FinishRequestEvent extends KernelEvent { } Event/ControllerArgumentsEvent.php 0000644 00000005773 15111167613 0013367 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Allows filtering of controller arguments. * * You can call getController() to retrieve the controller and getArguments * to retrieve the current arguments. With setArguments() you can replace * arguments that are used to call the controller. * * Arguments set in the event must be compatible with the signature of the * controller. * * @author Christophe Coevoet <stof@notk.org> */ final class ControllerArgumentsEvent extends KernelEvent { private ControllerEvent $controllerEvent; private array $arguments; private array $namedArguments; public function __construct(HttpKernelInterface $kernel, callable|ControllerEvent $controller, array $arguments, Request $request, ?int $requestType) { parent::__construct($kernel, $request, $requestType); if (!$controller instanceof ControllerEvent) { $controller = new ControllerEvent($kernel, $controller, $request, $requestType); } $this->controllerEvent = $controller; $this->arguments = $arguments; } public function getController(): callable { return $this->controllerEvent->getController(); } /** * @param array<class-string, list<object>>|null $attributes */ public function setController(callable $controller, array $attributes = null): void { $this->controllerEvent->setController($controller, $attributes); unset($this->namedArguments); } public function getArguments(): array { return $this->arguments; } public function setArguments(array $arguments): void { $this->arguments = $arguments; unset($this->namedArguments); } public function getNamedArguments(): array { if (isset($this->namedArguments)) { return $this->namedArguments; } $namedArguments = []; $arguments = $this->arguments; foreach ($this->controllerEvent->getControllerReflector()->getParameters() as $i => $param) { if ($param->isVariadic()) { $namedArguments[$param->name] = \array_slice($arguments, $i); break; } if (\array_key_exists($i, $arguments)) { $namedArguments[$param->name] = $arguments[$i]; } elseif ($param->isDefaultvalueAvailable()) { $namedArguments[$param->name] = $param->getDefaultValue(); } } return $this->namedArguments = $namedArguments; } /** * @return array<class-string, list<object>> */ public function getAttributes(): array { return $this->controllerEvent->getAttributes(); } } Event/TerminateEvent.php 0000644 00000002116 15111167613 0011272 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Allows to execute logic after a response was sent. * * Since it's only triggered on main requests, the `getRequestType()` method * will always return the value of `HttpKernelInterface::MAIN_REQUEST`. * * @author Jordi Boggiano <j.boggiano@seld.be> */ final class TerminateEvent extends KernelEvent { private Response $response; public function __construct(HttpKernelInterface $kernel, Request $request, Response $response) { parent::__construct($kernel, $request, HttpKernelInterface::MAIN_REQUEST); $this->response = $response; } public function getResponse(): Response { return $this->response; } } Event/ControllerEvent.php 0000644 00000006736 15111167613 0011501 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Allows filtering of a controller callable. * * You can call getController() to retrieve the current controller. With * setController() you can set a new controller that is used in the processing * of the request. * * Controllers should be callables. * * @author Bernhard Schussek <bschussek@gmail.com> */ final class ControllerEvent extends KernelEvent { private string|array|object $controller; private \ReflectionFunctionAbstract $controllerReflector; private array $attributes; public function __construct(HttpKernelInterface $kernel, callable $controller, Request $request, ?int $requestType) { parent::__construct($kernel, $request, $requestType); $this->setController($controller); } public function getController(): callable { return $this->controller; } public function getControllerReflector(): \ReflectionFunctionAbstract { return $this->controllerReflector; } /** * @param array<class-string, list<object>>|null $attributes */ public function setController(callable $controller, array $attributes = null): void { if (null !== $attributes) { $this->attributes = $attributes; } if (isset($this->controller) && ($controller instanceof \Closure ? $controller == $this->controller : $controller === $this->controller)) { $this->controller = $controller; return; } if (null === $attributes) { unset($this->attributes); } if (\is_array($controller) && method_exists(...$controller)) { $this->controllerReflector = new \ReflectionMethod(...$controller); } elseif (\is_string($controller) && str_contains($controller, '::')) { $this->controllerReflector = new \ReflectionMethod($controller); } else { $this->controllerReflector = new \ReflectionFunction($controller(...)); } $this->controller = $controller; } /** * @return array<class-string, list<object>> */ public function getAttributes(): array { if (isset($this->attributes)) { return $this->attributes; } if (\is_array($this->controller) && method_exists(...$this->controller)) { $class = new \ReflectionClass($this->controller[0]); } elseif (\is_string($this->controller) && false !== $i = strpos($this->controller, '::')) { $class = new \ReflectionClass(substr($this->controller, 0, $i)); } else { $class = str_contains($this->controllerReflector->name, '{closure}') ? null : (\PHP_VERSION_ID >= 80111 ? $this->controllerReflector->getClosureCalledClass() : $this->controllerReflector->getClosureScopeClass()); } $this->attributes = []; foreach (array_merge($class?->getAttributes() ?? [], $this->controllerReflector->getAttributes()) as $attribute) { if (class_exists($attribute->getName())) { $this->attributes[$attribute->getName()][] = $attribute->newInstance(); } } return $this->attributes; } } Event/ExceptionEvent.php 0000644 00000003576 15111167613 0011313 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Allows to create a response for a thrown exception. * * Call setResponse() to set the response that will be returned for the * current request. The propagation of this event is stopped as soon as a * response is set. * * You can also call setThrowable() to replace the thrown exception. This * exception will be thrown if no response is set during processing of this * event. * * @author Bernhard Schussek <bschussek@gmail.com> */ final class ExceptionEvent extends RequestEvent { private \Throwable $throwable; private bool $allowCustomResponseCode = false; public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Throwable $e) { parent::__construct($kernel, $request, $requestType); $this->setThrowable($e); } public function getThrowable(): \Throwable { return $this->throwable; } /** * Replaces the thrown exception. * * This exception will be thrown if no response is set in the event. */ public function setThrowable(\Throwable $exception): void { $this->throwable = $exception; } /** * Mark the event as allowing a custom response code. */ public function allowCustomResponseCode(): void { $this->allowCustomResponseCode = true; } /** * Returns true if the event allows a custom response code. */ public function isAllowingCustomResponseCode(): bool { return $this->allowCustomResponseCode; } } Event/ResponseEvent.php 0000644 00000002262 15111167614 0011143 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Allows to filter a Response object. * * You can call getResponse() to retrieve the current response. With * setResponse() you can set a new response that will be returned to the * browser. * * @author Bernhard Schussek <bschussek@gmail.com> */ final class ResponseEvent extends KernelEvent { private Response $response; public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, Response $response) { parent::__construct($kernel, $request, $requestType); $this->setResponse($response); } public function getResponse(): Response { return $this->response; } public function setResponse(Response $response): void { $this->response = $response; } } Event/RequestEvent.php 0000644 00000002304 15111167614 0010772 0 ustar 00 <?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\HttpKernel\Event; use Symfony\Component\HttpFoundation\Response; /** * Allows to create a response for a request. * * Call setResponse() to set the response that will be returned for the * current request. The propagation of this event is stopped as soon as a * response is set. * * @author Bernhard Schussek <bschussek@gmail.com> */ class RequestEvent extends KernelEvent { private ?Response $response = null; /** * Returns the response object. */ public function getResponse(): ?Response { return $this->response; } /** * Sets a response and stops event propagation. * * @return void */ public function setResponse(Response $response) { $this->response = $response; $this->stopPropagation(); } /** * Returns whether a response was set. */ public function hasResponse(): bool { return null !== $this->response; } } CHANGELOG.md 0000644 00000046367 15111167614 0006400 0 ustar 00 CHANGELOG ========= 6.3 --- * Deprecate parameters `container.dumper.inline_factories` and `container.dumper.inline_class_loader`, use `.container.dumper.inline_factories` and `.container.dumper.inline_class_loader` instead * `FileProfilerStorage` removes profiles automatically after two days * Add `#[WithHttpStatus]` for defining status codes for exceptions * Use an instance of `Psr\Clock\ClockInterface` to generate the current date time in `DateTimeValueResolver` * Add `#[WithLogLevel]` for defining log levels for exceptions * Add `skip_response_headers` to the `HttpCache` options * Introduce targeted value resolvers with `#[ValueResolver]` and `#[AsTargetedValueResolver]` * Add `#[MapRequestPayload]` to map and validate request payload from `Request::getContent()` or `Request::$request->all()` to typed objects * Add `#[MapQueryString]` to map and validate request query string from `Request::$query->all()` to typed objects * Add `#[MapQueryParameter]` to map and validate individual query parameters to controller arguments * Collect data from every event dispatcher 6.2 --- * Add constructor argument `bool $handleAllThrowable` to `HttpKernel` * Add `ControllerEvent::getAttributes()` to handle attributes on controllers * Add `#[Cache]` to describe the default HTTP cache headers on controllers * Add `absolute_uri` option to surrogate fragment renderers * Add `ValueResolverInterface` and deprecate `ArgumentValueResolverInterface` * Add argument `$reflector` to `ArgumentResolverInterface` and `ArgumentMetadataFactoryInterface` * Deprecate calling `ConfigDataCollector::setKernel()`, `RouterListener::setCurrentRequest()` without arguments 6.1 --- * Add `BackedEnumValueResolver` to resolve backed enum cases from request attributes in controller arguments * Add `DateTimeValueResolver` to resolve request attributes into DateTime objects in controller arguments * Deprecate StreamedResponseListener, it's not needed anymore * Add `Profiler::isEnabled()` so collaborating collector services may elect to omit themselves * Add the `UidValueResolver` argument value resolver * Add `AbstractBundle` class for DI configuration/definition on a single file * Update the path of a bundle placed in the `src/` directory to the parent directory when `AbstractBundle` is used 6.0 --- * Remove `ArgumentInterface` * Remove `ArgumentMetadata::getAttribute()`, use `getAttributes()` instead * Remove support for returning a `ContainerBuilder` from `KernelInterface::registerContainerConfiguration()` * Remove `KernelEvent::isMasterRequest()`, use `isMainRequest()` instead * Remove support for `service:action` syntax to reference controllers, use `serviceOrFqcn::method` instead 5.4 --- * Add the ability to enable the profiler using a request query parameter, body parameter or attribute * Deprecate `AbstractTestSessionListener` and `TestSessionListener`, use `AbstractSessionListener` and `SessionListener` instead * Deprecate the `fileLinkFormat` parameter of `DebugHandlersListener` * Add support for configuring log level, and status code by exception class * Allow ignoring "kernel.reset" methods that don't exist with "on_invalid" attribute 5.3 --- * Deprecate `ArgumentInterface` * Add `ArgumentMetadata::getAttributes()` * Deprecate `ArgumentMetadata::getAttribute()`, use `getAttributes()` instead * Mark the class `Symfony\Component\HttpKernel\EventListener\DebugHandlersListener` as internal * Deprecate returning a `ContainerBuilder` from `KernelInterface::registerContainerConfiguration()` * Deprecate `HttpKernelInterface::MASTER_REQUEST` and add `HttpKernelInterface::MAIN_REQUEST` as replacement * Deprecate `KernelEvent::isMasterRequest()` and add `isMainRequest()` as replacement * Add `#[AsController]` attribute for declaring standalone controllers on PHP 8 * Add `FragmentUriGeneratorInterface` and `FragmentUriGenerator` to generate the URI of a fragment 5.2.0 ----- * added session usage * made the public `http_cache` service handle requests when available * allowed enabling trusted hosts and proxies using new `kernel.trusted_hosts`, `kernel.trusted_proxies` and `kernel.trusted_headers` parameters * content of request parameter `_password` is now also hidden in the request profiler raw content section * Allowed adding attributes on controller arguments that will be passed to argument resolvers. * kernels implementing the `ExtensionInterface` will now be auto-registered to the container * added parameter `kernel.runtime_environment`, defined as `%env(default:kernel.environment:APP_RUNTIME_ENV)%` * do not set a default `Accept` HTTP header when using `HttpKernelBrowser` 5.1.0 ----- * allowed to use a specific logger channel for deprecations * made `WarmableInterface::warmUp()` return a list of classes or files to preload on PHP 7.4+; not returning an array is deprecated * made kernels implementing `WarmableInterface` be part of the cache warmup stage * deprecated support for `service:action` syntax to reference controllers, use `serviceOrFqcn::method` instead * allowed using public aliases to reference controllers * added session usage reporting when the `_stateless` attribute of the request is set to `true` * added `AbstractSessionListener::onSessionUsage()` to report when the session is used while a request is stateless 5.0.0 ----- * removed support for getting the container from a non-booted kernel * removed the first and second constructor argument of `ConfigDataCollector` * removed `ConfigDataCollector::getApplicationName()` * removed `ConfigDataCollector::getApplicationVersion()` * removed support for `Symfony\Component\Templating\EngineInterface` in `HIncludeFragmentRenderer`, use a `Twig\Environment` only * removed `TranslatorListener` in favor of `LocaleAwareListener` * removed `getRootDir()` and `getName()` from `Kernel` and `KernelInterface` * removed `FilterControllerArgumentsEvent`, use `ControllerArgumentsEvent` instead * removed `FilterControllerEvent`, use `ControllerEvent` instead * removed `FilterResponseEvent`, use `ResponseEvent` instead * removed `GetResponseEvent`, use `RequestEvent` instead * removed `GetResponseForControllerResultEvent`, use `ViewEvent` instead * removed `GetResponseForExceptionEvent`, use `ExceptionEvent` instead * removed `PostResponseEvent`, use `TerminateEvent` instead * removed `SaveSessionListener` in favor of `AbstractSessionListener` * removed `Client`, use `HttpKernelBrowser` instead * added method `getProjectDir()` to `KernelInterface` * removed methods `serialize` and `unserialize` from `DataCollector`, store the serialized state in the data property instead * made `ProfilerStorageInterface` internal * removed the second and third argument of `KernelInterface::locateResource` * removed the second and third argument of `FileLocator::__construct` * removed loading resources from `%kernel.root_dir%/Resources` and `%kernel.root_dir%` as fallback directories. * removed class `ExceptionListener`, use `ErrorListener` instead 4.4.0 ----- * The `DebugHandlersListener` class has been marked as `final` * Added new Bundle directory convention consistent with standard skeletons * Deprecated the second and third argument of `KernelInterface::locateResource` * Deprecated the second and third argument of `FileLocator::__construct` * Deprecated loading resources from `%kernel.root_dir%/Resources` and `%kernel.root_dir%` as fallback directories. Resources like service definitions are usually loaded relative to the current directory or with a glob pattern. The fallback directories have never been advocated so you likely do not use those in any app based on the SF Standard or Flex edition. * Marked all dispatched event classes as `@final` * Added `ErrorController` to enable the preview and error rendering mechanism * Getting the container from a non-booted kernel is deprecated. * Marked the `AjaxDataCollector`, `ConfigDataCollector`, `EventDataCollector`, `ExceptionDataCollector`, `LoggerDataCollector`, `MemoryDataCollector`, `RequestDataCollector` and `TimeDataCollector` classes as `@final`. * Marked the `RouterDataCollector::collect()` method as `@final`. * The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0. * Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead * Deprecated class `ExceptionListener`, use `ErrorListener` instead 4.3.0 ----- * renamed `Client` to `HttpKernelBrowser` * `KernelInterface` doesn't extend `Serializable` anymore * deprecated the `Kernel::serialize()` and `unserialize()` methods * increased the priority of `Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener` * made `Symfony\Component\HttpKernel\EventListener\LocaleListener` set the default locale early * deprecated `TranslatorListener` in favor of `LocaleAwareListener` * added the registration of all `LocaleAwareInterface` implementations into the `LocaleAwareListener` * made `FileLinkFormatter` final and not implement `Serializable` anymore * the base `DataCollector` doesn't implement `Serializable` anymore, you should store all the serialized state in the data property instead * `DumpDataCollector` has been marked as `final` * added an event listener to prevent search engines from indexing applications in debug mode. * renamed `FilterControllerArgumentsEvent` to `ControllerArgumentsEvent` * renamed `FilterControllerEvent` to `ControllerEvent` * renamed `FilterResponseEvent` to `ResponseEvent` * renamed `GetResponseEvent` to `RequestEvent` * renamed `GetResponseForControllerResultEvent` to `ViewEvent` * renamed `GetResponseForExceptionEvent` to `ExceptionEvent` * renamed `PostResponseEvent` to `TerminateEvent` * added `HttpClientKernel` for handling requests with an `HttpClientInterface` instance * added `trace_header` and `trace_level` configuration options to `HttpCache` 4.2.0 ----- * deprecated `KernelInterface::getRootDir()` and the `kernel.root_dir` parameter * deprecated `KernelInterface::getName()` and the `kernel.name` parameter * deprecated the first and second constructor argument of `ConfigDataCollector` * deprecated `ConfigDataCollector::getApplicationName()` * deprecated `ConfigDataCollector::getApplicationVersion()` 4.1.0 ----- * added orphaned events support to `EventDataCollector` * `ExceptionListener` now logs exceptions at priority `0` (previously logged at `-128`) * Added support for using `service::method` to reference controllers, making it consistent with other cases. It is recommended over the `service:action` syntax with a single colon, which will be deprecated in the future. * Added the ability to profile individual argument value resolvers via the `Symfony\Component\HttpKernel\Controller\ArgumentResolver\TraceableValueResolver` 4.0.0 ----- * removed the `DataCollector::varToString()` method, use `DataCollector::cloneVar()` instead * using the `DataCollector::cloneVar()` method requires the VarDumper component * removed the `ValueExporter` class * removed `ControllerResolverInterface::getArguments()` * removed `TraceableControllerResolver::getArguments()` * removed `ControllerResolver::getArguments()` and the ability to resolve arguments * removed the `argument_resolver` service dependency from the `debug.controller_resolver` * removed `LazyLoadingFragmentHandler::addRendererService()` * removed `Psr6CacheClearer::addPool()` * removed `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()` * removed `Kernel::loadClassCache()`, `Kernel::doLoadClassCache()`, `Kernel::setClassCache()`, and `Kernel::getEnvParameters()` * support for the `X-Status-Code` when handling exceptions in the `HttpKernel` has been dropped, use the `HttpKernel::allowCustomResponseCode()` method instead * removed convention-based commands registration * removed the `ChainCacheClearer::add()` method * removed the `CacheaWarmerAggregate::add()` and `setWarmers()` methods * made `CacheWarmerAggregate` and `ChainCacheClearer` classes final 3.4.0 ----- * added a minimalist PSR-3 `Logger` class that writes in `stderr` * made kernels implementing `CompilerPassInterface` able to process the container * deprecated bundle inheritance * added `RebootableInterface` and implemented it in `Kernel` * deprecated commands auto registration * deprecated `EnvParametersResource` * added `Symfony\Component\HttpKernel\Client::catchExceptions()` * deprecated the `ChainCacheClearer::add()` method * deprecated the `CacheaWarmerAggregate::add()` and `setWarmers()` methods * made `CacheWarmerAggregate` and `ChainCacheClearer` classes final * added the possibility to reset the profiler to its initial state * deprecated data collectors without a `reset()` method * deprecated implementing `DebugLoggerInterface` without a `clear()` method 3.3.0 ----- * added `kernel.project_dir` and `Kernel::getProjectDir()` * deprecated `kernel.root_dir` and `Kernel::getRootDir()` * deprecated `Kernel::getEnvParameters()` * deprecated the special `SYMFONY__` environment variables * added the possibility to change the query string parameter used by `UriSigner` * deprecated `LazyLoadingFragmentHandler::addRendererService()` * deprecated `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()` * deprecated `Psr6CacheClearer::addPool()` 3.2.0 ----- * deprecated `DataCollector::varToString()`, use `cloneVar()` instead * changed surrogate capability name in `AbstractSurrogate::addSurrogateCapability` to 'symfony' * Added `ControllerArgumentValueResolverPass` 3.1.0 ----- * deprecated passing objects as URI attributes to the ESI and SSI renderers * deprecated `ControllerResolver::getArguments()` * added `Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface` * added `Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface` as argument to `HttpKernel` * added `Symfony\Component\HttpKernel\Controller\ArgumentResolver` * added `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::getMethod()` * added `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::getRedirect()` * added the `kernel.controller_arguments` event, triggered after controller arguments have been resolved 3.0.0 ----- * removed `Symfony\Component\HttpKernel\Kernel::init()` * removed `Symfony\Component\HttpKernel\Kernel::isClassInActiveBundle()` and `Symfony\Component\HttpKernel\KernelInterface::isClassInActiveBundle()` * removed `Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher::setProfiler()` * removed `Symfony\Component\HttpKernel\EventListener\FragmentListener::getLocalIpAddresses()` * removed `Symfony\Component\HttpKernel\EventListener\LocaleListener::setRequest()` * removed `Symfony\Component\HttpKernel\EventListener\RouterListener::setRequest()` * removed `Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest()` * removed `Symfony\Component\HttpKernel\Fragment\FragmentHandler::setRequest()` * removed `Symfony\Component\HttpKernel\HttpCache\Esi::hasSurrogateEsiCapability()` * removed `Symfony\Component\HttpKernel\HttpCache\Esi::addSurrogateEsiCapability()` * removed `Symfony\Component\HttpKernel\HttpCache\Esi::needsEsiParsing()` * removed `Symfony\Component\HttpKernel\HttpCache\HttpCache::getEsi()` * removed `Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel` * removed `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass` * removed `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` * removed `Symfony\Component\HttpKernel\EventListener\EsiListener` * removed `Symfony\Component\HttpKernel\HttpCache\EsiResponseCacheStrategy` * removed `Symfony\Component\HttpKernel\HttpCache\EsiResponseCacheStrategyInterface` * removed `Symfony\Component\HttpKernel\Log\LoggerInterface` * removed `Symfony\Component\HttpKernel\Log\NullLogger` * removed `Symfony\Component\HttpKernel\Profiler::import()` * removed `Symfony\Component\HttpKernel\Profiler::export()` 2.8.0 ----- * deprecated `Profiler::import` and `Profiler::export` 2.7.0 ----- * added the HTTP status code to profiles 2.6.0 ----- * deprecated `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener`, use `Symfony\Component\HttpKernel\EventListener\DebugHandlersListener` instead * deprecated unused method `Symfony\Component\HttpKernel\Kernel::isClassInActiveBundle` and `Symfony\Component\HttpKernel\KernelInterface::isClassInActiveBundle` 2.5.0 ----- * deprecated `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass`, use `Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass` instead 2.4.0 ----- * added event listeners for the session * added the KernelEvents::FINISH_REQUEST event 2.3.0 ----- * [BC BREAK] renamed `Symfony\Component\HttpKernel\EventListener\DeprecationLoggerListener` to `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` and changed its constructor * deprecated `Symfony\Component\HttpKernel\Debug\ErrorHandler`, `Symfony\Component\HttpKernel\Debug\ExceptionHandler`, `Symfony\Component\HttpKernel\Exception\FatalErrorException` and `Symfony\Component\HttpKernel\Exception\FlattenException` * deprecated `Symfony\Component\HttpKernel\Kernel::init()` * added the possibility to specify an id an extra attributes to hinclude tags * added the collect of data if a controller is a Closure in the Request collector * pass exceptions from the ExceptionListener to the logger using the logging context to allow for more detailed messages 2.2.0 ----- * [BC BREAK] the path info for sub-request is now always _fragment (or whatever you configured instead of the default) * added Symfony\Component\HttpKernel\EventListener\FragmentListener * added Symfony\Component\HttpKernel\UriSigner * added Symfony\Component\HttpKernel\FragmentRenderer and rendering strategies (in Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface) * added Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel * added ControllerReference to create reference of Controllers (used in the FragmentRenderer class) * [BC BREAK] renamed TimeDataCollector::getTotalTime() to TimeDataCollector::getDuration() * updated the MemoryDataCollector to include the memory used in the kernel.terminate event listeners * moved the Stopwatch classes to a new component * added TraceableControllerResolver * added TraceableEventDispatcher (removed ContainerAwareTraceableEventDispatcher) * added support for WinCache opcode cache in ConfigDataCollector 2.1.0 ----- * [BC BREAK] the charset is now configured via the Kernel::getCharset() method * [BC BREAK] the current locale for the user is not stored anymore in the session * added the HTTP method to the profiler storage * updated all listeners to implement EventSubscriberInterface * added TimeDataCollector * added ContainerAwareTraceableEventDispatcher * moved TraceableEventDispatcherInterface to the EventDispatcher component * added RouterListener, LocaleListener, and StreamedResponseListener * added CacheClearerInterface (and ChainCacheClearer) * added a kernel.terminate event (via TerminableInterface and PostResponseEvent) * added a Stopwatch class * added WarmableInterface * improved extensibility between bundles * added profiler storages for Memcache(d), File-based, MongoDB, Redis * moved Filesystem class to its own component CacheClearer/ChainCacheClearer.php 0000644 00000001475 15111167614 0013034 0 ustar 00 <?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\HttpKernel\CacheClearer; /** * ChainCacheClearer. * * @author Dustin Dobervich <ddobervich@gmail.com> * * @final */ class ChainCacheClearer implements CacheClearerInterface { private iterable $clearers; /** * @param iterable<mixed, CacheClearerInterface> $clearers */ public function __construct(iterable $clearers = []) { $this->clearers = $clearers; } public function clear(string $cacheDir): void { foreach ($this->clearers as $clearer) { $clearer->clear($cacheDir); } } } CacheClearer/CacheClearerInterface.php 0000644 00000001034 15111167614 0013701 0 ustar 00 <?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\HttpKernel\CacheClearer; /** * CacheClearerInterface. * * @author Dustin Dobervich <ddobervich@gmail.com> */ interface CacheClearerInterface { /** * Clears any caches necessary. * * @return void */ public function clear(string $cacheDir); } CacheClearer/Psr6CacheClearer.php 0000644 00000003171 15111167614 0012637 0 ustar 00 <?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\HttpKernel\CacheClearer; use Psr\Cache\CacheItemPoolInterface; /** * @author Nicolas Grekas <p@tchwork.com> */ class Psr6CacheClearer implements CacheClearerInterface { private array $pools = []; /** * @param array<string, CacheItemPoolInterface> $pools */ public function __construct(array $pools = []) { $this->pools = $pools; } public function hasPool(string $name): bool { return isset($this->pools[$name]); } /** * @throws \InvalidArgumentException If the cache pool with the given name does not exist */ public function getPool(string $name): CacheItemPoolInterface { if (!$this->hasPool($name)) { throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name)); } return $this->pools[$name]; } /** * @throws \InvalidArgumentException If the cache pool with the given name does not exist */ public function clearPool(string $name): bool { if (!isset($this->pools[$name])) { throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name)); } return $this->pools[$name]->clear(); } /** * @return void */ public function clear(string $cacheDir) { foreach ($this->pools as $pool) { $pool->clear(); } } } CacheClearer/error_log 0000644 00000003040 15111167614 0010762 0 ustar 00 [19-Nov-2025 04:14:56 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php on line 21 [19-Nov-2025 04:15:03 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php on line 19 [19-Nov-2025 11:03:10 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php on line 19 [19-Nov-2025 11:03:16 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php:21 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php on line 21 Fragment/FragmentRendererInterface.php 0000644 00000001554 15111167614 0014103 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Controller\ControllerReference; /** * Interface implemented by all rendering strategies. * * @author Fabien Potencier <fabien@symfony.com> */ interface FragmentRendererInterface { /** * Renders a URI and returns the Response content. */ public function render(string|ControllerReference $uri, Request $request, array $options = []): Response; /** * Gets the name of the strategy. */ public function getName(): string; } Fragment/RoutableFragmentRenderer.php 0000644 00000002750 15111167614 0013757 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\EventListener\FragmentListener; /** * Adds the possibility to generate a fragment URI for a given Controller. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class RoutableFragmentRenderer implements FragmentRendererInterface { /** * @internal */ protected $fragmentPath = '/_fragment'; /** * Sets the fragment path that triggers the fragment listener. * * @see FragmentListener * * @return void */ public function setFragmentPath(string $path) { $this->fragmentPath = $path; } /** * Generates a fragment URI for a given controller. * * @param bool $absolute Whether to generate an absolute URL or not * @param bool $strict Whether to allow non-scalar attributes or not */ protected function generateFragmentUri(ControllerReference $reference, Request $request, bool $absolute = false, bool $strict = true): string { return (new FragmentUriGenerator($this->fragmentPath))->generate($reference, $request, $absolute, $strict, false); } } Fragment/InlineFragmentRenderer.php 0000644 00000012131 15111167614 0013412 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\HttpCache\SubRequestHandler; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** * Implements the inline rendering strategy where the Request is rendered by the current HTTP kernel. * * @author Fabien Potencier <fabien@symfony.com> */ class InlineFragmentRenderer extends RoutableFragmentRenderer { private HttpKernelInterface $kernel; private ?EventDispatcherInterface $dispatcher; public function __construct(HttpKernelInterface $kernel, EventDispatcherInterface $dispatcher = null) { $this->kernel = $kernel; $this->dispatcher = $dispatcher; } /** * Additional available options: * * * alt: an alternative URI to render in case of an error */ public function render(string|ControllerReference $uri, Request $request, array $options = []): Response { $reference = null; if ($uri instanceof ControllerReference) { $reference = $uri; // Remove attributes from the generated URI because if not, the Symfony // routing system will use them to populate the Request attributes. We don't // want that as we want to preserve objects (so we manually set Request attributes // below instead) $attributes = $reference->attributes; $reference->attributes = []; // The request format and locale might have been overridden by the user foreach (['_format', '_locale'] as $key) { if (isset($attributes[$key])) { $reference->attributes[$key] = $attributes[$key]; } } $uri = $this->generateFragmentUri($uri, $request, false, false); $reference->attributes = array_merge($attributes, $reference->attributes); } $subRequest = $this->createSubRequest($uri, $request); // override Request attributes as they can be objects (which are not supported by the generated URI) if (null !== $reference) { $subRequest->attributes->add($reference->attributes); } $level = ob_get_level(); try { return SubRequestHandler::handle($this->kernel, $subRequest, HttpKernelInterface::SUB_REQUEST, false); } catch (\Exception $e) { // we dispatch the exception event to trigger the logging // the response that comes back is ignored if (isset($options['ignore_errors']) && $options['ignore_errors'] && $this->dispatcher) { $event = new ExceptionEvent($this->kernel, $request, HttpKernelInterface::SUB_REQUEST, $e); $this->dispatcher->dispatch($event, KernelEvents::EXCEPTION); } // let's clean up the output buffers that were created by the sub-request Response::closeOutputBuffers($level, false); if (isset($options['alt'])) { $alt = $options['alt']; unset($options['alt']); return $this->render($alt, $request, $options); } if (!isset($options['ignore_errors']) || !$options['ignore_errors']) { throw $e; } return new Response(); } } /** * @return Request */ protected function createSubRequest(string $uri, Request $request) { $cookies = $request->cookies->all(); $server = $request->server->all(); unset($server['HTTP_IF_MODIFIED_SINCE']); unset($server['HTTP_IF_NONE_MATCH']); $subRequest = Request::create($uri, 'get', [], $cookies, [], $server); if ($request->headers->has('Surrogate-Capability')) { $subRequest->headers->set('Surrogate-Capability', $request->headers->get('Surrogate-Capability')); } static $setSession; $setSession ??= \Closure::bind(static function ($subRequest, $request) { $subRequest->session = $request->session; }, null, Request::class); $setSession($subRequest, $request); if ($request->get('_format')) { $subRequest->attributes->set('_format', $request->get('_format')); } if ($request->getDefaultLocale() !== $request->getLocale()) { $subRequest->setLocale($request->getLocale()); } if ($request->attributes->has('_stateless')) { $subRequest->attributes->set('_stateless', $request->attributes->get('_stateless')); } return $subRequest; } public function getName(): string { return 'inline'; } } Fragment/EsiFragmentRenderer.php 0000644 00000001026 15111167614 0012715 0 ustar 00 <?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\HttpKernel\Fragment; /** * Implements the ESI rendering strategy. * * @author Fabien Potencier <fabien@symfony.com> */ class EsiFragmentRenderer extends AbstractSurrogateFragmentRenderer { public function getName(): string { return 'esi'; } } Fragment/HIncludeFragmentRenderer.php 0000644 00000006434 15111167614 0013700 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\UriSigner; use Twig\Environment; /** * Implements the Hinclude rendering strategy. * * @author Fabien Potencier <fabien@symfony.com> */ class HIncludeFragmentRenderer extends RoutableFragmentRenderer { private ?string $globalDefaultTemplate; private ?UriSigner $signer; private ?Environment $twig; private string $charset; /** * @param string|null $globalDefaultTemplate The global default content (it can be a template name or the content) */ public function __construct(Environment $twig = null, UriSigner $signer = null, string $globalDefaultTemplate = null, string $charset = 'utf-8') { $this->twig = $twig; $this->globalDefaultTemplate = $globalDefaultTemplate; $this->signer = $signer; $this->charset = $charset; } /** * Checks if a templating engine has been set. */ public function hasTemplating(): bool { return null !== $this->twig; } /** * Additional available options: * * * default: The default content (it can be a template name or the content) * * id: An optional hx:include tag id attribute * * attributes: An optional array of hx:include tag attributes */ public function render(string|ControllerReference $uri, Request $request, array $options = []): Response { if ($uri instanceof ControllerReference) { $uri = (new FragmentUriGenerator($this->fragmentPath, $this->signer))->generate($uri, $request); } // We need to replace ampersands in the URI with the encoded form in order to return valid html/xml content. $uri = str_replace('&', '&', $uri); $template = $options['default'] ?? $this->globalDefaultTemplate; if (null !== $this->twig && $template && $this->twig->getLoader()->exists($template)) { $content = $this->twig->render($template); } else { $content = $template; } $attributes = isset($options['attributes']) && \is_array($options['attributes']) ? $options['attributes'] : []; if (isset($options['id']) && $options['id']) { $attributes['id'] = $options['id']; } $renderedAttributes = ''; if (\count($attributes) > 0) { $flags = \ENT_QUOTES | \ENT_SUBSTITUTE; foreach ($attributes as $attribute => $value) { $renderedAttributes .= sprintf( ' %s="%s"', htmlspecialchars($attribute, $flags, $this->charset, false), htmlspecialchars($value, $flags, $this->charset, false) ); } } return new Response(sprintf('<hx:include src="%s"%s>%s</hx:include>', $uri, $renderedAttributes, $content)); } public function getName(): string { return 'hinclude'; } } Fragment/SsiFragmentRenderer.php 0000644 00000001026 15111167614 0012733 0 ustar 00 <?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\HttpKernel\Fragment; /** * Implements the SSI rendering strategy. * * @author Sebastian Krebs <krebs.seb@gmail.com> */ class SsiFragmentRenderer extends AbstractSurrogateFragmentRenderer { public function getName(): string { return 'ssi'; } } Fragment/FragmentUriGeneratorInterface.php 0000644 00000002012 15111167614 0014731 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ControllerReference; /** * Interface implemented by rendering strategies able to generate a URL for a fragment. * * @author Kévin Dunglas <kevin@dunglas.fr> */ interface FragmentUriGeneratorInterface { /** * Generates a fragment URI for a given controller. * * @param bool $absolute Whether to generate an absolute URL or not * @param bool $strict Whether to allow non-scalar attributes or not * @param bool $sign Whether to sign the URL or not */ public function generate(ControllerReference $controller, Request $request = null, bool $absolute = false, bool $strict = true, bool $sign = true): string; } Fragment/error_log 0000644 00000012660 15111167614 0010234 0 ustar 00 [19-Nov-2025 14:41:39 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php on line 23 [19-Nov-2025 14:45:42 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php on line 25 [19-Nov-2025 14:48:48 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\AbstractSurrogateFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php on line 19 [19-Nov-2025 14:49:39 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\AbstractSurrogateFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php on line 19 [19-Nov-2025 14:56:39 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Fragment\FragmentUriGeneratorInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/FragmentUriGenerator.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/FragmentUriGenerator.php on line 25 [19-Nov-2025 14:58:46 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php on line 25 [19-Nov-2025 15:03:52 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php on line 28 [19-Nov-2025 23:04:01 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php:28 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php on line 28 [19-Nov-2025 23:06:07 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php:23 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php on line 23 [19-Nov-2025 23:09:07 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\AbstractSurrogateFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php on line 19 [19-Nov-2025 23:10:08 UTC] PHP Fatal error: Uncaught Error: Interface "Symfony\Component\HttpKernel\Fragment\FragmentUriGeneratorInterface" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/FragmentUriGenerator.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/FragmentUriGenerator.php on line 25 [19-Nov-2025 23:12:15 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\AbstractSurrogateFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php:19 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php on line 19 [19-Nov-2025 23:13:19 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php on line 25 [19-Nov-2025 23:18:33 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php:25 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php on line 25 Fragment/FragmentHandler.php 0000644 00000007144 15111167614 0012072 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\Exception\HttpException; /** * Renders a URI that represents a resource fragment. * * This class handles the rendering of resource fragments that are included into * a main resource. The handling of the rendering is managed by specialized renderers. * * @author Fabien Potencier <fabien@symfony.com> * * @see FragmentRendererInterface */ class FragmentHandler { private bool $debug; private array $renderers = []; private RequestStack $requestStack; /** * @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances * @param bool $debug Whether the debug mode is enabled or not */ public function __construct(RequestStack $requestStack, array $renderers = [], bool $debug = false) { $this->requestStack = $requestStack; foreach ($renderers as $renderer) { $this->addRenderer($renderer); } $this->debug = $debug; } /** * Adds a renderer. * * @return void */ public function addRenderer(FragmentRendererInterface $renderer) { $this->renderers[$renderer->getName()] = $renderer; } /** * Renders a URI and returns the Response content. * * Available options: * * * ignore_errors: true to return an empty string in case of an error * * @throws \InvalidArgumentException when the renderer does not exist * @throws \LogicException when no main request is being handled */ public function render(string|ControllerReference $uri, string $renderer = 'inline', array $options = []): ?string { if (!isset($options['ignore_errors'])) { $options['ignore_errors'] = !$this->debug; } if (!isset($this->renderers[$renderer])) { throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer)); } if (!$request = $this->requestStack->getCurrentRequest()) { throw new \LogicException('Rendering a fragment can only be done when handling a Request.'); } return $this->deliver($this->renderers[$renderer]->render($uri, $request, $options)); } /** * Delivers the Response as a string. * * When the Response is a StreamedResponse, the content is streamed immediately * instead of being returned. * * @return string|null The Response content or null when the Response is streamed * * @throws \RuntimeException when the Response is not successful */ protected function deliver(Response $response): ?string { if (!$response->isSuccessful()) { $responseStatusCode = $response->getStatusCode(); throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %d).', $this->requestStack->getCurrentRequest()->getUri(), $responseStatusCode), 0, new HttpException($responseStatusCode)); } if (!$response instanceof StreamedResponse) { return $response->getContent(); } $response->sendContent(); return null; } } Fragment/AbstractSurrogateFragmentRenderer.php 0000644 00000007375 15111167614 0015651 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\HttpCache\SurrogateInterface; use Symfony\Component\HttpKernel\UriSigner; /** * Implements Surrogate rendering strategy. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class AbstractSurrogateFragmentRenderer extends RoutableFragmentRenderer { private ?SurrogateInterface $surrogate; private FragmentRendererInterface $inlineStrategy; private ?UriSigner $signer; /** * The "fallback" strategy when surrogate is not available should always be an * instance of InlineFragmentRenderer. * * @param FragmentRendererInterface $inlineStrategy The inline strategy to use when the surrogate is not supported */ public function __construct(SurrogateInterface $surrogate = null, FragmentRendererInterface $inlineStrategy, UriSigner $signer = null) { $this->surrogate = $surrogate; $this->inlineStrategy = $inlineStrategy; $this->signer = $signer; } /** * Note that if the current Request has no surrogate capability, this method * falls back to use the inline rendering strategy. * * Additional available options: * * * alt: an alternative URI to render in case of an error * * comment: a comment to add when returning the surrogate tag * * absolute_uri: whether to generate an absolute URI or not. Default is false * * Note, that not all surrogate strategies support all options. For now * 'alt' and 'comment' are only supported by ESI. * * @see Symfony\Component\HttpKernel\HttpCache\SurrogateInterface */ public function render(string|ControllerReference $uri, Request $request, array $options = []): Response { if (!$this->surrogate || !$this->surrogate->hasSurrogateCapability($request)) { if ($uri instanceof ControllerReference && $this->containsNonScalars($uri->attributes)) { throw new \InvalidArgumentException('Passing non-scalar values as part of URI attributes to the ESI and SSI rendering strategies is not supported. Use a different rendering strategy or pass scalar values.'); } return $this->inlineStrategy->render($uri, $request, $options); } $absolute = $options['absolute_uri'] ?? false; if ($uri instanceof ControllerReference) { $uri = $this->generateSignedFragmentUri($uri, $request, $absolute); } $alt = $options['alt'] ?? null; if ($alt instanceof ControllerReference) { $alt = $this->generateSignedFragmentUri($alt, $request, $absolute); } $tag = $this->surrogate->renderIncludeTag($uri, $alt, $options['ignore_errors'] ?? false, $options['comment'] ?? ''); return new Response($tag); } private function generateSignedFragmentUri(ControllerReference $uri, Request $request, bool $absolute): string { return (new FragmentUriGenerator($this->fragmentPath, $this->signer))->generate($uri, $request, $absolute); } private function containsNonScalars(array $values): bool { foreach ($values as $value) { if (\is_scalar($value) || null === $value) { continue; } if (!\is_array($value) || $this->containsNonScalars($value)) { return true; } } return false; } } Fragment/FragmentUriGenerator.php 0000644 00000006716 15111167614 0013127 0 ustar 00 <?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\HttpKernel\Fragment; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\UriSigner; /** * Generates a fragment URI. * * @author Kévin Dunglas <kevin@dunglas.fr> * @author Fabien Potencier <fabien@symfony.com> */ final class FragmentUriGenerator implements FragmentUriGeneratorInterface { private string $fragmentPath; private ?UriSigner $signer; private ?RequestStack $requestStack; public function __construct(string $fragmentPath, UriSigner $signer = null, RequestStack $requestStack = null) { $this->fragmentPath = $fragmentPath; $this->signer = $signer; $this->requestStack = $requestStack; } public function generate(ControllerReference $controller, Request $request = null, bool $absolute = false, bool $strict = true, bool $sign = true): string { if (null === $request && (null === $this->requestStack || null === $request = $this->requestStack->getCurrentRequest())) { throw new \LogicException('Generating a fragment URL can only be done when handling a Request.'); } if ($sign && null === $this->signer) { throw new \LogicException('You must use a URI when using the ESI rendering strategy or set a URL signer.'); } if ($strict) { $this->checkNonScalar($controller->attributes); } // We need to forward the current _format and _locale values as we don't have // a proper routing pattern to do the job for us. // This makes things inconsistent if you switch from rendering a controller // to rendering a route if the route pattern does not contain the special // _format and _locale placeholders. if (!isset($controller->attributes['_format'])) { $controller->attributes['_format'] = $request->getRequestFormat(); } if (!isset($controller->attributes['_locale'])) { $controller->attributes['_locale'] = $request->getLocale(); } $controller->attributes['_controller'] = $controller->controller; $controller->query['_path'] = http_build_query($controller->attributes, '', '&'); $path = $this->fragmentPath.'?'.http_build_query($controller->query, '', '&'); // we need to sign the absolute URI, but want to return the path only. $fragmentUri = $sign || $absolute ? $request->getUriForPath($path) : $request->getBaseUrl().$path; if (!$sign) { return $fragmentUri; } $fragmentUri = $this->signer->sign($fragmentUri); return $absolute ? $fragmentUri : substr($fragmentUri, \strlen($request->getSchemeAndHttpHost())); } private function checkNonScalar(array $values): void { foreach ($values as $key => $value) { if (\is_array($value)) { $this->checkNonScalar($value); } elseif (!\is_scalar($value) && null !== $value) { throw new \LogicException(sprintf('Controller attributes cannot contain non-scalar/non-null values (value for key "%s" is not a scalar or null).', $key)); } } } } Kernel.php 0000644 00000072061 15111167614 0006506 0 ustar 00 <?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\HttpKernel; use Symfony\Component\Config\Builder\ConfigBuilderGenerator; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\Loader\DelegatingLoader; use Symfony\Component\Config\Loader\LoaderResolver; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Compiler\RemoveBuildParametersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Dumper\Preloader; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\DependencyInjection\Loader\ClosureLoader; use Symfony\Component\DependencyInjection\Loader\DirectoryLoader; use Symfony\Component\DependencyInjection\Loader\GlobFileLoader; use Symfony\Component\DependencyInjection\Loader\IniFileLoader; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\ErrorHandler\DebugClassLoader; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; use Symfony\Component\HttpKernel\Config\FileLocator; use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; // Help opcache.preload discover always-needed symbols class_exists(ConfigCache::class); /** * The Kernel is the heart of the Symfony system. * * It manages an environment made of bundles. * * Environment names must always start with a letter and * they must only contain letters and numbers. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class Kernel implements KernelInterface, RebootableInterface, TerminableInterface { /** * @var array<string, BundleInterface> */ protected $bundles = []; protected $container; protected $environment; protected $debug; protected $booted = false; protected $startTime; private string $projectDir; private ?string $warmupDir = null; private int $requestStackSize = 0; private bool $resetServices = false; /** * @var array<string, bool> */ private static array $freshCache = []; public const VERSION = '6.3.7'; public const VERSION_ID = 60307; public const MAJOR_VERSION = 6; public const MINOR_VERSION = 3; public const RELEASE_VERSION = 7; public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '01/2024'; public const END_OF_LIFE = '01/2024'; public function __construct(string $environment, bool $debug) { if (!$this->environment = $environment) { throw new \InvalidArgumentException(sprintf('Invalid environment provided to "%s": the environment cannot be empty.', get_debug_type($this))); } $this->debug = $debug; } public function __clone() { $this->booted = false; $this->container = null; $this->requestStackSize = 0; $this->resetServices = false; } /** * @return void */ public function boot() { if (true === $this->booted) { if (!$this->requestStackSize && $this->resetServices) { if ($this->container->has('services_resetter')) { $this->container->get('services_resetter')->reset(); } $this->resetServices = false; if ($this->debug) { $this->startTime = microtime(true); } } return; } if (null === $this->container) { $this->preBoot(); } foreach ($this->getBundles() as $bundle) { $bundle->setContainer($this->container); $bundle->boot(); } $this->booted = true; } /** * @return void */ public function reboot(?string $warmupDir) { $this->shutdown(); $this->warmupDir = $warmupDir; $this->boot(); } /** * @return void */ public function terminate(Request $request, Response $response) { if (false === $this->booted) { return; } if ($this->getHttpKernel() instanceof TerminableInterface) { $this->getHttpKernel()->terminate($request, $response); } } /** * @return void */ public function shutdown() { if (false === $this->booted) { return; } $this->booted = false; foreach ($this->getBundles() as $bundle) { $bundle->shutdown(); $bundle->setContainer(null); } $this->container = null; $this->requestStackSize = 0; $this->resetServices = false; } public function handle(Request $request, int $type = HttpKernelInterface::MAIN_REQUEST, bool $catch = true): Response { if (!$this->booted) { $container = $this->container ?? $this->preBoot(); if ($container->has('http_cache')) { return $container->get('http_cache')->handle($request, $type, $catch); } } $this->boot(); ++$this->requestStackSize; $this->resetServices = true; try { return $this->getHttpKernel()->handle($request, $type, $catch); } finally { --$this->requestStackSize; } } /** * Gets an HTTP kernel from the container. */ protected function getHttpKernel(): HttpKernelInterface { return $this->container->get('http_kernel'); } public function getBundles(): array { return $this->bundles; } public function getBundle(string $name): BundleInterface { if (!isset($this->bundles[$name])) { throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, get_debug_type($this))); } return $this->bundles[$name]; } public function locateResource(string $name): string { if ('@' !== $name[0]) { throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); } if (str_contains($name, '..')) { throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); } $bundleName = substr($name, 1); $path = ''; if (str_contains($bundleName, '/')) { [$bundleName, $path] = explode('/', $bundleName, 2); } $bundle = $this->getBundle($bundleName); if (file_exists($file = $bundle->getPath().'/'.$path)) { return $file; } throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); } public function getEnvironment(): string { return $this->environment; } public function isDebug(): bool { return $this->debug; } /** * Gets the application root dir (path of the project's composer file). */ public function getProjectDir(): string { if (!isset($this->projectDir)) { $r = new \ReflectionObject($this); if (!is_file($dir = $r->getFileName())) { throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name)); } $dir = $rootDir = \dirname($dir); while (!is_file($dir.'/composer.json')) { if ($dir === \dirname($dir)) { return $this->projectDir = $rootDir; } $dir = \dirname($dir); } $this->projectDir = $dir; } return $this->projectDir; } public function getContainer(): ContainerInterface { if (!$this->container) { throw new \LogicException('Cannot retrieve the container from a non-booted kernel.'); } return $this->container; } /** * @internal */ public function setAnnotatedClassCache(array $annotatedClasses): void { file_put_contents(($this->warmupDir ?: $this->getBuildDir()).'/annotations.map', sprintf('<?php return %s;', var_export($annotatedClasses, true))); } public function getStartTime(): float { return $this->debug && null !== $this->startTime ? $this->startTime : -\INF; } public function getCacheDir(): string { return $this->getProjectDir().'/var/cache/'.$this->environment; } public function getBuildDir(): string { // Returns $this->getCacheDir() for backward compatibility return $this->getCacheDir(); } public function getLogDir(): string { return $this->getProjectDir().'/var/log'; } public function getCharset(): string { return 'UTF-8'; } /** * Gets the patterns defining the classes to parse and cache for annotations. */ public function getAnnotatedClassesToCompile(): array { return []; } /** * Initializes bundles. * * @return void * * @throws \LogicException if two bundles share a common name */ protected function initializeBundles() { // init bundles $this->bundles = []; foreach ($this->registerBundles() as $bundle) { $name = $bundle->getName(); if (isset($this->bundles[$name])) { throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s".', $name)); } $this->bundles[$name] = $bundle; } } /** * The extension point similar to the Bundle::build() method. * * Use this method to register compiler passes and manipulate the container during the building process. * * @return void */ protected function build(ContainerBuilder $container) { } /** * Gets the container class. * * @throws \InvalidArgumentException If the generated classname is invalid */ protected function getContainerClass(): string { $class = static::class; $class = str_contains($class, "@anonymous\0") ? get_parent_class($class).str_replace('.', '_', ContainerBuilder::hash($class)) : $class; $class = str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container'; if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $class)) { throw new \InvalidArgumentException(sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment)); } return $class; } /** * Gets the container's base class. * * All names except Container must be fully qualified. */ protected function getContainerBaseClass(): string { return 'Container'; } /** * Initializes the service container. * * The built version of the service container is used when fresh, otherwise the * container is built. * * @return void */ protected function initializeContainer() { $class = $this->getContainerClass(); $buildDir = $this->warmupDir ?: $this->getBuildDir(); $cache = new ConfigCache($buildDir.'/'.$class.'.php', $this->debug); $cachePath = $cache->getPath(); // Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors $errorLevel = error_reporting(\E_ALL ^ \E_WARNING); try { if (is_file($cachePath) && \is_object($this->container = include $cachePath) && (!$this->debug || (self::$freshCache[$cachePath] ?? $cache->isFresh())) ) { self::$freshCache[$cachePath] = true; $this->container->set('kernel', $this); error_reporting($errorLevel); return; } } catch (\Throwable $e) { } $oldContainer = \is_object($this->container) ? new \ReflectionClass($this->container) : $this->container = null; try { is_dir($buildDir) ?: mkdir($buildDir, 0777, true); if ($lock = fopen($cachePath.'.lock', 'w+')) { if (!flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock) && !flock($lock, $wouldBlock ? \LOCK_SH : \LOCK_EX)) { fclose($lock); $lock = null; } elseif (!is_file($cachePath) || !\is_object($this->container = include $cachePath)) { $this->container = null; } elseif (!$oldContainer || $this->container::class !== $oldContainer->name) { flock($lock, \LOCK_UN); fclose($lock); $this->container->set('kernel', $this); return; } } } catch (\Throwable $e) { } finally { error_reporting($errorLevel); } if ($collectDeprecations = $this->debug && !\defined('PHPUNIT_COMPOSER_INSTALL')) { $collectedLogs = []; $previousHandler = set_error_handler(function ($type, $message, $file, $line) use (&$collectedLogs, &$previousHandler) { if (\E_USER_DEPRECATED !== $type && \E_DEPRECATED !== $type) { return $previousHandler ? $previousHandler($type, $message, $file, $line) : false; } if (isset($collectedLogs[$message])) { ++$collectedLogs[$message]['count']; return null; } $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 5); // Clean the trace by removing first frames added by the error handler itself. for ($i = 0; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) { $backtrace = \array_slice($backtrace, 1 + $i); break; } } for ($i = 0; isset($backtrace[$i]); ++$i) { if (!isset($backtrace[$i]['file'], $backtrace[$i]['line'], $backtrace[$i]['function'])) { continue; } if (!isset($backtrace[$i]['class']) && 'trigger_deprecation' === $backtrace[$i]['function']) { $file = $backtrace[$i]['file']; $line = $backtrace[$i]['line']; $backtrace = \array_slice($backtrace, 1 + $i); break; } } // Remove frames added by DebugClassLoader. for ($i = \count($backtrace) - 2; 0 < $i; --$i) { if (DebugClassLoader::class === ($backtrace[$i]['class'] ?? null)) { $backtrace = [$backtrace[$i + 1]]; break; } } $collectedLogs[$message] = [ 'type' => $type, 'message' => $message, 'file' => $file, 'line' => $line, 'trace' => [$backtrace[0]], 'count' => 1, ]; return null; }); } try { $container = null; $container = $this->buildContainer(); $container->compile(); } finally { if ($collectDeprecations) { restore_error_handler(); @file_put_contents($buildDir.'/'.$class.'Deprecations.log', serialize(array_values($collectedLogs))); @file_put_contents($buildDir.'/'.$class.'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : ''); } } $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); if ($lock) { flock($lock, \LOCK_UN); fclose($lock); } $this->container = require $cachePath; $this->container->set('kernel', $this); if ($oldContainer && $this->container::class !== $oldContainer->name) { // Because concurrent requests might still be using them, // old container files are not removed immediately, // but on a next dump of the container. static $legacyContainers = []; $oldContainerDir = \dirname($oldContainer->getFileName()); $legacyContainers[$oldContainerDir.'.legacy'] = true; foreach (glob(\dirname($oldContainerDir).\DIRECTORY_SEPARATOR.'*.legacy', \GLOB_NOSORT) as $legacyContainer) { if (!isset($legacyContainers[$legacyContainer]) && @unlink($legacyContainer)) { (new Filesystem())->remove(substr($legacyContainer, 0, -7)); } } touch($oldContainerDir.'.legacy'); } $preload = $this instanceof WarmableInterface ? (array) $this->warmUp($this->container->getParameter('kernel.cache_dir')) : []; if ($this->container->has('cache_warmer')) { $preload = array_merge($preload, (array) $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'))); } if ($preload && file_exists($preloadFile = $buildDir.'/'.$class.'.preload.php')) { Preloader::append($preloadFile, $preload); } } /** * Returns the kernel parameters. */ protected function getKernelParameters(): array { $bundles = []; $bundlesMetadata = []; foreach ($this->bundles as $name => $bundle) { $bundles[$name] = $bundle::class; $bundlesMetadata[$name] = [ 'path' => $bundle->getPath(), 'namespace' => $bundle->getNamespace(), ]; } return [ 'kernel.project_dir' => realpath($this->getProjectDir()) ?: $this->getProjectDir(), 'kernel.environment' => $this->environment, 'kernel.runtime_environment' => '%env(default:kernel.environment:APP_RUNTIME_ENV)%', 'kernel.debug' => $this->debug, 'kernel.build_dir' => realpath($buildDir = $this->warmupDir ?: $this->getBuildDir()) ?: $buildDir, 'kernel.cache_dir' => realpath($cacheDir = ($this->getCacheDir() === $this->getBuildDir() ? ($this->warmupDir ?: $this->getCacheDir()) : $this->getCacheDir())) ?: $cacheDir, 'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(), 'kernel.bundles' => $bundles, 'kernel.bundles_metadata' => $bundlesMetadata, 'kernel.charset' => $this->getCharset(), 'kernel.container_class' => $this->getContainerClass(), ]; } /** * Builds the service container. * * @throws \RuntimeException */ protected function buildContainer(): ContainerBuilder { foreach (['cache' => $this->getCacheDir(), 'build' => $this->warmupDir ?: $this->getBuildDir(), 'logs' => $this->getLogDir()] as $name => $dir) { if (!is_dir($dir)) { if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir)); } } elseif (!is_writable($dir)) { throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir)); } } $container = $this->getContainerBuilder(); $container->addObjectResource($this); $this->prepareContainer($container); $this->registerContainerConfiguration($this->getContainerLoader($container)); $container->addCompilerPass(new AddAnnotatedClassesToCachePass($this)); return $container; } /** * Prepares the ContainerBuilder before it is compiled. * * @return void */ protected function prepareContainer(ContainerBuilder $container) { $extensions = []; foreach ($this->bundles as $bundle) { if ($extension = $bundle->getContainerExtension()) { $container->registerExtension($extension); } if ($this->debug) { $container->addObjectResource($bundle); } } foreach ($this->bundles as $bundle) { $bundle->build($container); } $this->build($container); foreach ($container->getExtensions() as $extension) { $extensions[] = $extension->getAlias(); } // ensure these extensions are implicitly loaded $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); } /** * Gets a new ContainerBuilder instance used to build the service container. */ protected function getContainerBuilder(): ContainerBuilder { $container = new ContainerBuilder(); $container->getParameterBag()->add($this->getKernelParameters()); if ($this instanceof ExtensionInterface) { $container->registerExtension($this); } if ($this instanceof CompilerPassInterface) { $container->addCompilerPass($this, PassConfig::TYPE_BEFORE_OPTIMIZATION, -10000); } return $container; } /** * Dumps the service container to PHP code in the cache. * * @param string $class The name of the class to generate * @param string $baseClass The name of the container's base class * * @return void */ protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, string $class, string $baseClass) { // cache the container $dumper = new PhpDumper($container); $buildParameters = []; foreach ($container->getCompilerPassConfig()->getPasses() as $pass) { if ($pass instanceof RemoveBuildParametersPass) { $buildParameters = array_merge($buildParameters, $pass->getRemovedParameters()); } } $inlineFactories = false; if (isset($buildParameters['.container.dumper.inline_factories'])) { $inlineFactories = $buildParameters['.container.dumper.inline_factories']; } elseif ($container->hasParameter('container.dumper.inline_factories')) { trigger_deprecation('symfony/http-kernel', '6.3', 'Parameter "%s" is deprecated, use ".%1$s" instead.', 'container.dumper.inline_factories'); $inlineFactories = $container->getParameter('container.dumper.inline_factories'); } $inlineClassLoader = $this->debug; if (isset($buildParameters['.container.dumper.inline_class_loader'])) { $inlineClassLoader = $buildParameters['.container.dumper.inline_class_loader']; } elseif ($container->hasParameter('container.dumper.inline_class_loader')) { trigger_deprecation('symfony/http-kernel', '6.3', 'Parameter "%s" is deprecated, use ".%1$s" instead.', 'container.dumper.inline_class_loader'); $inlineClassLoader = $container->getParameter('container.dumper.inline_class_loader'); } $content = $dumper->dump([ 'class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath(), 'as_files' => true, 'debug' => $this->debug, 'inline_factories' => $inlineFactories, 'inline_class_loader' => $inlineClassLoader, 'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(), 'preload_classes' => array_map('get_class', $this->bundles), ]); $rootCode = array_pop($content); $dir = \dirname($cache->getPath()).'/'; $fs = new Filesystem(); foreach ($content as $file => $code) { $fs->dumpFile($dir.$file, $code); @chmod($dir.$file, 0666 & ~umask()); } $legacyFile = \dirname($dir.key($content)).'.legacy'; if (is_file($legacyFile)) { @unlink($legacyFile); } $cache->write($rootCode, $container->getResources()); } /** * Returns a loader for the container. */ protected function getContainerLoader(ContainerInterface $container): DelegatingLoader { $env = $this->getEnvironment(); $locator = new FileLocator($this); $resolver = new LoaderResolver([ new XmlFileLoader($container, $locator, $env), new YamlFileLoader($container, $locator, $env), new IniFileLoader($container, $locator, $env), new PhpFileLoader($container, $locator, $env, class_exists(ConfigBuilderGenerator::class) ? new ConfigBuilderGenerator($this->getBuildDir()) : null), new GlobFileLoader($container, $locator, $env), new DirectoryLoader($container, $locator, $env), new ClosureLoader($container, $env), ]); return new DelegatingLoader($resolver); } private function preBoot(): ContainerInterface { if ($this->debug) { $this->startTime = microtime(true); } if ($this->debug && !isset($_ENV['SHELL_VERBOSITY']) && !isset($_SERVER['SHELL_VERBOSITY'])) { putenv('SHELL_VERBOSITY=3'); $_ENV['SHELL_VERBOSITY'] = 3; $_SERVER['SHELL_VERBOSITY'] = 3; } $this->initializeBundles(); $this->initializeContainer(); $container = $this->container; if ($container->hasParameter('kernel.trusted_hosts') && $trustedHosts = $container->getParameter('kernel.trusted_hosts')) { Request::setTrustedHosts($trustedHosts); } if ($container->hasParameter('kernel.trusted_proxies') && $container->hasParameter('kernel.trusted_headers') && $trustedProxies = $container->getParameter('kernel.trusted_proxies')) { Request::setTrustedProxies(\is_array($trustedProxies) ? $trustedProxies : array_map('trim', explode(',', $trustedProxies)), $container->getParameter('kernel.trusted_headers')); } return $container; } /** * Removes comments from a PHP source string. * * We don't use the PHP php_strip_whitespace() function * as we want the content to be readable and well-formatted. */ public static function stripComments(string $source): string { if (!\function_exists('token_get_all')) { return $source; } $rawChunk = ''; $output = ''; $tokens = token_get_all($source); $ignoreSpace = false; for ($i = 0; isset($tokens[$i]); ++$i) { $token = $tokens[$i]; if (!isset($token[1]) || 'b"' === $token) { $rawChunk .= $token; } elseif (\T_START_HEREDOC === $token[0]) { $output .= $rawChunk.$token[1]; do { $token = $tokens[++$i]; $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token; } while (\T_END_HEREDOC !== $token[0]); $rawChunk = ''; } elseif (\T_WHITESPACE === $token[0]) { if ($ignoreSpace) { $ignoreSpace = false; continue; } // replace multiple new lines with a single newline $rawChunk .= preg_replace(['/\n{2,}/S'], "\n", $token[1]); } elseif (\in_array($token[0], [\T_COMMENT, \T_DOC_COMMENT])) { if (!\in_array($rawChunk[\strlen($rawChunk) - 1], [' ', "\n", "\r", "\t"], true)) { $rawChunk .= ' '; } $ignoreSpace = true; } else { $rawChunk .= $token[1]; // The PHP-open tag already has a new-line if (\T_OPEN_TAG === $token[0]) { $ignoreSpace = true; } else { $ignoreSpace = false; } } } $output .= $rawChunk; unset($tokens, $rawChunk); gc_mem_caches(); return $output; } public function __sleep(): array { return ['environment', 'debug']; } public function __wakeup() { if (\is_object($this->environment) || \is_object($this->debug)) { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } $this->__construct($this->environment, $this->debug); } } Config/error_log 0000644 00000000522 15111167614 0007670 0 ustar 00 [19-Nov-2025 12:05:21 UTC] PHP Fatal error: Uncaught Error: Class "Symfony\Component\Config\FileLocator" not found in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Config/FileLocator.php:22 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/symfony/http-kernel/Config/FileLocator.php on line 22 Config/FileLocator.php 0000644 00000002116 15111167614 0010670 0 ustar 00 <?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\HttpKernel\Config; use Symfony\Component\Config\FileLocator as BaseFileLocator; use Symfony\Component\HttpKernel\KernelInterface; /** * FileLocator uses the KernelInterface to locate resources in bundles. * * @author Fabien Potencier <fabien@symfony.com> */ class FileLocator extends BaseFileLocator { private KernelInterface $kernel; public function __construct(KernelInterface $kernel) { $this->kernel = $kernel; parent::__construct(); } public function locate(string $file, string $currentPath = null, bool $first = true): string|array { if (isset($file[0]) && '@' === $file[0]) { $resource = $this->kernel->locateResource($file); return $first ? $resource : [$resource]; } return parent::locate($file, $currentPath, $first); } }