Skip to content

Commit d29f355

Browse files
committed
Rework
1 parent fbfae9a commit d29f355

File tree

53 files changed

+648
-1315
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+648
-1315
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
use Symfony\Component\HttpKernel\Attribute\AsTargetedValueResolver;
102102
use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
103103
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
104-
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ValueResolver\ControllerValueResolverInterface;
104+
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ControllerValueResolverInterface;
105105
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
106106
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
107107
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

src/Symfony/Component/ArgumentResolver/Attribute/MapDateTime.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
* Controller parameter tag to configure DateTime arguments.
1919
*/
2020
#[\Attribute(\Attribute::TARGET_PARAMETER)]
21-
final class MapDateTime extends ValueResolver
21+
class MapDateTime extends ValueResolver
2222
{
2323
/**
2424
* @param string|null $format The DateTime format to use, @see https://php.net/datetime.format
2525
* @param bool $disabled Whether this value resolver is disabled; this allows to enable a value resolver globally while disabling it in specific cases
2626
* @param class-string<ValueResolverInterface>|string $resolver The name of the resolver to use
2727
*/
2828
public function __construct(
29-
public readonly ?string $format = null,
29+
public ?string $format = null,
3030
bool $disabled = false,
3131
string $resolver = DateTimeValueResolver::class,
3232
) {

src/Symfony/Component/ArgumentResolver/Exception/InvalidRawValueException.php renamed to src/Symfony/Component/ArgumentResolver/Exception/InvalidSourceValueException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
/**
1515
* @author Robin Chalas <[email protected]>
1616
*/
17-
class InvalidRawValueException extends RuntimeException implements ExceptionInterface
17+
class InvalidSourceValueException extends RuntimeException implements ExceptionInterface
1818
{
1919
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Symfony\Component\ArgumentResolver;
4+
5+
final readonly class SourceValue
6+
{
7+
const NOT_FOUND = 'notfound';
8+
9+
public function __construct(private mixed $value)
10+
{
11+
}
12+
13+
public function get(): mixed
14+
{
15+
return $this->value;
16+
}
17+
18+
public static function notFound(): self
19+
{
20+
return new self(static::NOT_FOUND);
21+
}
22+
}
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\ArgumentResolver\ValueResolver\Traits;
12+
namespace Symfony\Component\ArgumentResolver\ValueResolver;
1313

1414
use Symfony\Component\ArgumentResolver\ArgumentMetadata\ArgumentMetadata;
15-
use Symfony\Component\ArgumentResolver\Exception\InvalidRawValueException;
15+
use Symfony\Component\ArgumentResolver\Exception\InvalidSourceValueException;
16+
use Symfony\Component\ArgumentResolver\SourceValue;
1617
use Symfony\Component\ArgumentResolver\ValueAccessor\RawValueAccessorInterface;
1718

1819
/**
@@ -22,21 +23,21 @@
2223
* @author Maxime Steinhausser <[email protected]>
2324
* @author Robin Chalas <[email protected]>
2425
*/
25-
trait BackedEnumValueResolverTrait
26+
final readonly class BackedEnumValueResolver implements ValueResolverInterface
2627
{
27-
private function doResolve(ArgumentMetadata $argument, array $rawValues): iterable
28+
public function resolveArgument(ArgumentMetadata $argument, SourceValue $value): iterable
2829
{
2930
if (!is_subclass_of($argument->getType(), \BackedEnum::class)) {
3031
return [];
3132
}
3233

33-
if ($argument->isVariadic()) {
34+
$value = $value->get();
35+
36+
if ($argument->isVariadic() || SourceValue::NOT_FOUND === $value) {
3437
// not supported
3538
return [];
3639
}
3740

38-
$value = $rawValues[0] ?? null;
39-
4041
if (null === $value) {
4142
return [null];
4243
}
@@ -46,7 +47,7 @@ private function doResolve(ArgumentMetadata $argument, array $rawValues): iterab
4647
}
4748

4849
if (!\is_int($value) && !\is_string($value)) {
49-
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)));
50+
throw new \LogicException(\sprintf('Could not resolve the "%s $%s" argument: expecting an int or string, got "%s".', $argument->getType(), $argument->getName(), get_debug_type($value)));
5051
}
5152

5253
/** @var class-string<\BackedEnum> $enumType */
@@ -55,7 +56,7 @@ private function doResolve(ArgumentMetadata $argument, array $rawValues): iterab
5556
try {
5657
return [$enumType::from($value)];
5758
} catch (\ValueError|\TypeError $e) {
58-
throw new InvalidRawValueException(\sprintf('Could not resolve the "%s $%s" controller argument: ', $argument->getType(), $argument->getName()).$e->getMessage(), $e->getCode(), $e);
59+
throw new InvalidSourceValueException(\sprintf('Could not resolve the "%s $%s" argument: ', $argument->getType(), $argument->getName()).$e->getMessage(), $e->getCode(), $e);
5960
}
6061
}
6162
}
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\ArgumentResolver\ValueResolver\Traits;
12+
namespace Symfony\Component\ArgumentResolver\ValueResolver;
1313

1414
use Psr\Clock\ClockInterface;
1515
use Symfony\Component\ArgumentResolver\ArgumentMetadata\ArgumentMetadata;
16-
use Symfony\Component\ArgumentResolver\Exception\InvalidRawValueException;
17-
use Symfony\Component\HttpKernel\Attribute\MapDateTime;
16+
use Symfony\Component\ArgumentResolver\Attribute\MapDateTime;
17+
use Symfony\Component\ArgumentResolver\Exception\InvalidSourceValueException;
18+
use Symfony\Component\ArgumentResolver\SourceValue;
1819

