8000 [Form] Deprecate not honoring with_seconds => false for HTML5 datetim… · symfony/symfony@097820f · GitHub
[go: up one dir, main page]

Skip to content

Commit 097820f

Browse files
committed
[Form] Deprecate not honoring with_seconds => false for HTML5 datetime inputs in DateTimeType
1 parent a08a41c commit 097820f

File tree

6 files changed

+93
-15
lines changed

6 files changed

+93
-15
lines changed

UPGRADE-6.3.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ FrameworkBundle
3838
</framework:config>
3939
```
4040

41+
Form
42+
----
43+
44+
* Deprecate not honoring the `with_seconds` option when it's set to `false` for HTML5 datetime inputs in `DateTimeType`, set it to `true` before upgrading to 7.0
45+
4146
FrameworkBundle
4247
---------------
4348

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Add the `bool $withSeconds` optional argument to the constructor of `DateTimeToHtml5LocalDateTimeTransformer`
8+
* Deprecate not honoring the `with_seconds` option when it's set to `false` for HTML5 datetime inputs in `DateTimeType`
9+
410
6.2
511
---
612

src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformer.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@
2323
class DateTimeToHtml5LocalDateTimeTransformer extends BaseDateTimeTransformer
2424
{
2525
public const HTML5_FORMAT = 'Y-m-d\\TH:i:s';
26+
public const HTML5_WITHOUT_SECONDS_FORMAT = 'Y-m-d\\TH:i';
27+
28+
private readonly bool $withSeconds;
29+
30+
/**
31+
* @param bool $withSeconds
32+
*/
33+
public function __construct(string $inputTimezone = null, string $outputTimezone = null/* , private readonly bool $withSeconds = true */)
34+
{
35+
parent::__construct($inputTimezone, $outputTimezone);
36+
37+
$this->withSeconds = 3 <= \func_num_args() ? func_get_arg(2) : true;
38+
}
2639

2740
/**
2841
* Transforms a \DateTime into a local date and time string.
@@ -54,7 +67,7 @@ public function transform(mixed $dateTime): string
5467
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
5568
}
5669

57-
return $dateTime->format(self::HTML5_FORMAT);
70+
return $dateTime->format($this->withSeconds ? self::HTML5_FORMAT : self::HTML5_WITHOUT_SECONDS_FORMAT);
5871
}
5972

6073
/**

src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\Core\Type;
1313

1414
use Symfony\Component\Form\AbstractType;
15+
use Symfony\Component\Form\DataTransformerInterface;
1516
use Symfony\Component\Form\Exception\LogicException;
1617
use Symfony\Component\Form\Extension\Core\DataTransformer\ArrayToPartsTransformer;
1718
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
@@ -74,10 +75,35 @@ public function buildForm(FormBuilderInterface $builder, array $options)
7475

7576
if ('single_text' === $options['widget']) {
7677
if (self::HTML5_FORMAT === $pattern) {
77-
$builder->addViewTransformer(new DateTimeToHtml5LocalDateTimeTransformer(
78-
$options['model_timezone'],
79-
$options['view_timezone']
80-
));
78+
// Keep only the code inside this if in Symfony 7.0
79+
if ($options['with_seconds']) {
80+
$builder->addViewTransformer(new DateTimeToHtml5LocalDateTimeTransformer(
81+
$options['model_timezone'],
82+
$options['view_timezone'],
83+
$options['with_seconds'],
84+
));
85+
} else {
86+
$builder->addViewTransformer(new class(new DateTimeToHtml5LocalDateTimeTransformer($options['model_timezone'], $options['view_timezone'], true)) implements DataTransformerInterface {
87+
public function __construct(
88+
private readonly DateTimeToHtml5LocalDateTimeTransformer $transformer,
89+
) {
90+
}
91+
92+
public function transform(mixed $value): string
93+
{
94+
trigger_deprecation('symfony/form', '6.3', 'The "with_seconds" option for HTML5 datetime inputs in "%s" will be honored in Symfony 7.0, set it to "true" to keep the current behavior and get rid of this deprecation.', DateTimeType::class);
95+
96+
return $this->transformer->transform($value);
97+
}
98+
99+
public function reverseTransform(mixed $value): ?\DateTime
100+
{
101+
// Reverse transform already works without seconds
102+
// We can't "remove" the seconds from a \DateTime instance so there's nothing else to do
103+
return $this->transformer->reverseTransform($value);
104+
}
105+
});
106+
}
81107
} else {
82108
$builder->addViewTransformer(new DateTimeToLocalizedStringTransformer(
83109
$options['model_timezone'],

src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@ class DateTimeToHtml5LocalDateTimeTransformerTest extends BaseDateTimeTransforme
2323
public function transformProvider()
2424
{
2525
return [
26-
['UTC', 'UTC', '2010-02-03 04:05:06 UTC', '2010-02-03T04:05:06'],
27-
['UTC', 'UTC', null, ''],
28-
['America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:06 America/New_York', '2010-02-03T17:05:06'],
29-
['America/New_York', 'Asia/Hong_Kong', null, ''],
30-
['UTC', 'Asia/Hong_Kong', '2010-02-03 04:05:06 UTC', '2010-02-03T12:05:06'],
31-
['America/New_York', 'UTC', '2010-02-03 04:05:06 America/New_York', '2010-02-03T09:05:06'],
26+
['UTC', 'UTC', '2010-02-03 04:05:06 UTC', '2010-02-03T04:05:06', true],
27+
['UTC', 'UTC', null, '', true],
28+
['America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:06 America/New_York', '2010-02-03T17:05:06', true],
29+
['America/New_York', 'Asia/Hong_Kong', null, '', true],
30+
['UTC', 'Asia/Hong_Kong', '2010-02-03 04:05:06 UTC', '2010-02-03T12:05:06', true],
31+
['America/New_York', 'UTC', '2010-02-03 04:05:06 America/New_York', '2010-02-03T09:05:06', true],
32+
['UTC', 'UTC', '2010-02-03 04:05:06 UTC', '2010-02-03T04:05', false],
33+
['America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:06 America/New_York', '2010-02-03T17:05', false],
34+
['UTC', 'Asia/Hong_Kong', '2010-02-03 04:05:06 UTC', '2010-02-03T12:05', false],
35+
['America/New_York', 'UTC', '2010-02-03 04:05:06 America/New_York', '2010-02-03T09:05', false],
3236
];
3337
}
3438

@@ -55,19 +59,19 @@ public function reverseTransformProvider()
5559
/**
5660
* @dataProvider transformProvider
5761
*/
58-
public function testTransform($fromTz, $toTz, $from, $to)
62+
public function testTransform($fromTz, $toTz, $from, $to, bool $withSeconds)
5963
{
60-
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz);
64+
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz, $withSeconds);
6165

6266
$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null));
6367
}
6468

6569
/**
6670
* @dataProvider transformProvider
6771
*/
68-
public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to)
72+
public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to, bool $withSeconds)
6973
{
70-
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz);
74+
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz, $withSeconds);
7175

7276
$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTimeImmutable($from) : null));
7377
}

src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111

1212
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
1313

14+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1415
use Symfony\Component\Form\FormError;
1516
use Symfony\Component\Form\FormInterface;
1617

1718
class DateTimeTypeTest extends BaseTypeTest
1819
{
20+
use ExpectDeprecationTrait;
21+
1922
public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\DateTimeType';
2023

2124
private $defaultLocale;
@@ -243,6 +246,7 @@ public function testSubmitDifferentTimezonesDateTime()
243246
'view_timezone' => 'Pacific/Tahiti',
244247
'widget' => 'single_text',
245248
'input' => 'datetime',
249+
'with_seconds' => true,
246250
]);
247251

248252
$outputTime = new \DateTime('2010-06-02 03:04:00 Pacific/Tahiti');
@@ -262,6 +266,7 @@ public function testSubmitDifferentTimezonesDateTimeImmutable()
262266
'view_timezone' => 'Pacific/Tahiti',
263267
'widget' => 'single_text',
264268
'input' => 'datetime_immutable',
269+
'with_seconds' => true,
265270
]);
266271

267272
$outputTime = new \DateTimeImmutable('2010-06-02 03:04:00 Pacific/Tahiti');
@@ -282,6 +287,7 @@ public function testSubmitStringSingleText()
282287
'view_timezone' => 'UTC',
283288
'input' => 'string',
284289
'widget' => 'single_text',
290+
'with_seconds' => true,
285291
]);
286292

287293
$form->submit('2010-06-02T03:04:00');
@@ -337,6 +343,7 @@ public function testSingleTextWidgetShouldUseTheRightInputType()
337343
{
338344
$view = $this->factory->create(static::TESTED_TYPE, null, [
339345
'widget' => 'single_text',
346+
'with_seconds' => true,
340347
])
341348
->createView();
342349

@@ -462,6 +469,7 @@ public function testPassHtml5TypeIfSingleTextAndHtml5Format()
462469
{
463470
$view = $this->factory->create(static::TESTED_TYPE, null, [
464471
'widget' => 'single_text',
472+
'with_seconds' => true,
465473
])
466474
->createView();
467475

@@ -473,6 +481,7 @@ public function testDontPassHtml5TypeIfHtml5NotAllowed()
473481
$view = $this->factory->create(static::TESTED_TYPE, null, [
474482
'widget' => 'single_text',
475483
'html5' => false,
484+
'with_seconds' => true,
476485
])
477486
->createView();
478487

@@ -663,6 +672,7 @@ public function testSubmitNullWithSingleText()
663672
{
664673
$form = $this->factory->create(static::TESTED_TYPE, null, [
665674
'widget' => 'single_text',
675+
'with_seconds' => true,
666676
]);
667677
$form->submit(null);
668678

@@ -695,6 +705,7 @@ public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedDa
695705
$form = $this->factory->create(static::TESTED_TYPE, null, [
696706
'widget' => $widget,
697707
'empty_data' => $emptyData,
708+
'with_seconds' => 'single_text' === $widget,
698709
]);
699710
$form->submit(null);
700711

@@ -729,10 +740,23 @@ public function testSubmitStringWithCustomInputFormat()
729740
'input' => 'string',
730741
'widget' => 'single_text',
731742
'input_format' => 'd/m/Y H:i:s P',
743+
'with_seconds' => true,
732744
]);
733745

734746
$form->submit('2018-01-14T21:29:00');
735747

736748
$this->assertSame('14/01/2018 21:29:00 +00:00', $form->getData());
737749
}
750+
751+
/**
752+
* @group legacy
753+
*/
754+
public function testHTML5DateTimeInputWithoutSecondsTriggersADeprecation()
755+
{
756+
$this->expectDeprecation('Since symfony/form 6.3: The "with_seconds" option for HTML5 datetime inputs in "Symfony\Component\Form\Extension\Core\Type\DateTimeType" will be honored in Symfony 7.0, set it to "true" to keep the current behavior and get rid of this deprecation.');
757+
758+
$this->factory->create(static::TESTED_TYPE, null, [
759+
'widget' => 'single_text',
760+
]);
761+
}
738762
}

0 commit comments

Comments
 (0)
0