package and depencies
This commit is contained in:
84
vendor/symfony/http-kernel/Attribute/Cache.php
vendored
Normal file
84
vendor/symfony/http-kernel/Attribute/Cache.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?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,
|
||||
) {
|
||||
}
|
||||
}
|
@@ -11,13 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Attribute;
|
||||
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'The "%s" interface is deprecated.', ArgumentInterface::class);
|
||||
|
||||
/**
|
||||
* Marker interface for controller argument attributes.
|
||||
*
|
||||
* @deprecated since Symfony 5.3
|
||||
* Controller parameter tag to configure DateTime arguments.
|
||||
*/
|
||||
interface ArgumentInterface
|
||||
#[\Attribute(\Attribute::TARGET_PARAMETER)]
|
||||
class MapDateTime
|
||||
{
|
||||
public function __construct(
|
||||
public readonly ?string $format = null
|
||||
) {
|
||||
}
|
||||
}
|
61
vendor/symfony/http-kernel/Bundle/AbstractBundle.php
vendored
Normal file
61
vendor/symfony/http-kernel/Bundle/AbstractBundle.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
38
vendor/symfony/http-kernel/Bundle/Bundle.php
vendored
38
vendor/symfony/http-kernel/Bundle/Bundle.php
vendored
@@ -29,25 +29,17 @@ abstract class Bundle implements BundleInterface
|
||||
protected $name;
|
||||
protected $extension;
|
||||
protected $path;
|
||||
private $namespace;
|
||||
private string $namespace;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This method can be overridden to register compilation passes,
|
||||
* other extensions, ...
|
||||
*/
|
||||
@@ -58,11 +50,9 @@ abstract class Bundle implements BundleInterface
|
||||
/**
|
||||
* Returns the bundle's container extension.
|
||||
*
|
||||
* @return ExtensionInterface|null
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function getContainerExtension()
|
||||
public function getContainerExtension(): ?ExtensionInterface
|
||||
{
|
||||
if (null === $this->extension) {
|
||||
$extension = $this->createContainerExtension();
|
||||
@@ -89,22 +79,16 @@ abstract class Bundle implements BundleInterface
|
||||
return $this->extension ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNamespace()
|
||||
public function getNamespace(): string
|
||||
{
|
||||
if (null === $this->namespace) {
|
||||
if (!isset($this->namespace)) {
|
||||
$this->parseClassName();
|
||||
}
|
||||
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPath()
|
||||
public function getPath(): string
|
||||
{
|
||||
if (null === $this->path) {
|
||||
$reflected = new \ReflectionObject($this);
|
||||
@@ -132,10 +116,8 @@ abstract class Bundle implements BundleInterface
|
||||
|
||||
/**
|
||||
* Returns the bundle's container extension class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getContainerExtensionClass()
|
||||
protected function getContainerExtensionClass(): string
|
||||
{
|
||||
$basename = preg_replace('/Bundle$/', '', $this->getName());
|
||||
|
||||
@@ -144,10 +126,8 @@ abstract class Bundle implements BundleInterface
|
||||
|
||||
/**
|
||||
* Creates the bundle's container extension.
|
||||
*
|
||||
* @return ExtensionInterface|null
|
||||
*/
|
||||
protected function createContainerExtension()
|
||||
protected function createContainerExtension(): ?ExtensionInterface
|
||||
{
|
||||
return class_exists($class = $this->getContainerExtensionClass()) ? new $class() : null;
|
||||
}
|
||||
@@ -156,8 +136,6 @@ abstract class Bundle implements BundleInterface
|
||||
{
|
||||
$pos = strrpos(static::class, '\\');
|
||||
$this->namespace = false === $pos ? '' : substr(static::class, 0, $pos);
|
||||
if (null === $this->name) {
|
||||
$this->name = false === $pos ? static::class : substr(static::class, $pos + 1);
|
||||
}
|
||||
$this->name ??= false === $pos ? static::class : substr(static::class, $pos + 1);
|
||||
}
|
||||
}
|
||||
|
67
vendor/symfony/http-kernel/Bundle/BundleExtension.php
vendored
Normal file
67
vendor/symfony/http-kernel/Bundle/BundleExtension.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
@@ -41,31 +41,23 @@ interface BundleInterface extends ContainerAwareInterface
|
||||
|
||||
/**
|
||||
* Returns the container extension that should be implicitly loaded.
|
||||
*
|
||||
* @return ExtensionInterface|null
|
||||
*/
|
||||
public function getContainerExtension();
|
||||
public function getContainerExtension(): ?ExtensionInterface;
|
||||
|
||||
/**
|
||||
* Returns the bundle name (the class short name).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Gets the Bundle namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace();
|
||||
public function getNamespace(): string;
|
||||
|
||||
/**
|
||||
* Gets the Bundle directory path.
|
||||
*
|
||||
* The path should always be returned as a Unix path (with /).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath();
|
||||
public function getPath(): string;
|
||||
}
|
||||
|
31
vendor/symfony/http-kernel/CHANGELOG.md
vendored
31
vendor/symfony/http-kernel/CHANGELOG.md
vendored
@@ -1,6 +1,37 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
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
|
||||
---
|
||||
|
||||
|
@@ -20,7 +20,7 @@ namespace Symfony\Component\HttpKernel\CacheClearer;
|
||||
*/
|
||||
class ChainCacheClearer implements CacheClearerInterface
|
||||
{
|
||||
private $clearers;
|
||||
private iterable $clearers;
|
||||
|
||||
/**
|
||||
* @param iterable<mixed, CacheClearerInterface> $clearers
|
||||
@@ -30,9 +30,6 @@ class ChainCacheClearer implements CacheClearerInterface
|
||||
$this->clearers = $clearers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear(string $cacheDir)
|
||||
{
|
||||
foreach ($this->clearers as $clearer) {
|
||||
|
@@ -18,7 +18,7 @@ use Psr\Cache\CacheItemPoolInterface;
|
||||
*/
|
||||
class Psr6CacheClearer implements CacheClearerInterface
|
||||
{
|
||||
private $pools = [];
|
||||
private array $pools = [];
|
||||
|
||||
/**
|
||||
* @param array<string, CacheItemPoolInterface> $pools
|
||||
@@ -28,20 +28,15 @@ class Psr6CacheClearer implements CacheClearerInterface
|
||||
$this->pools = $pools;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPool(string $name)
|
||||
public function hasPool(string $name): bool
|
||||
{
|
||||
return isset($this->pools[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CacheItemPoolInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException If the cache pool with the given name does not exist
|
||||
*/
|
||||
public function getPool(string $name)
|
||||
public function getPool(string $name): CacheItemPoolInterface
|
||||
{
|
||||
if (!$this->hasPool($name)) {
|
||||
throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name));
|
||||
@@ -51,11 +46,9 @@ class Psr6CacheClearer implements CacheClearerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @throws \InvalidArgumentException If the cache pool with the given name does not exist
|
||||
*/
|
||||
public function clearPool(string $name)
|
||||
public function clearPool(string $name): bool
|
||||
{
|
||||
if (!isset($this->pools[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name));
|
||||
@@ -64,9 +57,6 @@ class Psr6CacheClearer implements CacheClearerInterface
|
||||
return $this->pools[$name]->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear(string $cacheDir)
|
||||
{
|
||||
foreach ($this->pools as $pool) {
|
||||
|
@@ -20,11 +20,11 @@ namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
*/
|
||||
class CacheWarmerAggregate implements CacheWarmerInterface
|
||||
{
|
||||
private $warmers;
|
||||
private $debug;
|
||||
private $deprecationLogsFilepath;
|
||||
private $optionalsEnabled = false;
|
||||
private $onlyOptionalsEnabled = false;
|
||||
private iterable $warmers;
|
||||
private bool $debug;
|
||||
private ?string $deprecationLogsFilepath;
|
||||
private bool $optionalsEnabled = false;
|
||||
private bool $onlyOptionalsEnabled = false;
|
||||
|
||||
/**
|
||||
* @param iterable<mixed, CacheWarmerInterface> $warmers
|
||||
@@ -46,9 +46,6 @@ class CacheWarmerAggregate implements CacheWarmerInterface
|
||||
$this->onlyOptionalsEnabled = $this->optionalsEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function warmUp(string $cacheDir): array
|
||||
{
|
||||
if ($collectDeprecations = $this->debug && !\defined('PHPUNIT_COMPOSER_INSTALL')) {
|
||||
@@ -116,9 +113,6 @@ class CacheWarmerAggregate implements CacheWarmerInterface
|
||||
return array_values(array_unique(array_merge([], ...$preload)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isOptional(): bool
|
||||
{
|
||||
return false;
|
||||
|
@@ -21,7 +21,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
|
||||
*/
|
||||
class FileLocator extends BaseFileLocator
|
||||
{
|
||||
private $kernel;
|
||||
private KernelInterface $kernel;
|
||||
|
||||
public function __construct(KernelInterface $kernel)
|
||||
{
|
||||
@@ -30,10 +30,7 @@ class FileLocator extends BaseFileLocator
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locate(string $file, string $currentPath = null, bool $first = true)
|
||||
public function locate(string $file, string $currentPath = null, bool $first = true): string|array
|
||||
{
|
||||
if (isset($file[0]) && '@' === $file[0]) {
|
||||
$resource = $this->kernel->locateResource($file);
|
||||
|
@@ -16,6 +16,7 @@ use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolve
|
||||
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;
|
||||
@@ -27,11 +28,11 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInter
|
||||
*/
|
||||
final class ArgumentResolver implements ArgumentResolverInterface
|
||||
{
|
||||
private $argumentMetadataFactory;
|
||||
private $argumentValueResolvers;
|
||||
private ArgumentMetadataFactoryInterface $argumentMetadataFactory;
|
||||
private iterable $argumentValueResolvers;
|
||||
|
||||
/**
|
||||
* @param iterable<mixed, ArgumentValueResolverInterface> $argumentValueResolvers
|
||||
* @param iterable<mixed, ArgumentValueResolverInterface|ValueResolverInterface> $argumentValueResolvers
|
||||
*/
|
||||
public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [])
|
||||
{
|
||||
@@ -39,33 +40,34 @@ final class ArgumentResolver implements ArgumentResolverInterface
|
||||
$this->argumentValueResolvers = $argumentValueResolvers ?: self::getDefaultArgumentValueResolvers();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArguments(Request $request, callable $controller): array
|
||||
public function getArguments(Request $request, callable $controller, \ReflectionFunctionAbstract $reflector = null): array
|
||||
{
|
||||
$arguments = [];
|
||||
|
||||
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller) as $metadata) {
|
||||
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller, $reflector) as $metadata) {
|
||||
foreach ($this->argumentValueResolvers as $resolver) {
|
||||
if (!$resolver->supports($request, $metadata)) {
|
||||
if ((!$resolver instanceof ValueResolverInterface || $resolver instanceof TraceableValueResolver) && !$resolver->supports($request, $metadata)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resolved = $resolver->resolve($request, $metadata);
|
||||
|
||||
$atLeastOne = false;
|
||||
foreach ($resolved as $append) {
|
||||
$atLeastOne = true;
|
||||
$arguments[] = $append;
|
||||
$count = 0;
|
||||
foreach ($resolver->resolve($request, $metadata) as $argument) {
|
||||
++$count;
|
||||
$arguments[] = $argument;
|
||||
}
|
||||
|
||||
if (!$atLeastOne) {
|
||||
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)));
|
||||
}
|
||||
|
||||
// continue to the next controller argument
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$representative = $controller;
|
||||
@@ -73,7 +75,7 @@ final class ArgumentResolver implements ArgumentResolverInterface
|
||||
if (\is_array($representative)) {
|
||||
$representative = sprintf('%s::%s()', \get_class($representative[0]), $representative[1]);
|
||||
} elseif (\is_object($representative)) {
|
||||
$representative = \get_class($representative);
|
||||
$representative = get_debug_type($representative);
|
||||
}
|
||||
|
||||
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 because there is a non optional argument after this one.', $representative, $metadata->getName()));
|
||||
|
93
vendor/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php
vendored
Normal file
93
vendor/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
}
|
86
vendor/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php
vendored
Normal file
86
vendor/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?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\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
|
||||
{
|
||||
/**
|
||||
* @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 instanceof \DateTimeInterface) {
|
||||
return [$value instanceof $class ? $value : $class::createFromInterface($value)];
|
||||
}
|
||||
|
||||
if ($argument->isNullable() && !$value) {
|
||||
return [null];
|
||||
}
|
||||
|
||||
$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);
|
||||
|
||||
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 ?? 'now');
|
||||
} catch (\Exception) {
|
||||
$date = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$date) {
|
||||
throw new NotFoundHttpException(sprintf('Invalid date given for parameter "%s".', $argument->getName()));
|
||||
}
|
||||
|
||||
return [$date];
|
||||
}
|
||||
}
|
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -20,21 +21,28 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class DefaultValueResolver implements ArgumentValueResolverInterface
|
||||
final class DefaultValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): array
|
||||
{
|
||||
yield $argument->hasDefaultValue() ? $argument->getDefaultValue() : null;
|
||||
if ($argument->hasDefaultValue()) {
|
||||
return [$argument->getDefaultValue()];
|
||||
}
|
||||
|
||||
if (null !== $argument->getType() && $argument->isNullable() && !$argument->isVariadic()) {
|
||||
return [null];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -22,9 +23,9 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Simeon Kolev <simeon.kolev9@gmail.com>
|
||||
*/
|
||||
final class NotTaggedControllerValueResolver implements ArgumentValueResolverInterface
|
||||
final class NotTaggedControllerValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
private $container;
|
||||
private ContainerInterface $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
@@ -32,10 +33,12 @@ final class NotTaggedControllerValueResolver implements ArgumentValueResolverInt
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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])) {
|
||||
@@ -55,13 +58,14 @@ final class NotTaggedControllerValueResolver implements ArgumentValueResolverInt
|
||||
return false === $this->container->has($controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): array
|
||||
{
|
||||
if (\is_array($controller = $request->attributes->get('_controller'))) {
|
||||
$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]) {
|
||||
@@ -74,6 +78,10 @@ final class NotTaggedControllerValueResolver implements ArgumentValueResolverInt
|
||||
: $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);
|
||||
|
||||
|
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -20,21 +21,20 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class RequestAttributeValueResolver implements ArgumentValueResolverInterface
|
||||
final class RequestAttributeValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): array
|
||||
{
|
||||
yield $request->attributes->get($argument->getName());
|
||||
return !$argument->isVariadic() && $request->attributes->has($argument->getName()) ? [$request->attributes->get($argument->getName())] : [];
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -20,21 +21,20 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class RequestValueResolver implements ArgumentValueResolverInterface
|
||||
final class RequestValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): array
|
||||
{
|
||||
yield $request;
|
||||
return Request::class === $argument->getType() || is_subclass_of($argument->getType(), Request::class) ? [$request] : [];
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -22,9 +23,9 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class ServiceValueResolver implements ArgumentValueResolverInterface
|
||||
final class ServiceValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
private $container;
|
||||
private ContainerInterface $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
@@ -32,10 +33,12 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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])) {
|
||||
@@ -55,26 +58,30 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface
|
||||
return $this->container->has($controller) && $this->container->get($controller)->has($argument->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): array
|
||||
{
|
||||
if (\is_array($controller = $request->attributes->get('_controller'))) {
|
||||
$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)) {
|
||||
$i = strrpos($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 {
|
||||
yield $this->container->get($controller)->get($argument->getName());
|
||||
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());
|
||||
@@ -84,7 +91,6 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface
|
||||
}
|
||||
|
||||
$r = new \ReflectionProperty($e, 'message');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($e, $message);
|
||||
|
||||
throw $e;
|
||||
|
@@ -14,6 +14,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -21,13 +22,15 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class SessionValueResolver implements ArgumentValueResolverInterface
|
||||
final class SessionValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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;
|
||||
}
|
||||
@@ -40,11 +43,17 @@ final class SessionValueResolver implements ArgumentValueResolverInterface
|
||||
return $request->getSession() instanceof $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): array
|
||||
{
|
||||
yield $request->getSession();
|
||||
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()] : [];
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
@@ -21,22 +22,26 @@ use Symfony\Component\Stopwatch\Stopwatch;
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class TraceableValueResolver implements ArgumentValueResolverInterface
|
||||
final class TraceableValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
private $inner;
|
||||
private $stopwatch;
|
||||
private ArgumentValueResolverInterface|ValueResolverInterface $inner;
|
||||
private Stopwatch $stopwatch;
|
||||
|
||||
public function __construct(ArgumentValueResolverInterface $inner, Stopwatch $stopwatch)
|
||||
public function __construct(ArgumentValueResolverInterface|ValueResolverInterface $inner, Stopwatch $stopwatch)
|
||||
{
|
||||
$this->inner = $inner;
|
||||
$this->stopwatch = $stopwatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @deprecated since Symfony 6.2, use resolve() instead
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument): bool
|
||||
{
|
||||
if ($this->inner instanceof ValueResolverInterface) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$method = \get_class($this->inner).'::'.__FUNCTION__;
|
||||
$this->stopwatch->start($method, 'controller.argument_value_resolver');
|
||||
|
||||
@@ -47,9 +52,6 @@ final class TraceableValueResolver implements ArgumentValueResolverInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
{
|
||||
$method = \get_class($this->inner).'::'.__FUNCTION__;
|
||||
|
53
vendor/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php
vendored
Normal file
53
vendor/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -20,27 +21,30 @@ use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class VariadicValueResolver implements ArgumentValueResolverInterface
|
||||
final class VariadicValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable
|
||||
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)));
|
||||
}
|
||||
|
||||
yield from $values;
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
|
@@ -24,9 +24,9 @@ interface ArgumentResolverInterface
|
||||
/**
|
||||
* Returns the arguments to pass to the controller.
|
||||
*
|
||||
* @return array
|
||||
* @param \ReflectionFunctionAbstract|null $reflector
|
||||
*
|
||||
* @throws \RuntimeException When no value could be provided for a required argument
|
||||
*/
|
||||
public function getArguments(Request $request, callable $controller);
|
||||
public function getArguments(Request $request, callable $controller/* , \ReflectionFunctionAbstract $reflector = null */): array;
|
||||
}
|
||||
|
@@ -18,20 +18,18 @@ 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.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument);
|
||||
public function supports(Request $request, ArgumentMetadata $argument): bool;
|
||||
|
||||
/**
|
||||
* Returns the possible value(s).
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument);
|
||||
public function resolve(Request $request, ArgumentMetadata $argument): iterable;
|
||||
}
|
||||
|
@@ -32,20 +32,7 @@ class ContainerControllerResolver extends ControllerResolver
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
protected function createController(string $controller)
|
||||
{
|
||||
if (1 === substr_count($controller, ':')) {
|
||||
$controller = str_replace(':', '::', $controller);
|
||||
trigger_deprecation('symfony/http-kernel', '5.1', 'Referencing controllers with a single colon is deprecated. Use "%s" instead.', $controller);
|
||||
}
|
||||
|
||||
return parent::createController($controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function instantiateController(string $class)
|
||||
protected function instantiateController(string $class): object
|
||||
{
|
||||
$class = ltrim($class, '\\');
|
||||
|
||||
|
@@ -23,22 +23,17 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*/
|
||||
class ControllerResolver implements ControllerResolverInterface
|
||||
{
|
||||
private $logger;
|
||||
private ?LoggerInterface $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger = null)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getController(Request $request)
|
||||
public function getController(Request $request): callable|false
|
||||
{
|
||||
if (!$controller = $request->attributes->get('_controller')) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.');
|
||||
}
|
||||
$this->logger?->warning('Unable to look for the controller as the "_controller" parameter is missing.');
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -48,15 +43,8 @@ class ControllerResolver implements ControllerResolverInterface
|
||||
try {
|
||||
$controller[0] = $this->instantiateController($controller[0]);
|
||||
} catch (\Error|\LogicException $e) {
|
||||
try {
|
||||
// We cannot just check is_callable but have to use reflection because a non-static method
|
||||
// can still be called statically in PHP but we don't want that. This is deprecated in PHP 7, so we
|
||||
// could simplify this with PHP 8.
|
||||
if ((new \ReflectionMethod($controller[0], $controller[1]))->isStatic()) {
|
||||
return $controller;
|
||||
}
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
throw $e;
|
||||
if (\is_callable($controller)) {
|
||||
return $controller;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
@@ -98,11 +86,9 @@ class ControllerResolver implements ControllerResolverInterface
|
||||
/**
|
||||
* Returns a callable for the given controller.
|
||||
*
|
||||
* @return callable
|
||||
*
|
||||
* @throws \InvalidArgumentException When the controller cannot be created
|
||||
*/
|
||||
protected function createController(string $controller)
|
||||
protected function createController(string $controller): callable
|
||||
{
|
||||
if (!str_contains($controller, '::')) {
|
||||
$controller = $this->instantiateController($controller);
|
||||
@@ -123,7 +109,7 @@ class ControllerResolver implements ControllerResolverInterface
|
||||
if ((new \ReflectionMethod($class, $method))->isStatic()) {
|
||||
return $class.'::'.$method;
|
||||
}
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
} catch (\ReflectionException) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
@@ -139,15 +125,13 @@ class ControllerResolver implements ControllerResolverInterface
|
||||
|
||||
/**
|
||||
* Returns an instantiated controller.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
protected function instantiateController(string $class)
|
||||
protected function instantiateController(string $class): object
|
||||
{
|
||||
return new $class();
|
||||
}
|
||||
|
||||
private function getControllerError($callable): string
|
||||
private function getControllerError(mixed $callable): string
|
||||
{
|
||||
if (\is_string($callable)) {
|
||||
if (str_contains($callable, '::')) {
|
||||
|
@@ -37,5 +37,5 @@ interface ControllerResolverInterface
|
||||
*
|
||||
* @throws \LogicException If a controller was found based on the request but it is not callable
|
||||
*/
|
||||
public function getController(Request $request);
|
||||
public function getController(Request $request): callable|false;
|
||||
}
|
||||
|
@@ -25,11 +25,11 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
class ErrorController
|
||||
{
|
||||
private $kernel;
|
||||
private $controller;
|
||||
private $errorRenderer;
|
||||
private HttpKernelInterface $kernel;
|
||||
private string|object|array|null $controller;
|
||||
private ErrorRendererInterface $errorRenderer;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, $controller, ErrorRendererInterface $errorRenderer)
|
||||
public function __construct(HttpKernelInterface $kernel, string|object|array|null $controller, ErrorRendererInterface $errorRenderer)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->controller = $controller;
|
||||
|
@@ -19,8 +19,8 @@ use Symfony\Component\Stopwatch\Stopwatch;
|
||||
*/
|
||||
class TraceableArgumentResolver implements ArgumentResolverInterface
|
||||
{
|
||||
private $resolver;
|
||||
private $stopwatch;
|
||||
private ArgumentResolverInterface $resolver;
|
||||
private Stopwatch $stopwatch;
|
||||
|
||||
public function __construct(ArgumentResolverInterface $resolver, Stopwatch $stopwatch)
|
||||
{
|
||||
@@ -29,13 +29,14 @@ class TraceableArgumentResolver implements ArgumentResolverInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param \ReflectionFunctionAbstract|null $reflector
|
||||
*/
|
||||
public function getArguments(Request $request, callable $controller)
|
||||
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');
|
||||
|
||||
$ret = $this->resolver->getArguments($request, $controller);
|
||||
$ret = $this->resolver->getArguments($request, $controller, $reflector);
|
||||
|
||||
$e->stop();
|
||||
|
||||
|
@@ -19,8 +19,8 @@ use Symfony\Component\Stopwatch\Stopwatch;
|
||||
*/
|
||||
class TraceableControllerResolver implements ControllerResolverInterface
|
||||
{
|
||||
private $resolver;
|
||||
private $stopwatch;
|
||||
private ControllerResolverInterface $resolver;
|
||||
private Stopwatch $stopwatch;
|
||||
|
||||
public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch)
|
||||
{
|
||||
@@ -28,10 +28,7 @@ class TraceableControllerResolver implements ControllerResolverInterface
|
||||
$this->stopwatch = $stopwatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getController(Request $request)
|
||||
public function getController(Request $request): callable|false
|
||||
{
|
||||
$e = $this->stopwatch->start('controller.get_callable');
|
||||
|
||||
|
28
vendor/symfony/http-kernel/Controller/ValueResolverInterface.php
vendored
Normal file
28
vendor/symfony/http-kernel/Controller/ValueResolverInterface.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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;
|
||||
}
|
@@ -11,8 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\ControllerMetadata;
|
||||
|
||||
use Symfony\Component\HttpKernel\Attribute\ArgumentInterface;
|
||||
|
||||
/**
|
||||
* Responsible for storing metadata of an argument.
|
||||
*
|
||||
@@ -22,18 +20,18 @@ class ArgumentMetadata
|
||||
{
|
||||
public const IS_INSTANCEOF = 2;
|
||||
|
||||
private $name;
|
||||
private $type;
|
||||
private $isVariadic;
|
||||
private $hasDefaultValue;
|
||||
private $defaultValue;
|
||||
private $isNullable;
|
||||
private $attributes;
|
||||
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, $defaultValue, bool $isNullable = false, $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;
|
||||
@@ -41,21 +39,13 @@ class ArgumentMetadata
|
||||
$this->hasDefaultValue = $hasDefaultValue;
|
||||
$this->defaultValue = $defaultValue;
|
||||
$this->isNullable = $isNullable || null === $type || ($hasDefaultValue && null === $defaultValue);
|
||||
|
||||
if (null === $attributes || $attributes instanceof ArgumentInterface) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'The "%s" constructor expects an array of PHP attributes as last argument, %s given.', __CLASS__, get_debug_type($attributes));
|
||||
$attributes = $attributes ? [$attributes] : [];
|
||||
}
|
||||
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name as given in PHP, $foo would yield "foo".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
@@ -64,20 +54,16 @@ class ArgumentMetadata
|
||||
* Returns the type of the argument.
|
||||
*
|
||||
* The type is the PHP class in 5.5+ and additionally the basic type in PHP 7.0+.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getType()
|
||||
public function getType(): ?string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the argument is defined as "...$variadic".
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVariadic()
|
||||
public function isVariadic(): bool
|
||||
{
|
||||
return $this->isVariadic;
|
||||
}
|
||||
@@ -86,20 +72,16 @@ class ArgumentMetadata
|
||||
* Returns whether the argument has a default value.
|
||||
*
|
||||
* Implies whether an argument is optional.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasDefaultValue()
|
||||
public function hasDefaultValue(): bool
|
||||
{
|
||||
return $this->hasDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the argument accepts null values.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNullable()
|
||||
public function isNullable(): bool
|
||||
{
|
||||
return $this->isNullable;
|
||||
}
|
||||
@@ -108,10 +90,8 @@ class ArgumentMetadata
|
||||
* Returns the default value of the argument.
|
||||
*
|
||||
* @throws \LogicException if no default value is present; {@see self::hasDefaultValue()}
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefaultValue()
|
||||
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__));
|
||||
@@ -121,21 +101,10 @@ class ArgumentMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute (if any) that was set on the argument.
|
||||
*/
|
||||
public function getAttribute(): ?ArgumentInterface
|
||||
{
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Method "%s()" is deprecated, use "getAttributes()" instead.', __METHOD__);
|
||||
|
||||
if (!$this->attributes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->attributes[0] instanceof ArgumentInterface ? $this->attributes[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object[]
|
||||
* @param class-string $name
|
||||
* @param self::IS_INSTANCEOF|0 $flags
|
||||
*
|
||||
* @return array<object>
|
||||
*/
|
||||
public function getAttributes(string $name = null, int $flags = 0): array
|
||||
{
|
||||
@@ -143,6 +112,19 @@ class ArgumentMetadata
|
||||
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) {
|
||||
@@ -152,7 +134,7 @@ class ArgumentMetadata
|
||||
}
|
||||
} else {
|
||||
foreach ($this->attributes as $attribute) {
|
||||
if (\get_class($attribute) === $name) {
|
||||
if ($attribute::class === $name) {
|
||||
$attributes[] = $attribute;
|
||||
}
|
||||
}
|
||||
|
@@ -18,37 +18,20 @@ namespace Symfony\Component\HttpKernel\ControllerMetadata;
|
||||
*/
|
||||
final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createArgumentMetadata($controller): array
|
||||
public function createArgumentMetadata(string|object|array $controller, \ReflectionFunctionAbstract $reflector = null): array
|
||||
{
|
||||
$arguments = [];
|
||||
$reflector ??= new \ReflectionFunction($controller(...));
|
||||
|
||||
if (\is_array($controller)) {
|
||||
$reflection = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
$class = $reflection->class;
|
||||
} elseif (\is_object($controller) && !$controller instanceof \Closure) {
|
||||
$reflection = new \ReflectionMethod($controller, '__invoke');
|
||||
$class = $reflection->class;
|
||||
} else {
|
||||
$reflection = new \ReflectionFunction($controller);
|
||||
if ($class = str_contains($reflection->name, '{closure}') ? null : (\PHP_VERSION_ID >= 80111 ? $reflection->getClosureCalledClass() : $reflection->getClosureScopeClass())) {
|
||||
$class = $class->name;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($reflection->getParameters() as $param) {
|
||||
foreach ($reflector->getParameters() as $param) {
|
||||
$attributes = [];
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
foreach ($param->getAttributes() as $reflectionAttribute) {
|
||||
if (class_exists($reflectionAttribute->getName())) {
|
||||
$attributes[] = $reflectionAttribute->newInstance();
|
||||
}
|
||||
foreach ($param->getAttributes() as $reflectionAttribute) {
|
||||
if (class_exists($reflectionAttribute->getName())) {
|
||||
$attributes[] = $reflectionAttribute->newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
$arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param, $class), $param->isVariadic(), $param->isDefaultValueAvailable(), $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, $param->allowsNull(), $attributes);
|
||||
$arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $param->isVariadic(), $param->isDefaultValueAvailable(), $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, $param->allowsNull(), $attributes);
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
@@ -57,22 +40,17 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface
|
||||
/**
|
||||
* Returns an associated type to the given parameter if available.
|
||||
*/
|
||||
private function getType(\ReflectionParameter $parameter, ?string $class): ?string
|
||||
private function getType(\ReflectionParameter $parameter): ?string
|
||||
{
|
||||
if (!$type = $parameter->getType()) {
|
||||
return null;
|
||||
}
|
||||
$name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
|
||||
|
||||
if (null !== $class) {
|
||||
switch (strtolower($name)) {
|
||||
case 'self':
|
||||
return $class;
|
||||
case 'parent':
|
||||
return get_parent_class($class) ?: null;
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
return match (strtolower($name)) {
|
||||
'self' => $parameter->getDeclaringClass()?->name,
|
||||
'parent' => get_parent_class($parameter->getDeclaringClass()?->name ?? '') ?: null,
|
||||
default => $name,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -19,9 +19,9 @@ namespace Symfony\Component\HttpKernel\ControllerMetadata;
|
||||
interface ArgumentMetadataFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string|object|array $controller The controller to resolve the arguments for
|
||||
* @param \ReflectionFunctionAbstract|null $reflector
|
||||
*
|
||||
* @return ArgumentMetadata[]
|
||||
*/
|
||||
public function createArgumentMetadata($controller);
|
||||
public function createArgumentMetadata(string|object|array $controller/* , \ReflectionFunctionAbstract $reflector = null */): array;
|
||||
}
|
||||
|
@@ -24,26 +24,24 @@ use Symfony\Component\VarDumper\Caster\ClassStub;
|
||||
*/
|
||||
class ConfigDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
/**
|
||||
* @var KernelInterface
|
||||
*/
|
||||
private $kernel;
|
||||
private KernelInterface $kernel;
|
||||
|
||||
/**
|
||||
* Sets the Kernel associated with this Request.
|
||||
*/
|
||||
public function setKernel(KernelInterface $kernel = null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
$eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE);
|
||||
$eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE);
|
||||
$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'),
|
||||
@@ -60,15 +58,15 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
'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_BOOLEAN),
|
||||
'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN),
|
||||
'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(\get_class($bundle));
|
||||
$this->data['bundles'][$name] = new ClassStub($bundle::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,9 +76,6 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = [];
|
||||
@@ -108,9 +103,8 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the current Symfony release.
|
||||
*
|
||||
* @return string One of: unknown, dev, stable, eom, eol
|
||||
* Returns the state of the current Symfony release
|
||||
* as one of: unknown, dev, stable, eom, eol.
|
||||
*/
|
||||
public function getSymfonyState(): string
|
||||
{
|
||||
@@ -126,9 +120,6 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return $this->data['symfony_minor_version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the current Symfony version is a Long-Term Support one.
|
||||
*/
|
||||
public function isSymfonyLts(): bool
|
||||
{
|
||||
return $this->data['symfony_lts'];
|
||||
@@ -168,9 +159,6 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return $this->data['php_version_extra'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int The PHP architecture as number of bits (e.g. 32 or 64)
|
||||
*/
|
||||
public function getPhpArchitecture(): int
|
||||
{
|
||||
return $this->data['php_architecture'];
|
||||
@@ -199,19 +187,27 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
*
|
||||
* @return bool|string true if debug is enabled, false otherwise or a string if no kernel was set
|
||||
*/
|
||||
public function isDebug()
|
||||
public function isDebug(): bool|string
|
||||
{
|
||||
return $this->data['debug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the XDebug is enabled.
|
||||
* Returns true if the Xdebug is enabled.
|
||||
*/
|
||||
public function hasXDebug(): bool
|
||||
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.
|
||||
*/
|
||||
@@ -241,24 +237,16 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return $this->data['sapi_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'config';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to retrieve information about the current Symfony version.
|
||||
*
|
||||
* @return string One of: dev, stable, eom, eol
|
||||
*/
|
||||
private function determineSymfonyState(): string
|
||||
{
|
||||
$now = new \DateTime();
|
||||
$eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE)->modify('last day of this month');
|
||||
$eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE)->modify('last day of this month');
|
||||
$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';
|
||||
|
@@ -33,27 +33,20 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
*/
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* @var ClonerInterface
|
||||
*/
|
||||
private $cloner;
|
||||
private ClonerInterface $cloner;
|
||||
|
||||
/**
|
||||
* Converts the variable into a serializable Data instance.
|
||||
*
|
||||
* This array can be displayed in the template using
|
||||
* the VarDumper component.
|
||||
*
|
||||
* @param mixed $var
|
||||
*
|
||||
* @return Data
|
||||
*/
|
||||
protected function cloneVar($var)
|
||||
protected function cloneVar(mixed $var): Data
|
||||
{
|
||||
if ($var instanceof Data) {
|
||||
return $var;
|
||||
}
|
||||
if (null === $this->cloner) {
|
||||
if (!isset($this->cloner)) {
|
||||
$this->cloner = new VarCloner();
|
||||
$this->cloner->setMaxItems(-1);
|
||||
$this->cloner->addCasters($this->getCasters());
|
||||
@@ -84,10 +77,7 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
return $casters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
public function __sleep(): array
|
||||
{
|
||||
return ['data'];
|
||||
}
|
||||
@@ -106,7 +96,7 @@ abstract class DataCollector implements DataCollectorInterface
|
||||
/**
|
||||
* @internal to prevent implementing \Serializable
|
||||
*/
|
||||
final protected function unserialize($data)
|
||||
final protected function unserialize(string $data)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@@ -31,23 +31,19 @@ use Symfony\Component\VarDumper\Server\Connection;
|
||||
*/
|
||||
class DumpDataCollector extends DataCollector implements DataDumperInterface
|
||||
{
|
||||
private $stopwatch;
|
||||
private $fileLinkFormat;
|
||||
private $dataCount = 0;
|
||||
private $isCollected = true;
|
||||
private $clonesCount = 0;
|
||||
private $clonesIndex = 0;
|
||||
private $rootRefs;
|
||||
private $charset;
|
||||
private $requestStack;
|
||||
private $dumper;
|
||||
private $sourceContextProvider;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @param string|FileLinkFormatter|null $fileLinkFormat
|
||||
* @param DataDumperInterface|Connection|null $dumper
|
||||
*/
|
||||
public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, string $charset = null, RequestStack $requestStack = null, $dumper = null)
|
||||
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;
|
||||
@@ -74,9 +70,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
|
||||
|
||||
public function dump(Data $data)
|
||||
{
|
||||
if ($this->stopwatch) {
|
||||
$this->stopwatch->start('dump');
|
||||
}
|
||||
$this->stopwatch?->start('dump');
|
||||
|
||||
['name' => $name, 'file' => $file, 'line' => $line, 'file_excerpt' => $fileExcerpt] = $this->sourceContextProvider->getContext();
|
||||
|
||||
@@ -96,9 +90,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
|
||||
$this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt');
|
||||
++$this->dataCount;
|
||||
|
||||
if ($this->stopwatch) {
|
||||
$this->stopwatch->stop('dump');
|
||||
}
|
||||
$this->stopwatch?->stop('dump');
|
||||
}
|
||||
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
@@ -138,9 +130,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
|
||||
|
||||
public function reset()
|
||||
{
|
||||
if ($this->stopwatch) {
|
||||
$this->stopwatch->reset();
|
||||
}
|
||||
$this->stopwatch?->reset();
|
||||
$this->data = [];
|
||||
$this->dataCount = 0;
|
||||
$this->isCollected = true;
|
||||
|
@@ -22,13 +22,15 @@ use Symfony\Contracts\Service\ResetInterface;
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @see TraceableEventDispatcher
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class EventDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
protected $dispatcher;
|
||||
private $requestStack;
|
||||
private $currentRequest;
|
||||
private ?EventDispatcherInterface $dispatcher;
|
||||
private ?RequestStack $requestStack;
|
||||
private ?Request $currentRequest = null;
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher = null, RequestStack $requestStack = null)
|
||||
{
|
||||
@@ -36,9 +38,6 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
||||
$this->requestStack = $requestStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
$this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null;
|
||||
@@ -70,8 +69,6 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $listeners An array of called listeners
|
||||
*
|
||||
* @see TraceableEventDispatcher
|
||||
*/
|
||||
public function setCalledListeners(array $listeners)
|
||||
@@ -81,10 +78,8 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
||||
|
||||
/**
|
||||
* @see TraceableEventDispatcher
|
||||
*
|
||||
* @return array|Data
|
||||
*/
|
||||
public function getCalledListeners()
|
||||
public function getCalledListeners(): array|Data
|
||||
{
|
||||
return $this->data['called_listeners'];
|
||||
}
|
||||
@@ -99,10 +94,8 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
||||
|
||||
/**
|
||||
* @see TraceableEventDispatcher
|
||||
*
|
||||
* @return array|Data
|
||||
*/
|
||||
public function getNotCalledListeners()
|
||||
public function getNotCalledListeners(): array|Data
|
||||
{
|
||||
return $this->data['not_called_listeners'];
|
||||
}
|
||||
@@ -119,17 +112,12 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
||||
|
||||
/**
|
||||
* @see TraceableEventDispatcher
|
||||
*
|
||||
* @return array|Data
|
||||
*/
|
||||
public function getOrphanedEvents()
|
||||
public function getOrphanedEvents(): array|Data
|
||||
{
|
||||
return $this->data['orphaned_events'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'events';
|
||||
|
@@ -22,9 +22,6 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
*/
|
||||
class ExceptionDataCollector extends DataCollector
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
if (null !== $exception) {
|
||||
@@ -34,9 +31,6 @@ class ExceptionDataCollector extends DataCollector
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = [];
|
||||
@@ -47,10 +41,7 @@ class ExceptionDataCollector extends DataCollector
|
||||
return isset($this->data['exception']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Exception|FlattenException
|
||||
*/
|
||||
public function getException()
|
||||
public function getException(): \Exception|FlattenException
|
||||
{
|
||||
return $this->data['exception'];
|
||||
}
|
||||
@@ -75,9 +66,6 @@ class ExceptionDataCollector extends DataCollector
|
||||
return $this->data['exception']->getTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'exception';
|
||||
|
@@ -24,15 +24,15 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||
*/
|
||||
class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
private $logger;
|
||||
private $containerPathPrefix;
|
||||
private $currentRequest;
|
||||
private $requestStack;
|
||||
private $processedLogs;
|
||||
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 (null !== $logger && $logger instanceof DebugLoggerInterface) {
|
||||
if ($logger instanceof DebugLoggerInterface) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
@@ -40,31 +40,22 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
$this->requestStack = $requestStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
$this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->logger instanceof DebugLoggerInterface) {
|
||||
if (isset($this->logger)) {
|
||||
$this->logger->clear();
|
||||
}
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lateCollect()
|
||||
{
|
||||
if (null !== $this->logger) {
|
||||
if (isset($this->logger)) {
|
||||
$containerDeprecationLogs = $this->getContainerDeprecationLogs();
|
||||
$this->data = $this->computeErrorsCount($containerDeprecationLogs);
|
||||
// get compiler logs later (only when they are needed) to improve performance
|
||||
@@ -187,9 +178,6 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return $this->cloneVar($this->getContainerCompilerLogs($this->data['compiler_logs_filepath'] ?? null));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'logger';
|
||||
|
@@ -26,17 +26,11 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
$this->updateMemoryUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = [
|
||||
@@ -45,9 +39,6 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lateCollect()
|
||||
{
|
||||
$this->updateMemoryUsage();
|
||||
@@ -58,10 +49,7 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
return $this->data['memory'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|float
|
||||
*/
|
||||
public function getMemoryLimit()
|
||||
public function getMemoryLimit(): int|float
|
||||
{
|
||||
return $this->data['memory_limit'];
|
||||
}
|
||||
@@ -71,18 +59,12 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
$this->data['memory'] = memory_get_peak_usage(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'memory';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|float
|
||||
*/
|
||||
private function convertToBytes(string $memoryLimit)
|
||||
private function convertToBytes(string $memoryLimit): int|float
|
||||
{
|
||||
if ('-1' === $memoryLimit) {
|
||||
return -1;
|
||||
@@ -100,11 +82,11 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
|
||||
switch (substr($memoryLimit, -1)) {
|
||||
case 't': $max *= 1024;
|
||||
// no break
|
||||
// no break
|
||||
case 'g': $max *= 1024;
|
||||
// no break
|
||||
// no break
|
||||
case 'm': $max *= 1024;
|
||||
// no break
|
||||
// no break
|
||||
case 'k': $max *= 1024;
|
||||
}
|
||||
|
||||
|
@@ -34,9 +34,9 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
/**
|
||||
* @var \SplObjectStorage<Request, callable>
|
||||
*/
|
||||
private $controllers;
|
||||
private $sessionUsages = [];
|
||||
private $requestStack;
|
||||
private \SplObjectStorage $controllers;
|
||||
private array $sessionUsages = [];
|
||||
private ?RequestStack $requestStack;
|
||||
|
||||
public function __construct(RequestStack $requestStack = null)
|
||||
{
|
||||
@@ -44,9 +44,6 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
$this->requestStack = $requestStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
// attributes are serialized and as they can be anything, they need to be converted to strings.
|
||||
@@ -110,7 +107,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
'session_metadata' => $sessionMetadata,
|
||||
'session_attributes' => $sessionAttributes,
|
||||
'session_usages' => array_values($this->sessionUsages),
|
||||
'stateless_check' => $this->requestStack && ($mainRequest = $this->requestStack->getMainRequest()) && $mainRequest->attributes->get('_stateless', false),
|
||||
'stateless_check' => $this->requestStack?->getMainRequest()?->attributes->get('_stateless') ?? false,
|
||||
'flashes' => $flashes,
|
||||
'path_info' => $request->getPathInfo(),
|
||||
'controller' => 'n/a',
|
||||
@@ -346,7 +343,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
* @return array|string|Data The controller as a string or array of data
|
||||
* with keys 'class', 'method', 'file' and 'line'
|
||||
*/
|
||||
public function getController()
|
||||
public function getController(): array|string|Data
|
||||
{
|
||||
return $this->data['controller'];
|
||||
}
|
||||
@@ -357,7 +354,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
* @return array|Data|false A legacy array of data from the previous redirection response
|
||||
* or false otherwise
|
||||
*/
|
||||
public function getRedirect()
|
||||
public function getRedirect(): array|Data|false
|
||||
{
|
||||
return $this->data['redirect'] ?? false;
|
||||
}
|
||||
@@ -391,9 +388,6 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'request';
|
||||
@@ -431,11 +425,9 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|object|array|null $controller The controller to parse
|
||||
*
|
||||
* @return array|string An array of controller data or a simple string
|
||||
*/
|
||||
private function parseController($controller)
|
||||
private function parseController(array|object|string|null $controller): array|string
|
||||
{
|
||||
if (\is_string($controller) && str_contains($controller, '::')) {
|
||||
$controller = explode('::', $controller);
|
||||
@@ -451,7 +443,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
'file' => $r->getFileName(),
|
||||
'line' => $r->getStartLine(),
|
||||
];
|
||||
} catch (\ReflectionException $e) {
|
||||
} catch (\ReflectionException) {
|
||||
if (\is_callable($controller)) {
|
||||
// using __call or __callStatic
|
||||
return [
|
||||
|
@@ -32,8 +32,6 @@ class RouterDataCollector extends DataCollector
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
@@ -61,7 +59,7 @@ class RouterDataCollector extends DataCollector
|
||||
];
|
||||
}
|
||||
|
||||
protected function guessRoute(Request $request, $controller)
|
||||
protected function guessRoute(Request $request, string|object|array $controller)
|
||||
{
|
||||
return 'n/a';
|
||||
}
|
||||
@@ -77,31 +75,22 @@ class RouterDataCollector extends DataCollector
|
||||
/**
|
||||
* @return bool Whether this request will result in a redirect
|
||||
*/
|
||||
public function getRedirect()
|
||||
public function getRedirect(): bool
|
||||
{
|
||||
return $this->data['redirect'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTargetUrl()
|
||||
public function getTargetUrl(): ?string
|
||||
{
|
||||
return $this->data['url'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTargetRoute()
|
||||
public function getTargetRoute(): ?string
|
||||
{
|
||||
return $this->data['route'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
public function getName(): string
|
||||
{
|
||||
return 'router';
|
||||
}
|
||||
|
@@ -24,8 +24,8 @@ use Symfony\Component\Stopwatch\StopwatchEvent;
|
||||
*/
|
||||
class TimeDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
private $kernel;
|
||||
private $stopwatch;
|
||||
private ?KernelInterface $kernel;
|
||||
private ?Stopwatch $stopwatch;
|
||||
|
||||
public function __construct(KernelInterface $kernel = null, Stopwatch $stopwatch = null)
|
||||
{
|
||||
@@ -33,9 +33,6 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
||||
$this->stopwatch = $stopwatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Throwable $exception = null)
|
||||
{
|
||||
if (null !== $this->kernel) {
|
||||
@@ -52,21 +49,13 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = [];
|
||||
|
||||
if (null !== $this->stopwatch) {
|
||||
$this->stopwatch->reset();
|
||||
}
|
||||
$this->stopwatch?->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lateCollect()
|
||||
{
|
||||
if (null !== $this->stopwatch && isset($this->data['token'])) {
|
||||
@@ -133,9 +122,6 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
||||
return $this->data['stopwatch_installed'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'time';
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
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;
|
||||
@@ -24,28 +25,19 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
*/
|
||||
class FileLinkFormatter
|
||||
{
|
||||
private const FORMATS = [
|
||||
'textmate' => 'txmt://open?url=file://%f&line=%l',
|
||||
'macvim' => 'mvim://open?url=file://%f&line=%l',
|
||||
'emacs' => 'emacs://open?url=file://%f&line=%l',
|
||||
'sublime' => 'subl://open?url=file://%f&line=%l',
|
||||
'phpstorm' => 'phpstorm://open?file=%f&line=%l',
|
||||
'atom' => 'atom://core/open/file?filename=%f&line=%l',
|
||||
'vscode' => 'vscode://file/%f:%l',
|
||||
];
|
||||
|
||||
private $fileLinkFormat;
|
||||
private $requestStack;
|
||||
private $baseDir;
|
||||
private $urlFormat;
|
||||
private array|false $fileLinkFormat;
|
||||
private ?RequestStack $requestStack = null;
|
||||
private ?string $baseDir = null;
|
||||
private \Closure|string|null $urlFormat;
|
||||
|
||||
/**
|
||||
* @param string|array|null $fileLinkFormat
|
||||
* @param string|\Closure $urlFormat the URL format, or a closure that returns it on-demand
|
||||
* @param string|\Closure $urlFormat the URL format, or a closure that returns it on-demand
|
||||
*/
|
||||
public function __construct($fileLinkFormat = null, RequestStack $requestStack = null, string $baseDir = null, $urlFormat = null)
|
||||
public function __construct(string|array $fileLinkFormat = null, RequestStack $requestStack = null, string $baseDir = null, string|\Closure $urlFormat = null)
|
||||
{
|
||||
if (!\is_array($fileLinkFormat) && $fileLinkFormat = (self::FORMATS[$fileLinkFormat] ?? $fileLinkFormat) ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format')) {
|
||||
$fileLinkFormat ??= $_ENV['SYMFONY_IDE'] ?? $_SERVER['SYMFONY_IDE'] ?? '';
|
||||
|
||||
if (!\is_array($fileLinkFormat) && $fileLinkFormat = (ErrorRendererInterface::IDE_LINK_FORMATS[$fileLinkFormat] ?? $fileLinkFormat) ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: false) {
|
||||
$i = strpos($f = $fileLinkFormat, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
|
||||
$fileLinkFormat = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, \PREG_SPLIT_DELIM_CAPTURE);
|
||||
}
|
||||
@@ -89,12 +81,12 @@ class FileLinkFormatter
|
||||
{
|
||||
try {
|
||||
return $router->generate($routeName).$queryString;
|
||||
} catch (\Throwable $e) {
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function getFileLinkFormat()
|
||||
private function getFileLinkFormat(): array|false
|
||||
{
|
||||
if ($this->fileLinkFormat) {
|
||||
return $this->fileLinkFormat;
|
||||
@@ -111,6 +103,6 @@ class FileLinkFormatter
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -23,9 +23,6 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
*/
|
||||
class TraceableEventDispatcher extends BaseTraceableEventDispatcher
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function beforeDispatch(string $eventName, object $event)
|
||||
{
|
||||
switch ($eventName) {
|
||||
@@ -52,15 +49,12 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
|
||||
// which must be caught.
|
||||
try {
|
||||
$this->stopwatch->openSection($sectionId);
|
||||
} catch (\LogicException $e) {
|
||||
} catch (\LogicException) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function afterDispatch(string $eventName, object $event)
|
||||
{
|
||||
switch ($eventName) {
|
||||
@@ -83,7 +77,7 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
|
||||
}
|
||||
try {
|
||||
$this->stopwatch->stopSection($sectionId);
|
||||
} catch (\LogicException $e) {
|
||||
} catch (\LogicException) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\ErrorHandler\DebugClassLoader;
|
||||
@@ -25,16 +24,13 @@ use Symfony\Component\HttpKernel\Kernel;
|
||||
*/
|
||||
class AddAnnotatedClassesToCachePass implements CompilerPassInterface
|
||||
{
|
||||
private $kernel;
|
||||
private Kernel $kernel;
|
||||
|
||||
public function __construct(Kernel $kernel)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$annotatedClasses = [];
|
||||
@@ -93,7 +89,7 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($function[0] instanceof DebugClassLoader || $function[0] instanceof LegacyDebugClassLoader) {
|
||||
if ($function[0] instanceof DebugClassLoader) {
|
||||
$function = $function[0]->getClassLoader();
|
||||
}
|
||||
|
||||
@@ -117,7 +113,7 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface
|
||||
$regex = strtr($regex, ['\\*\\*' => '.*?', '\\*' => '[^\\\\]*?']);
|
||||
|
||||
// If this class does not end by a slash, anchor the end
|
||||
if ('\\' !== substr($regex, -1)) {
|
||||
if (!str_ends_with($regex, '\\')) {
|
||||
$regex .= '$';
|
||||
}
|
||||
|
||||
|
@@ -27,9 +27,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
*/
|
||||
abstract class ConfigurableExtension extends Extension
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
$this->loadInternal($this->processConfiguration($this->getConfiguration($configs, $container), $configs), $container);
|
||||
|
@@ -28,40 +28,25 @@ class ControllerArgumentValueResolverPass implements CompilerPassInterface
|
||||
{
|
||||
use PriorityTaggedServiceTrait;
|
||||
|
||||
private $argumentResolverService;
|
||||
private $argumentValueResolverTag;
|
||||
private $traceableResolverStopwatch;
|
||||
|
||||
public function __construct(string $argumentResolverService = 'argument_resolver', string $argumentValueResolverTag = 'controller.argument_value_resolver', string $traceableResolverStopwatch = 'debug.stopwatch')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->argumentResolverService = $argumentResolverService;
|
||||
$this->argumentValueResolverTag = $argumentValueResolverTag;
|
||||
$this->traceableResolverStopwatch = $traceableResolverStopwatch;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->argumentResolverService)) {
|
||||
if (!$container->hasDefinition('argument_resolver')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resolvers = $this->findAndSortTaggedServices($this->argumentValueResolverTag, $container);
|
||||
$resolvers = $this->findAndSortTaggedServices('controller.argument_value_resolver', $container);
|
||||
|
||||
if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has($this->traceableResolverStopwatch)) {
|
||||
if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has('debug.stopwatch')) {
|
||||
foreach ($resolvers as $resolverReference) {
|
||||
$id = (string) $resolverReference;
|
||||
$container->register("debug.$id", TraceableValueResolver::class)
|
||||
->setDecoratedService($id)
|
||||
->setArguments([new Reference("debug.$id.inner"), new Reference($this->traceableResolverStopwatch)]);
|
||||
->setArguments([new Reference("debug.$id.inner"), new Reference('debug.stopwatch')]);
|
||||
}
|
||||
}
|
||||
|
||||
$container
|
||||
->getDefinition($this->argumentResolverService)
|
||||
->getDefinition('argument_resolver')
|
||||
->replaceArgument(1, new IteratorArgument($resolvers))
|
||||
;
|
||||
}
|
||||
|
@@ -20,14 +20,12 @@ use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension;
|
||||
*/
|
||||
abstract class Extension extends BaseExtension
|
||||
{
|
||||
private $annotatedClasses = [];
|
||||
private array $annotatedClasses = [];
|
||||
|
||||
/**
|
||||
* Gets the annotated classes to cache.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAnnotatedClassesToCompile()
|
||||
public function getAnnotatedClassesToCompile(): array
|
||||
{
|
||||
return $this->annotatedClasses;
|
||||
}
|
||||
|
@@ -25,28 +25,15 @@ use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface;
|
||||
*/
|
||||
class FragmentRendererPass implements CompilerPassInterface
|
||||
{
|
||||
private $handlerService;
|
||||
private $rendererTag;
|
||||
|
||||
public function __construct(string $handlerService = 'fragment.handler', string $rendererTag = 'kernel.fragment_renderer')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->handlerService = $handlerService;
|
||||
$this->rendererTag = $rendererTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->handlerService)) {
|
||||
if (!$container->hasDefinition('fragment.handler')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition($this->handlerService);
|
||||
$definition = $container->getDefinition('fragment.handler');
|
||||
$renderers = [];
|
||||
foreach ($container->findTaggedServiceIds($this->rendererTag, true) as $id => $tags) {
|
||||
foreach ($container->findTaggedServiceIds('kernel.fragment_renderer', true) as $id => $tags) {
|
||||
$def = $container->getDefinition($id);
|
||||
$class = $container->getParameterBag()->resolveValue($def->getClass());
|
||||
|
||||
|
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -22,12 +23,12 @@ use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
|
||||
*/
|
||||
class LazyLoadingFragmentHandler extends FragmentHandler
|
||||
{
|
||||
private $container;
|
||||
private ContainerInterface $container;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $initialized = [];
|
||||
private array $initialized = [];
|
||||
|
||||
public function __construct(ContainerInterface $container, RequestStack $requestStack, bool $debug = false)
|
||||
{
|
||||
@@ -36,10 +37,7 @@ class LazyLoadingFragmentHandler extends FragmentHandler
|
||||
parent::__construct($requestStack, [], $debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render($uri, string $renderer = 'inline', array $options = [])
|
||||
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));
|
||||
|
@@ -14,6 +14,8 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -23,9 +25,6 @@ use Symfony\Component\HttpKernel\Log\Logger;
|
||||
*/
|
||||
class LoggerPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$container->setAlias(LoggerInterface::class, 'logger')
|
||||
@@ -36,6 +35,7 @@ class LoggerPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
$container->register('logger', Logger::class)
|
||||
->setArguments([null, null, null, new Reference(RequestStack::class)])
|
||||
->setPublic(false);
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
*/
|
||||
class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass
|
||||
{
|
||||
private $extensions;
|
||||
private array $extensions;
|
||||
|
||||
/**
|
||||
* @param string[] $extensions
|
||||
|
@@ -11,21 +11,20 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
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\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
|
||||
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.
|
||||
@@ -34,26 +33,9 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
*/
|
||||
class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
{
|
||||
private $resolverServiceId;
|
||||
private $controllerTag;
|
||||
private $controllerLocator;
|
||||
private $notTaggedControllerResolverServiceId;
|
||||
|
||||
public function __construct(string $resolverServiceId = 'argument_resolver.service', string $controllerTag = 'controller.service_arguments', string $controllerLocator = 'argument_resolver.controller_locator', string $notTaggedControllerResolverServiceId = 'argument_resolver.not_tagged_controller')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->resolverServiceId = $resolverServiceId;
|
||||
$this->controllerTag = $controllerTag;
|
||||
$this->controllerLocator = $controllerLocator;
|
||||
$this->notTaggedControllerResolverServiceId = $notTaggedControllerResolverServiceId;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (false === $container->hasDefinition($this->resolverServiceId) && false === $container->hasDefinition($this->notTaggedControllerResolverServiceId)) {
|
||||
if (!$container->hasDefinition('argument_resolver.service') && !$container->hasDefinition('argument_resolver.not_tagged_controller')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,7 +49,9 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->controllerTag, true) as $id => $tags) {
|
||||
$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();
|
||||
@@ -85,13 +69,12 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
if (!$r = $container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
$isContainerAware = $r->implementsInterface(ContainerAwareInterface::class) || is_subclass_of($class, AbstractController::class);
|
||||
|
||||
// get regular public methods
|
||||
$methods = [];
|
||||
$arguments = [];
|
||||
foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $r) {
|
||||
if ('setContainer' === $r->name && $isContainerAware) {
|
||||
if ('setContainer' === $r->name) {
|
||||
continue;
|
||||
}
|
||||
if (!$r->isConstructor() && !$r->isDestructor() && !$r->isAbstract()) {
|
||||
@@ -107,11 +90,11 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
}
|
||||
foreach (['action', 'argument', 'id'] as $k) {
|
||||
if (!isset($attributes[$k][0])) {
|
||||
throw new InvalidArgumentException(sprintf('Missing "%s" attribute on tag "%s" %s for service "%s".', $k, $this->controllerTag, json_encode($attributes, \JSON_UNESCAPED_UNICODE), $id));
|
||||
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 "%s" for service "%s": no public "%s()" method found on class "%s".', $this->controllerTag, $id, $attributes['action'], $class));
|
||||
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;
|
||||
@@ -127,7 +110,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid "%s" tag for service "%s": method "%s()" has no "%s" argument on class "%s".', $this->controllerTag, $id, $r->name, $attributes['argument'], $class));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,15 +121,16 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
$args = [];
|
||||
foreach ($parameters as $p) {
|
||||
/** @var \ReflectionParameter $p */
|
||||
$type = ltrim($target = (string) ProxyHelper::getTypeHint($r, $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 "%s" tag must have non-empty "id" attributes for service "%s".', $this->controllerTag, $id));
|
||||
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;
|
||||
}
|
||||
@@ -156,17 +140,10 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
[$bindingValue, $bindingId, , $bindingType, $bindingFile] = $binding->getValues();
|
||||
$binding->setValues([$bindingValue, $bindingId, true, $bindingType, $bindingFile]);
|
||||
|
||||
if (!$bindingValue instanceof Reference) {
|
||||
$args[$p->name] = new Reference('.value.'.$container->hash($bindingValue));
|
||||
$container->register((string) $args[$p->name], 'mixed')
|
||||
->setFactory('current')
|
||||
->addArgument([$bindingValue]);
|
||||
} else {
|
||||
$args[$p->name] = $bindingValue;
|
||||
}
|
||||
$args[$p->name] = $bindingValue;
|
||||
|
||||
continue;
|
||||
} elseif (!$type || !$autowire || '\\' !== $target[0]) {
|
||||
} elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class)) && (!$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
|
||||
@@ -179,6 +156,21 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($autowireAttributes) {
|
||||
$value = $autowireAttributes[0]->newInstance()->value;
|
||||
|
||||
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);
|
||||
|
||||
@@ -192,7 +184,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
|
||||
$args[$p->name] = new Reference($erroredId, ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE);
|
||||
} else {
|
||||
$target = ltrim($target, '\\');
|
||||
$target = preg_replace('/(^|[(|&])\\\\/', '\1', $target);
|
||||
$args[$p->name] = $type ? new TypedReference($target, $type, $invalidBehavior, Target::parseName($p)) : new Reference($target, $invalidBehavior);
|
||||
}
|
||||
}
|
||||
@@ -209,16 +201,16 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
|
||||
$controllerLocatorRef = ServiceLocatorTagPass::register($container, $controllers);
|
||||
|
||||
if ($container->hasDefinition($this->resolverServiceId)) {
|
||||
$container->getDefinition($this->resolverServiceId)
|
||||
if ($container->hasDefinition('argument_resolver.service')) {
|
||||
$container->getDefinition('argument_resolver.service')
|
||||
->replaceArgument(0, $controllerLocatorRef);
|
||||
}
|
||||
|
||||
if ($container->hasDefinition($this->notTaggedControllerResolverServiceId)) {
|
||||
$container->getDefinition($this->notTaggedControllerResolverServiceId)
|
||||
if ($container->hasDefinition('argument_resolver.not_tagged_controller')) {
|
||||
$container->getDefinition('argument_resolver.not_tagged_controller')
|
||||
->replaceArgument(0, $controllerLocatorRef);
|
||||
}
|
||||
|
||||
$container->setAlias($this->controllerLocator, (string) $controllerLocatorRef);
|
||||
$container->setAlias('argument_resolver.controller_locator', (string) $controllerLocatorRef);
|
||||
}
|
||||
}
|
||||
|
@@ -23,39 +23,26 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*/
|
||||
class RegisterLocaleAwareServicesPass implements CompilerPassInterface
|
||||
{
|
||||
private $listenerServiceId;
|
||||
private $localeAwareTag;
|
||||
|
||||
public function __construct(string $listenerServiceId = 'locale_aware_listener', string $localeAwareTag = 'kernel.locale_aware')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->listenerServiceId = $listenerServiceId;
|
||||
$this->localeAwareTag = $localeAwareTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->listenerServiceId)) {
|
||||
if (!$container->hasDefinition('locale_aware_listener')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$services = [];
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->localeAwareTag) as $id => $tags) {
|
||||
foreach ($container->findTaggedServiceIds('kernel.locale_aware') as $id => $tags) {
|
||||
$services[] = new Reference($id);
|
||||
}
|
||||
|
||||
if (!$services) {
|
||||
$container->removeDefinition($this->listenerServiceId);
|
||||
$container->removeDefinition('locale_aware_listener');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$container
|
||||
->getDefinition($this->listenerServiceId)
|
||||
->getDefinition('locale_aware_listener')
|
||||
->setArgument(0, new IteratorArgument($services))
|
||||
;
|
||||
}
|
||||
|
@@ -21,20 +21,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
*/
|
||||
class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||
{
|
||||
private $controllerLocator;
|
||||
|
||||
public function __construct(string $controllerLocator = 'argument_resolver.controller_locator')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->controllerLocator = $controllerLocator;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$controllerLocator = $container->findDefinition($this->controllerLocator);
|
||||
$controllerLocator = $container->findDefinition('argument_resolver.controller_locator');
|
||||
$controllers = $controllerLocator->getArgument(0);
|
||||
|
||||
foreach ($controllers as $controller => $argumentRef) {
|
||||
|
@@ -23,20 +23,6 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*/
|
||||
class ResettableServicePass implements CompilerPassInterface
|
||||
{
|
||||
private $tagName;
|
||||
|
||||
public function __construct(string $tagName = 'kernel.reset')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->tagName = $tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->has('services_resetter')) {
|
||||
@@ -45,12 +31,12 @@ class ResettableServicePass implements CompilerPassInterface
|
||||
|
||||
$services = $methods = [];
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->tagName, true) as $id => $tags) {
|
||||
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 "%s" requires the "method" attribute to be set.', $this->tagName));
|
||||
throw new RuntimeException(sprintf('Tag "kernel.reset" requires the "method" attribute to be set on service "%s".', $id));
|
||||
}
|
||||
|
||||
if (!isset($methods[$id])) {
|
||||
|
@@ -23,8 +23,8 @@ use Symfony\Contracts\Service\ResetInterface;
|
||||
*/
|
||||
class ServicesResetter implements ResetInterface
|
||||
{
|
||||
private $resettableServices;
|
||||
private $resetMethods;
|
||||
private \Traversable $resettableServices;
|
||||
private array $resetMethods;
|
||||
|
||||
/**
|
||||
* @param \Traversable<string, object> $resettableServices
|
||||
|
@@ -28,25 +28,34 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
final class ControllerArgumentsEvent extends KernelEvent
|
||||
{
|
||||
private $controller;
|
||||
private $arguments;
|
||||
private ControllerEvent $controllerEvent;
|
||||
private array $arguments;
|
||||
private array $namedArguments;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, callable $controller, array $arguments, Request $request, ?int $requestType)
|
||||
public function __construct(HttpKernelInterface $kernel, callable|ControllerEvent $controller, array $arguments, Request $request, ?int $requestType)
|
||||
{
|
||||
parent::__construct($kernel, $request, $requestType);
|
||||
|
||||
$this->controller = $controller;
|
||||
if (!$controller instanceof ControllerEvent) {
|
||||
$controller = new ControllerEvent($kernel, $controller, $request, $requestType);
|
||||
}
|
||||
|
||||
$this->controllerEvent = $controller;
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function getController(): callable
|
||||
{
|
||||
return $this->controller;
|
||||
return $this->controllerEvent->getController();
|
||||
}
|
||||
|
||||
public function setController(callable $controller)
|
||||
/**
|
||||
* @param array<class-string, list<object>>|null $attributes
|
||||
*/
|
||||
public function setController(callable $controller, array $attributes = null): void
|
||||
{
|
||||
$this->controller = $controller;
|
||||
$this->controllerEvent->setController($controller, $attributes);
|
||||
unset($this->namedArguments);
|
||||
}
|
||||
|
||||
public function getArguments(): array
|
||||
@@ -57,5 +66,38 @@ final class ControllerArgumentsEvent extends KernelEvent
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$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();
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,9 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
final class ControllerEvent extends KernelEvent
|
||||
{
|
||||
private $controller;
|
||||
private string|array|object $controller;
|
||||
private \ReflectionFunctionAbstract $controllerReflector;
|
||||
private array $attributes;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, callable $controller, Request $request, ?int $requestType)
|
||||
{
|
||||
@@ -41,8 +43,65 @@ final class ControllerEvent extends KernelEvent
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
public function setController(callable $controller): void
|
||||
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) && false !== $i = strpos($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;
|
||||
}
|
||||
}
|
||||
|
@@ -29,12 +29,8 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
final class ExceptionEvent extends RequestEvent
|
||||
{
|
||||
private $throwable;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $allowCustomResponseCode = false;
|
||||
private \Throwable $throwable;
|
||||
private bool $allowCustomResponseCode = false;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Throwable $e)
|
||||
{
|
||||
|
30
vendor/symfony/http-kernel/Event/KernelEvent.php
vendored
30
vendor/symfony/http-kernel/Event/KernelEvent.php
vendored
@@ -22,9 +22,9 @@ use Symfony\Contracts\EventDispatcher\Event;
|
||||
*/
|
||||
class KernelEvent extends Event
|
||||
{
|
||||
private $kernel;
|
||||
private $request;
|
||||
private $requestType;
|
||||
private HttpKernelInterface $kernel;
|
||||
private Request $request;
|
||||
private ?int $requestType;
|
||||
|
||||
/**
|
||||
* @param int $requestType The request type the kernel is currently processing; one of
|
||||
@@ -39,20 +39,16 @@ class KernelEvent extends Event
|
||||
|
||||
/**
|
||||
* Returns the kernel in which this event was thrown.
|
||||
*
|
||||
* @return HttpKernelInterface
|
||||
*/
|
||||
public function getKernel()
|
||||
public function getKernel(): HttpKernelInterface
|
||||
{
|
||||
return $this->kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request the kernel is currently processing.
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function getRequest()
|
||||
public function getRequest(): Request
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
@@ -63,7 +59,7 @@ class KernelEvent extends Event
|
||||
* @return int One of HttpKernelInterface::MAIN_REQUEST and
|
||||
* HttpKernelInterface::SUB_REQUEST
|
||||
*/
|
||||
public function getRequestType()
|
||||
public function getRequestType(): int
|
||||
{
|
||||
return $this->requestType;
|
||||
}
|
||||
@@ -75,18 +71,4 @@ class KernelEvent extends Event
|
||||
{
|
||||
return HttpKernelInterface::MAIN_REQUEST === $this->requestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a master request.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since symfony/http-kernel 5.3, use isMainRequest() instead
|
||||
*/
|
||||
public function isMasterRequest()
|
||||
{
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', '"%s()" is deprecated, use "isMainRequest()" instead.', __METHOD__);
|
||||
|
||||
return $this->isMainRequest();
|
||||
}
|
||||
}
|
||||
|
@@ -24,14 +24,12 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
*/
|
||||
class RequestEvent extends KernelEvent
|
||||
{
|
||||
private $response;
|
||||
private ?Response $response = null;
|
||||
|
||||
/**
|
||||
* Returns the response object.
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
public function getResponse()
|
||||
public function getResponse(): ?Response
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
@@ -48,10 +46,8 @@ class RequestEvent extends KernelEvent
|
||||
|
||||
/**
|
||||
* Returns whether a response was set.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasResponse()
|
||||
public function hasResponse(): bool
|
||||
{
|
||||
return null !== $this->response;
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
final class ResponseEvent extends KernelEvent
|
||||
{
|
||||
private $response;
|
||||
private Response $response;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, Response $response)
|
||||
{
|
||||
|
@@ -25,7 +25,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
final class TerminateEvent extends KernelEvent
|
||||
{
|
||||
private $response;
|
||||
private Response $response;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, Response $response)
|
||||
{
|
||||
|
25
vendor/symfony/http-kernel/Event/ViewEvent.php
vendored
25
vendor/symfony/http-kernel/Event/ViewEvent.php
vendored
@@ -25,36 +25,23 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
*/
|
||||
final class ViewEvent extends RequestEvent
|
||||
{
|
||||
/**
|
||||
* The return value of the controller.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $controllerResult;
|
||||
public readonly ?ControllerArgumentsEvent $controllerArgumentsEvent;
|
||||
private mixed $controllerResult;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the return value of the controller.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getControllerResult()
|
||||
public function getControllerResult(): mixed
|
||||
{
|
||||
return $this->controllerResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the return value of the controller.
|
||||
*
|
||||
* @param mixed $controllerResult The controller return value
|
||||
*/
|
||||
public function setControllerResult($controllerResult): void
|
||||
public function setControllerResult(mixed $controllerResult): void
|
||||
{
|
||||
$this->controllerResult = $controllerResult;
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@ 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\FinishRequestEvent;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Exception\UnexpectedSessionUsageException;
|
||||
@@ -44,8 +43,7 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
public const NO_AUTO_CACHE_CONTROL_HEADER = 'Symfony-Session-NoAutoCacheControl';
|
||||
|
||||
protected $container;
|
||||
private $sessionUsageStack = [];
|
||||
private $debug;
|
||||
private bool $debug;
|
||||
|
||||
/**
|
||||
* @var array<string, mixed>
|
||||
@@ -88,9 +86,6 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
return $sess;
|
||||
});
|
||||
}
|
||||
|
||||
$session = $this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : null;
|
||||
$this->sessionUsageStack[] = $session instanceof Session ? $session->getUsageIndex() : 0;
|
||||
}
|
||||
|
||||
public function onKernelResponse(ResponseEvent $event)
|
||||
@@ -103,10 +98,10 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
$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 (!$session = $this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : ($event->getRequest()->hasSession() ? $event->getRequest()->getSession() : null)) {
|
||||
if (!$event->getRequest()->hasSession(true)) {
|
||||
return;
|
||||
}
|
||||
$session = $event->getRequest()->getSession();
|
||||
|
||||
if ($session->isStarted()) {
|
||||
/*
|
||||
@@ -156,7 +151,7 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
$request = $event->getRequest();
|
||||
$requestSessionCookieId = $request->cookies->get($sessionName);
|
||||
|
||||
$isSessionEmpty = $session->isEmpty() && empty($_SESSION); // checking $_SESSION to keep compatibility with native sessions
|
||||
$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
|
||||
@@ -195,7 +190,7 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
}
|
||||
}
|
||||
|
||||
if ($session instanceof Session ? $session->getUsageIndex() === end($this->sessionUsageStack) : !$session->isStarted()) {
|
||||
if ($session instanceof Session ? 0 === $session->getUsageIndex() : !$session->isStarted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -221,24 +216,17 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
}
|
||||
}
|
||||
|
||||
public function onFinishRequest(FinishRequestEvent $event)
|
||||
{
|
||||
if ($event->isMainRequest()) {
|
||||
array_pop($this->sessionUsageStack);
|
||||
}
|
||||
}
|
||||
|
||||
public function onSessionUsage(): void
|
||||
{
|
||||
if (!$this->debug) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->container && $this->container->has('session_collector')) {
|
||||
if ($this->container?->has('session_collector')) {
|
||||
$this->container->get('session_collector')();
|
||||
}
|
||||
|
||||
if (!$requestStack = $this->container && $this->container->has('request_stack') ? $this->container->get('request_stack') : null) {
|
||||
if (!$requestStack = $this->container?->has('request_stack') ? $this->container->get('request_stack') : null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -252,7 +240,7 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$session = $this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : $requestStack->getCurrentRequest()->getSession()) {
|
||||
if (!$session = $requestStack->getCurrentRequest()->getSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -267,9 +255,8 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => ['onKernelRequest', 128],
|
||||
// low priority to come after regular response listeners, but higher than StreamedResponseListener
|
||||
// low priority to come after regular response listeners
|
||||
KernelEvents::RESPONSE => ['onKernelResponse', -1000],
|
||||
KernelEvents::FINISH_REQUEST => ['onFinishRequest'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -289,10 +276,8 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese
|
||||
|
||||
/**
|
||||
* Gets the session object.
|
||||
*
|
||||
* @return SessionInterface|null
|
||||
*/
|
||||
abstract protected function getSession();
|
||||
abstract protected function getSession(): ?SessionInterface;
|
||||
|
||||
private function getSessionOptions(array $sessionOptions): array
|
||||
{
|
||||
|
@@ -1,120 +0,0 @@
|
||||
<?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\Cookie;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
trigger_deprecation('symfony/http-kernel', '5.4', '"%s" is deprecated use "%s" instead.', AbstractTestSessionListener::class, AbstractSessionListener::class);
|
||||
|
||||
/**
|
||||
* TestSessionListener.
|
||||
*
|
||||
* Saves session in test environment.
|
||||
*
|
||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @deprecated since Symfony 5.4, use AbstractSessionListener instead
|
||||
*/
|
||||
abstract class AbstractTestSessionListener implements EventSubscriberInterface
|
||||
{
|
||||
private $sessionId;
|
||||
private $sessionOptions;
|
||||
|
||||
public function __construct(array $sessionOptions = [])
|
||||
{
|
||||
$this->sessionOptions = $sessionOptions;
|
||||
}
|
||||
|
||||
public function onKernelRequest(RequestEvent $event)
|
||||
{
|
||||
if (!$event->isMainRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// bootstrap the session
|
||||
if ($event->getRequest()->hasSession()) {
|
||||
$session = $event->getRequest()->getSession();
|
||||
} elseif (!$session = $this->getSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cookies = $event->getRequest()->cookies;
|
||||
|
||||
if ($cookies->has($session->getName())) {
|
||||
$this->sessionId = $cookies->get($session->getName());
|
||||
$session->setId($this->sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if session was initialized and saves if current request is the main request
|
||||
* Runs on 'kernel.response' in test environment.
|
||||
*/
|
||||
public function onKernelResponse(ResponseEvent $event)
|
||||
{
|
||||
if (!$event->isMainRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
if (!$request->hasSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$session = $request->getSession();
|
||||
if ($wasStarted = $session->isStarted()) {
|
||||
$session->save();
|
||||
}
|
||||
|
||||
if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) {
|
||||
$params = session_get_cookie_params() + ['samesite' => null];
|
||||
foreach ($this->sessionOptions as $k => $v) {
|
||||
if (str_starts_with($k, 'cookie_')) {
|
||||
$params[substr($k, 7)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($event->getResponse()->headers->getCookies() as $cookie) {
|
||||
if ($session->getName() === $cookie->getName() && $params['path'] === $cookie->getPath() && $params['domain'] == $cookie->getDomain()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'], false, $params['samesite'] ?: null));
|
||||
$this->sessionId = $session->getId();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => ['onKernelRequest', 127], // AFTER SessionListener
|
||||
KernelEvents::RESPONSE => ['onKernelResponse', -128],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the session object.
|
||||
*
|
||||
* @return SessionInterface|null
|
||||
*/
|
||||
abstract protected function getSession();
|
||||
}
|
@@ -24,7 +24,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
*/
|
||||
class AddRequestFormatsListener implements EventSubscriberInterface
|
||||
{
|
||||
protected $formats;
|
||||
private array $formats;
|
||||
|
||||
public function __construct(array $formats)
|
||||
{
|
||||
@@ -42,9 +42,6 @@ class AddRequestFormatsListener implements EventSubscriberInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [KernelEvents::REQUEST => ['onKernelRequest', 100]];
|
||||
|
193
vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php
vendored
Normal file
193
vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
<?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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@@ -27,20 +27,20 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
*
|
||||
* @final
|
||||
*
|
||||
* @internal since Symfony 5.3
|
||||
* @internal
|
||||
*/
|
||||
class DebugHandlersListener implements EventSubscriberInterface
|
||||
{
|
||||
private $earlyHandler;
|
||||
private $exceptionHandler;
|
||||
private $logger;
|
||||
private $deprecationLogger;
|
||||
private $levels;
|
||||
private $throwAt;
|
||||
private $scream;
|
||||
private $scope;
|
||||
private $firstCall = true;
|
||||
private $hasTerminatedWithException;
|
||||
private string|object|null $earlyHandler;
|
||||
private ?\Closure $exceptionHandler;
|
||||
private ?LoggerInterface $logger;
|
||||
private ?LoggerInterface $deprecationLogger;
|
||||
private array|int|null $levels;
|
||||
private ?int $throwAt;
|
||||
private bool $scream;
|
||||
private bool $scope;
|
||||
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
|
||||
@@ -49,19 +49,13 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
* @param bool $scream Enables/disables screaming mode, where even silenced errors are logged
|
||||
* @param bool $scope Enables/disables scoping mode
|
||||
*/
|
||||
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, $scope = true, $deprecationLogger = null, $fileLinkFormat = null)
|
||||
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, array|int|null $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, bool $scope = true, LoggerInterface $deprecationLogger = null)
|
||||
{
|
||||
if (!\is_bool($scope)) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.4', 'Passing a $fileLinkFormat is deprecated.');
|
||||
$scope = $deprecationLogger;
|
||||
$deprecationLogger = $fileLinkFormat;
|
||||
}
|
||||
|
||||
$handler = set_exception_handler('is_int');
|
||||
$this->earlyHandler = \is_array($handler) ? $handler[0] : null;
|
||||
restore_exception_handler();
|
||||
|
||||
$this->exceptionHandler = $exceptionHandler;
|
||||
$this->exceptionHandler = null === $exceptionHandler ? null : $exceptionHandler(...);
|
||||
$this->logger = $logger;
|
||||
$this->levels = $levels ?? \E_ALL;
|
||||
$this->throwAt = \is_int($throwAt) ? $throwAt : (null === $throwAt ? null : ($throwAt ? \E_ALL : null));
|
||||
|
@@ -31,10 +31,7 @@ class DisallowRobotsIndexingListener implements EventSubscriberInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
KernelEvents::RESPONSE => ['onResponse', -255],
|
||||
|
@@ -25,9 +25,9 @@ use Symfony\Component\VarDumper\VarDumper;
|
||||
*/
|
||||
class DumpListener implements EventSubscriberInterface
|
||||
{
|
||||
private $cloner;
|
||||
private $dumper;
|
||||
private $connection;
|
||||
private ClonerInterface $cloner;
|
||||
private DataDumperInterface $dumper;
|
||||
private ?Connection $connection;
|
||||
|
||||
public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper, Connection $connection = null)
|
||||
{
|
||||
@@ -51,7 +51,7 @@ class DumpListener implements EventSubscriberInterface
|
||||
});
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
if (!class_exists(ConsoleEvents::class)) {
|
||||
return [];
|
||||
|
@@ -12,7 +12,6 @@
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Debug\Exception\FlattenException as LegacyFlattenException;
|
||||
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -41,7 +40,7 @@ class ErrorListener implements EventSubscriberInterface
|
||||
/**
|
||||
* @param array<class-string, array{log_level: string|null, status_code: int<100,599>|null}> $exceptionsMapping
|
||||
*/
|
||||
public function __construct($controller, LoggerInterface $logger = null, bool $debug = false, array $exceptionsMapping = [])
|
||||
public function __construct(string|object|array|null $controller, LoggerInterface $logger = null, bool $debug = false, array $exceptionsMapping = [])
|
||||
{
|
||||
$this->controller = $controller;
|
||||
$this->logger = $logger;
|
||||
@@ -102,7 +101,6 @@ class ErrorListener implements EventSubscriberInterface
|
||||
} while ($prev = $wrapper->getPrevious());
|
||||
|
||||
$prev = new \ReflectionProperty($wrapper instanceof \Exception ? \Exception::class : \Error::class, 'previous');
|
||||
$prev->setAccessible(true);
|
||||
$prev->setValue($wrapper, $throwable);
|
||||
|
||||
throw $e;
|
||||
@@ -130,10 +128,10 @@ class ErrorListener implements EventSubscriberInterface
|
||||
return;
|
||||
}
|
||||
|
||||
$r = new \ReflectionFunction(\Closure::fromCallable($event->getController()));
|
||||
$r = new \ReflectionFunction($event->getController()(...));
|
||||
$r = $r->getParameters()[$k] ?? null;
|
||||
|
||||
if ($r && (!($r = $r->getType()) instanceof \ReflectionNamedType || \in_array($r->getName(), [FlattenException::class, LegacyFlattenException::class], true))) {
|
||||
if ($r && (!($r = $r->getType()) instanceof \ReflectionNamedType || FlattenException::class === $r->getName())) {
|
||||
$arguments = $event->getArguments();
|
||||
$arguments[$k] = FlattenException::createFromThrowable($e);
|
||||
$event->setArguments($arguments);
|
||||
|
@@ -33,8 +33,8 @@ use Symfony\Component\HttpKernel\UriSigner;
|
||||
*/
|
||||
class FragmentListener implements EventSubscriberInterface
|
||||
{
|
||||
private $signer;
|
||||
private $fragmentPath;
|
||||
private UriSigner $signer;
|
||||
private string $fragmentPath;
|
||||
|
||||
/**
|
||||
* @param string $fragmentPath The path that triggers this listener
|
||||
|
@@ -25,8 +25,8 @@ use Symfony\Contracts\Translation\LocaleAwareInterface;
|
||||
*/
|
||||
class LocaleAwareListener implements EventSubscriberInterface
|
||||
{
|
||||
private $localeAwareServices;
|
||||
private $requestStack;
|
||||
private iterable $localeAwareServices;
|
||||
private RequestStack $requestStack;
|
||||
|
||||
/**
|
||||
* @param iterable<mixed, LocaleAwareInterface> $localeAwareServices
|
||||
@@ -55,7 +55,7 @@ class LocaleAwareListener implements EventSubscriberInterface
|
||||
$this->setLocale($parentRequest->getLocale(), $parentRequest->getDefaultLocale());
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
// must be registered after the Locale listener
|
||||
@@ -69,7 +69,7 @@ class LocaleAwareListener implements EventSubscriberInterface
|
||||
foreach ($this->localeAwareServices as $service) {
|
||||
try {
|
||||
$service->setLocale($locale);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
} catch (\InvalidArgumentException) {
|
||||
$service->setLocale($defaultLocale);
|
||||
}
|
||||
}
|
||||
|
@@ -29,11 +29,11 @@ use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
*/
|
||||
class LocaleListener implements EventSubscriberInterface
|
||||
{
|
||||
private $router;
|
||||
private $defaultLocale;
|
||||
private $requestStack;
|
||||
private $useAcceptLanguageHeader;
|
||||
private $enabledLocales;
|
||||
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 = [])
|
||||
{
|
||||
@@ -68,17 +68,17 @@ class LocaleListener implements EventSubscriberInterface
|
||||
{
|
||||
if ($locale = $request->attributes->get('_locale')) {
|
||||
$request->setLocale($locale);
|
||||
} elseif ($this->useAcceptLanguageHeader && $this->enabledLocales && ($preferredLanguage = $request->getPreferredLanguage($this->enabledLocales))) {
|
||||
$request->setLocale($preferredLanguage);
|
||||
} elseif ($this->useAcceptLanguageHeader) {
|
||||
if ($preferredLanguage = $request->getPreferredLanguage($this->enabledLocales)) {
|
||||
$request->setLocale($preferredLanguage);
|
||||
}
|
||||
$request->attributes->set('_vary_by_language', true);
|
||||
}
|
||||
}
|
||||
|
||||
private function setRouterContext(Request $request)
|
||||
{
|
||||
if (null !== $this->router) {
|
||||
$this->router->getContext()->setParameter('_locale', $request->getLocale());
|
||||
}
|
||||
$this->router?->getContext()->setParameter('_locale', $request->getLocale());
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
|
@@ -32,17 +32,17 @@ use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||
*/
|
||||
class ProfilerListener implements EventSubscriberInterface
|
||||
{
|
||||
protected $profiler;
|
||||
protected $matcher;
|
||||
protected $onlyException;
|
||||
protected $onlyMainRequests;
|
||||
protected $exception;
|
||||
private Profiler $profiler;
|
||||
private ?RequestMatcherInterface $matcher;
|
||||
private bool $onlyException;
|
||||
private bool $onlyMainRequests;
|
||||
private ?\Throwable $exception = null;
|
||||
/** @var \SplObjectStorage<Request, Profile> */
|
||||
protected $profiles;
|
||||
protected $requestStack;
|
||||
protected $collectParameter;
|
||||
private \SplObjectStorage $profiles;
|
||||
private RequestStack $requestStack;
|
||||
private ?string $collectParameter;
|
||||
/** @var \SplObjectStorage<Request, Request|null> */
|
||||
protected $parents;
|
||||
private \SplObjectStorage $parents;
|
||||
|
||||
/**
|
||||
* @param bool $onlyException True if the profiler only collects data when an exception occurs, false otherwise
|
||||
@@ -87,7 +87,7 @@ class ProfilerListener implements EventSubscriberInterface
|
||||
|
||||
$request = $event->getRequest();
|
||||
if (null !== $this->collectParameter && null !== $collectParameterValue = $request->get($this->collectParameter)) {
|
||||
true === $collectParameterValue || filter_var($collectParameterValue, \FILTER_VALIDATE_BOOLEAN) ? $this->profiler->enable() : $this->profiler->disable();
|
||||
true === $collectParameterValue || filter_var($collectParameterValue, \FILTER_VALIDATE_BOOL) ? $this->profiler->enable() : $this->profiler->disable();
|
||||
}
|
||||
|
||||
$exception = $this->exception;
|
||||
@@ -97,7 +97,7 @@ class ProfilerListener implements EventSubscriberInterface
|
||||
return;
|
||||
}
|
||||
|
||||
$session = $request->hasPreviousSession() && $request->hasSession() ? $request->getSession() : null;
|
||||
$session = $request->hasPreviousSession() ? $request->getSession() : null;
|
||||
|
||||
if ($session instanceof Session) {
|
||||
$usageIndexValue = $usageIndexReference = &$session->getUsageIndex();
|
||||
|
@@ -24,8 +24,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
*/
|
||||
class ResponseListener implements EventSubscriberInterface
|
||||
{
|
||||
private $charset;
|
||||
private $addContentLanguageHeader;
|
||||
private string $charset;
|
||||
private bool $addContentLanguageHeader;
|
||||
|
||||
public function __construct(string $charset, bool $addContentLanguageHeader = false)
|
||||
{
|
||||
|
@@ -42,25 +42,20 @@ use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
*/
|
||||
class RouterListener implements EventSubscriberInterface
|
||||
{
|
||||
private $matcher;
|
||||
private $context;
|
||||
private $logger;
|
||||
private $requestStack;
|
||||
private $projectDir;
|
||||
private $debug;
|
||||
private RequestMatcherInterface|UrlMatcherInterface $matcher;
|
||||
private RequestContext $context;
|
||||
private ?LoggerInterface $logger;
|
||||
private RequestStack $requestStack;
|
||||
private ?string $projectDir;
|
||||
private bool $debug;
|
||||
|
||||
/**
|
||||
* @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher
|
||||
* @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
|
||||
* @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null, string $projectDir = null, bool $debug = true)
|
||||
public function __construct(UrlMatcherInterface|RequestMatcherInterface $matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null, string $projectDir = null, bool $debug = true)
|
||||
{
|
||||
if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
|
||||
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
|
||||
}
|
||||
|
||||
if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
|
||||
throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
|
||||
}
|
||||
@@ -73,7 +68,7 @@ class RouterListener implements EventSubscriberInterface
|
||||
$this->debug = $debug;
|
||||
}
|
||||
|
||||
private function setCurrentRequest(Request $request = null)
|
||||
private function setCurrentRequest(?Request $request)
|
||||
{
|
||||
if (null !== $request) {
|
||||
try {
|
||||
@@ -88,7 +83,7 @@ class RouterListener implements EventSubscriberInterface
|
||||
* 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(FinishRequestEvent $event)
|
||||
public function onKernelFinishRequest()
|
||||
{
|
||||
$this->setCurrentRequest($this->requestStack->getParentRequest());
|
||||
}
|
||||
@@ -113,14 +108,12 @@ class RouterListener implements EventSubscriberInterface
|
||||
$parameters = $this->matcher->match($request->getPathInfo());
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->info('Matched route "{route}".', [
|
||||
'route' => $parameters['_route'] ?? 'n/a',
|
||||
'route_parameters' => $parameters,
|
||||
'request_uri' => $request->getUri(),
|
||||
'method' => $request->getMethod(),
|
||||
]);
|
||||
}
|
||||
$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']);
|
||||
|
@@ -12,45 +12,18 @@
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
|
||||
/**
|
||||
* Sets the session in the request.
|
||||
*
|
||||
* When the passed container contains a "session_storage" entry which
|
||||
* holds a NativeSessionStorage instance, the "cookie_secure" option
|
||||
* will be set to true whenever the current main request is secure.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class SessionListener extends AbstractSessionListener
|
||||
{
|
||||
public function onKernelRequest(RequestEvent $event)
|
||||
{
|
||||
parent::onKernelRequest($event);
|
||||
|
||||
if (!$event->isMainRequest() || (!$this->container->has('session') && !$this->container->has('session_factory'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->container->has('session_storage')
|
||||
&& ($storage = $this->container->get('session_storage')) instanceof NativeSessionStorage
|
||||
&& ($mainRequest = $this->container->get('request_stack')->getMainRequest())
|
||||
&& $mainRequest->isSecure()
|
||||
) {
|
||||
$storage->setOptions(['cookie_secure' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getSession(): ?SessionInterface
|
||||
{
|
||||
if ($this->container->has('session')) {
|
||||
return $this->container->get('session');
|
||||
}
|
||||
|
||||
if ($this->container->has('session_factory')) {
|
||||
return $this->container->get('session_factory')->createSession();
|
||||
}
|
||||
|
@@ -16,6 +16,8 @@ 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.
|
||||
@@ -23,6 +25,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*
|
||||
* @deprecated since Symfony 6.1
|
||||
*/
|
||||
class StreamedResponseListener implements EventSubscriberInterface
|
||||
{
|
||||
|
@@ -26,7 +26,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
*/
|
||||
class SurrogateListener implements EventSubscriberInterface
|
||||
{
|
||||
private $surrogate;
|
||||
private ?SurrogateInterface $surrogate;
|
||||
|
||||
public function __construct(SurrogateInterface $surrogate = null)
|
||||
{
|
||||
|
@@ -1,46 +0,0 @@
|
||||
<?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\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
trigger_deprecation('symfony/http-kernel', '5.4', '"%s" is deprecated, use "%s" instead.', TestSessionListener::class, SessionListener::class);
|
||||
|
||||
/**
|
||||
* Sets the session in the request.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*
|
||||
* @deprecated since Symfony 5.4, use SessionListener instead
|
||||
*/
|
||||
class TestSessionListener extends AbstractTestSessionListener
|
||||
{
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container, array $sessionOptions = [])
|
||||
{
|
||||
$this->container = $container;
|
||||
parent::__construct($sessionOptions);
|
||||
}
|
||||
|
||||
protected function getSession(): ?SessionInterface
|
||||
{
|
||||
if ($this->container->has('session')) {
|
||||
return $this->container->get('session');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -41,9 +41,6 @@ class ValidateRequestListener implements EventSubscriberInterface
|
||||
$request->getHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
|
@@ -17,19 +17,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class AccessDeniedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(403, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class BadRequestHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(400, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class ConflictHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(409, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,6 @@ class ControllerDoesNotReturnResponseException extends \LogicException
|
||||
$this->file = $controllerDefinition['file'];
|
||||
$this->line = $controllerDefinition['line'];
|
||||
$r = new \ReflectionProperty(\Exception::class, 'trace');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, array_merge([
|
||||
[
|
||||
'line' => $line,
|
||||
@@ -50,7 +49,7 @@ class ControllerDoesNotReturnResponseException extends \LogicException
|
||||
'file' => $r->getFileName(),
|
||||
'line' => $r->getEndLine(),
|
||||
];
|
||||
} catch (\ReflectionException $e) {
|
||||
} catch (\ReflectionException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -69,7 +68,7 @@ class ControllerDoesNotReturnResponseException extends \LogicException
|
||||
|
||||
try {
|
||||
$line = $r->getMethod('__invoke')->getEndLine();
|
||||
} catch (\ReflectionException $e) {
|
||||
} catch (\ReflectionException) {
|
||||
$line = $r->getEndLine();
|
||||
}
|
||||
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class GoneHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(410, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
@@ -18,43 +18,27 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class HttpException extends \RuntimeException implements HttpExceptionInterface
|
||||
{
|
||||
private $statusCode;
|
||||
private $headers;
|
||||
private int $statusCode;
|
||||
private array $headers;
|
||||
|
||||
public function __construct(int $statusCode, ?string $message = '', \Throwable $previous = null, array $headers = [], ?int $code = 0)
|
||||
public function __construct(int $statusCode, string $message = '', \Throwable $previous = null, array $headers = [], int $code = 0)
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
if (null === $code) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $code to "%s()" is deprecated, pass 0 instead.', __METHOD__);
|
||||
|
||||
$code = 0;
|
||||
}
|
||||
|
||||
$this->statusCode = $statusCode;
|
||||
$this->headers = $headers;
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public function getStatusCode()
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
public function getHeaders()
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set response headers.
|
||||
*
|
||||
* @param array $headers Response headers
|
||||
*/
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
$this->headers = $headers;
|
||||
|
@@ -20,15 +20,11 @@ interface HttpExceptionInterface extends \Throwable
|
||||
{
|
||||
/**
|
||||
* Returns the status code.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode();
|
||||
public function getStatusCode(): int;
|
||||
|
||||
/**
|
||||
* Returns response headers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders();
|
||||
public function getHeaders(): array;
|
||||
}
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class LengthRequiredHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(411, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
23
vendor/symfony/http-kernel/Exception/LockedHttpException.php
vendored
Normal file
23
vendor/symfony/http-kernel/Exception/LockedHttpException.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
@@ -17,24 +17,10 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
class MethodNotAllowedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string[] $allow An array of allowed methods
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int|null $code The internal exception code
|
||||
* @param string[] $allow An array of allowed methods
|
||||
*/
|
||||
public function __construct(array $allow, ?string $message = '', \Throwable $previous = null, ?int $code = 0, array $headers = [])
|
||||
public function __construct(array $allow, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
if (null === $code) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $code to "%s()" is deprecated, pass 0 instead.', __METHOD__);
|
||||
|
||||
$code = 0;
|
||||
}
|
||||
|
||||
$headers['Allow'] = strtoupper(implode(', ', $allow));
|
||||
|
||||
parent::__construct(405, $message, $previous, $headers, $code);
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class NotAcceptableHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(406, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class NotFoundHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(404, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
@@ -16,19 +16,8 @@ namespace Symfony\Component\HttpKernel\Exception;
|
||||
*/
|
||||
class PreconditionFailedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* @param string|null $message The internal exception message
|
||||
* @param \Throwable|null $previous The previous exception
|
||||
* @param int $code The internal exception code
|
||||
*/
|
||||
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
|
||||
{
|
||||
if (null === $message) {
|
||||
trigger_deprecation('symfony/http-kernel', '5.3', 'Passing null as $message to "%s()" is deprecated, pass an empty string instead.', __METHOD__);
|
||||
|
||||
$message = '';
|
||||
}
|
||||
|
||||
parent::__construct(412, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user