1920
/**
2021
* Convert DateTime instances from request attribute variable.
@@ -23,20 +24,25 @@
2324
* @author Tim Goudriaan <[email protected]>
2425
* @author Robin Chalas <[email protected]>
2526
*/
26-
trait DateTimeValueResolverTrait
27+
final readonly class DateTimeValueResolver implements ValueResolverInterface
2728
{
2829
public function __construct(
2930
private readonly ?ClockInterface $clock = null,
3031
) {
3132
}
3233

33-
private function doResolve(ArgumentMetadata $argument, array $rawValues): iterable
34+
public function resolveArgument(ArgumentMetadata $argument, SourceValue $value): iterable
3435
{
3536
if (!is_a($argument->getType(), \DateTimeInterface::class, true)) {
3637
return [];
3738
}
3839

39-
$value = $rawValues[0] ?? null;
40+
$value = $value->get();
41+
42+
if (SourceValue::NOT_FOUND === $value) {
43+
return [];
44+
}
45+
4046
$class = \DateTimeInterface::class === $argument->getType() ? \DateTimeImmutable::class : $argument->getType();
4147

4248
if (!$value) {
@@ -78,7 +84,7 @@ private function doResolve(ArgumentMetadata $argument, array $rawValues): iterab
7884
}
7985

8086
if (!$date) {
81-
throw new InvalidRawValueException(\sprintf('Invalid date given for parameter "%s".', $argument->getName()));
87+
throw new InvalidSourceValueException(\sprintf('Invalid date given for parameter "%s".', $argument->getName()));
8288
}
8389

8490
return [$date];

src/Symfony/Component/ArgumentResolver/ValueResolver/DefaultValueResolver.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\ArgumentResolver\ValueResolver;
1313

1414
use Symfony\Component\ArgumentResolver\ArgumentMetadata\ArgumentMetadata;
15+
use Symfony\Component\ArgumentResolver\SourceValue;
1516

1617
/**
1718
* Yields the default value defined in the action signature when no value has been given.
@@ -20,7 +21,7 @@
2021
*/
2122
final class DefaultValueResolver implements ValueResolverInterface
2223
{
23-
public function resolve(ArgumentMetadata $argument): iterable
24+
public function resolveArgument(ArgumentMetadata $argument, SourceValue $value): iterable
2425
{
2526
if ($argument->hasDefaultValue()) {
2627
return [$argument->getDefaultValue()];
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\ArgumentResolver\ValueResolver;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\ArgumentResolver\ArgumentMetadata\ArgumentMetadata;
16+
use Symfony\Component\ArgumentResolver\SourceValue;
17+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
18+
19+
/**
20+
* Provides an intuitive error message when controller fails because it is not registered as a service.
21+
*
22+
* @author Simeon Kolev <[email protected]>
23+
*/
24+
final readonly class NotTaggedCallableValueResolver implements ValueResolverInterface
25+
{
26+
public function __construct(
27+
private ContainerInterface $container,
28+
) {
29+
}
30+
31+
public function resolveArgument(ArgumentMetadata $argument, SourceValue $value): iterable
32+
{
33+
$callable = $value->get();
34+
35+
if (\is_array($callable) && \is_callable($callable, true) && \is_string($callable[0])) {
36+
$callable = $callable[0].'::'.$callable[1];
37+
} elseif (!\is_string($callable) || '' === $callable || SourceValue::NOT_FOUND === $callable) {
38+
return [];
39+
}
40+
41+
if ('\\' === $callable[0]) {
42+
$callable = ltrim($callable, '\\');
43+
}
44+
45+
if (!$this->container->has($callable)) {
46+
$callable = (false !== $i = strrpos($callable, ':'))
47+
? substr($callable, 0, $i).strtolower(substr($callable, $i))
48+
: $callable.'::__invoke';
49+
}
50+
51+
if ($this->container->has($callable)) {
52+
return [];
53+
}
54+
55+
throw new RuntimeException(\sprintf('Could not resolve argument $%s of "%s()", maybe you forgot to register it as a service?', $argument->getName(), $callable));
56+
}
57+
}
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\ArgumentResolver\ValueResolver\Traits;
12+
namespace Symfony\Component\ArgumentResolver\ValueResolver;
1313

1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\ArgumentResolver\ArgumentMetadata\ArgumentMetadata;
1616
use Symfony\Component\ArgumentResolver\Exception\NearMissValueResolverException;
17+
use Symfony\Component\ArgumentResolver\SourceValue;
1718
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
1819

1920
/**
@@ -22,16 +23,26 @@
2223
* @author Nicolas Grekas <[email protected]>
2324
* @author Robin Chalas <[email protected]>
2425
*/
25-
trait ServiceValueResolverTrait
26+
final readonly class ServiceValueResolver implements ValueResolverInterface
2627
{
2728
public function __construct(
2829
private ContainerInterface $container,
2930
) {
3031
}
3132

32-
private function doResolve(ArgumentMetadata $argument, array $rawValues): iterable
33+
public function resolveArgument(ArgumentMetadata $argument, SourceValue $value): iterable
3334
{
34-
$callable = $rawValues[0];
35+
$callable = $value->get();
36+
37+
if (SourceValue::NOT_FOUND === $callable) {
38+
return [];
39+
}
40+
41+
if (\is_array($callable) && \is_callable($callable, true) && \is_string($callable[0])) {
42+
$callable = $callable[0].'::'.$callable[1];
43+
} elseif (!\is_string($callable) || '' === $callable) {
44+
return [];
45+
}
3546

3647
if ('\\' === $callable[0]) {
3748
$callable = ltrim($callable, '\\');

src/Symfony/Component/ArgumentResolver/ValueResolver/Traits/VariadicValueResolverTrait.php

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)