Skip to content

Commit 972926c

Browse files
bug #48346 [HttpKernel] In DateTimeValueResolver, convert previously defined date attribute to the expected class (GromNaN)
This PR was merged into the 6.1 branch. Discussion ---------- [HttpKernel] In DateTimeValueResolver, convert previously defined date attribute to the expected class | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix https://github.com/symfony/symfony/pull/48098/files#r1013997729 | License | MIT Convert an instance of `DateTimeInterface` to the expected class if the value was predefined in the request attributes. ```php # in a request listener $request->attributes->set('date', new \DateTimeImmutable()); ``` ```php class MyController { public function index(\DateTime $date) { // Use the $date } } ``` ``` Uncaught TypeError: MyController::index(): Argument #1 ($date) must be of type DateTime, DateTimeImmutable given ``` Commits ------- 22a1567 Convert previously defined date attribute to the expected class
2 parents 5b24890 + 22a1567 commit 972926c

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DateTimeValueResolver.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
3939
public function resolve(Request $request, ArgumentMetadata $argument): iterable
4040
{
4141
$value = $request->attributes->get($argument->getName());
42+
$class = \DateTimeInterface::class === $argument->getType() ? \DateTimeImmutable::class : $argument->getType();
4243

4344
if ($value instanceof \DateTimeInterface) {
44-
yield $value;
45+
yield $value instanceof $class ? $value : $class::createFromInterface($value);
4546

4647
return;
4748
}
@@ -52,7 +53,6 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
5253
return;
5354
}
5455

55-
$class = \DateTimeInterface::class === $argument->getType() ? \DateTimeImmutable::class : $argument->getType();
5656
$format = null;
5757

5858
if ($attributes = $argument->getAttributes(MapDateTime::class, ArgumentMetadata::IS_INSTANCEOF)) {

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/DateTimeValueResolverTest.php

+19-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
class DateTimeValueResolverTest extends TestCase
2222
{
23-
private $defaultTimezone;
23+
private readonly string $defaultTimezone;
2424

2525
protected function setUp(): void
2626
{
@@ -32,13 +32,20 @@ protected function tearDown(): void
3232
date_default_timezone_set($this->defaultTimezone);
3333
}
3434

35-
public function getTimeZones()
35+
public static function getTimeZones()
3636
{
3737
yield ['UTC'];
3838
yield ['Etc/GMT+9'];
3939
yield ['Etc/GMT-14'];
4040
}
4141

42+
public static function getClasses()
43+
{
44+
yield [\DateTimeInterface::class];
45+
yield [\DateTime::class];
46+
yield [FooDateTime::class];
47+
}
48+
4249
public function testSupports()
4350
{
4451
$resolver = new DateTimeValueResolver();
@@ -133,19 +140,25 @@ public function testNow(string $timezone)
133140
$this->assertSame($timezone, $results[0]->getTimezone()->getName(), 'Default timezone');
134141
}
135142

136-
public function testPreviouslyConvertedAttribute()
143+
/**
144+
* @param class-string<\DateTimeInterface> $class
145+
*
146+
* @dataProvider getClasses
147+
*/
148+
public function testPreviouslyConvertedAttribute(string $class)
137149
{
138150
$resolver = new DateTimeValueResolver();
139151

140-
$argument = new ArgumentMetadata('dummy', \DateTime::class, false, false, null, true);
152+
$argument = new ArgumentMetadata('dummy', $class, false, false, null, true);
141153
$request = self::requestWithAttributes(['dummy' => $datetime = new \DateTime()]);
142154

143155
/** @var \Generator $results */
144156
$results = $resolver->resolve($request, $argument);
145157
$results = iterator_to_array($results);
146158

147159
$this->assertCount(1, $results);
148-
$this->assertSame($datetime, $results[0]);
160+
$this->assertEquals($datetime, $results[0], 'The value is the same, but the class can be modified.');
161+
$this->assertInstanceOf($class, $results[0]);
149162
}
150163

151164
public function testCustomClass()
@@ -209,7 +222,7 @@ public function testWithFormat(string $timezone)
209222
$this->assertEquals('2016-09-08 12:34:56', $results[0]->format('Y-m-d H:i:s'));
210223
}
211224

212-
public function provideInvalidDates()
225+
public static function provideInvalidDates()
213226
{
214227
return [
215228
'invalid date' => [

0 commit comments

Comments
 (0)