Skip to content

Commit 261a8ed

Browse files
feature #46426 [Form] deprecate using the date and time types with date objects with not-matching timezones (xabbuh)
This PR was merged into the 6.4 branch. Discussion ---------- [Form] deprecate using the date and time types with date objects with not-matching timezones | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | no | Deprecations? | yes | Tickets | | License | MIT | Doc PR | Commits ------- b78bfbc deprecate using date and time types with date objects with not-matching timezones
2 parents 7885223 + b78bfbc commit 261a8ed

File tree

8 files changed

+160
-3
lines changed

8 files changed

+160
-3
lines changed

UPGRADE-6.4.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ DoctrineBridge
1414
* Deprecate `DoctrineDataCollector::addLogger()`, use a `DebugDataHolder` instead
1515
* Deprecate `ContainerAwareLoader`, use dependency injection in your fixtures instead
1616

17+
Form
18+
----
19+
20+
* Deprecate using `DateTime` or `DateTimeImmutable` model data with a different timezone than configured with the
21+
`model_timezone` option in `DateType`, `DateTimeType`, and `TimeType`
22+
1723
HttpFoundation
1824
--------------
1925

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.4
5+
---
6+
7+
* Deprecate using `DateTime` or `DateTimeImmutable` model data with a different timezone than configured with the
8+
`model_timezone` option in `DateType`, `DateTimeType`, and `TimeType`
9+
410
6.3
511
---
612

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
2323
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
2424
use Symfony\Component\Form\FormBuilderInterface;
25+
use Symfony\Component\Form\FormEvent;
26+
use Symfony\Component\Form\FormEvents;
2527
use Symfony\Component\Form\FormInterface;
2628
use Symfony\Component\Form\FormView;
2729
use Symfony\Component\Form\ReversedTransformer;
@@ -194,6 +196,21 @@ public function buildForm(FormBuilderInterface $builder, array $options)
194196
new DateTimeToArrayTransformer($options['model_timezone'], $options['model_timezone'], $parts)
195197
));
196198
}
199+
200+
if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) {
201+
$builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void {
202+
$date = $event->getData();
203+
204+
if (!$date instanceof \DateTimeInterface) {
205+
return;
206+
}
207+
208+
if ($date->getTimezone()->getName() !== $options['model_timezone']) {
209+
trigger_deprecation('symfony/form', '6.4', sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is deprecated.', $date::class, $date->getTimezone()->getName(), $options['model_timezone']));
210+
// throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', $date::class, $date->getTimezone()->getName(), $options['model_timezone']));
211+
}
212+
});
213+
}
197214
}
198215

199216
/**

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
2020
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
2121
use Symfony\Component\Form\FormBuilderInterface;
22+
use Symfony\Component\Form\FormEvent;
23+
use Symfony\Component\Form\FormEvents;
2224
use Symfony\Component\Form\FormInterface;
2325
use Symfony\Component\Form\FormView;
2426
use Symfony\Component\Form\ReversedTransformer;
@@ -178,6 +180,21 @@ class_exists(\IntlTimeZone::class, false) ? \IntlTimeZone::createDefault() : nul
178180
new DateTimeToArrayTransformer($options['model_timezone'], $options['model_timezone'], ['year', 'month', 'day'])
179181
));
180182
}
183+
184+
if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) {
185+
$builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void {
186+
$date = $event->getData();
187+
188+
if (!$date instanceof \DateTimeInterface) {
189+
return;
190+
}
191+
192+
if ($date->getTimezone()->getName() !== $options['model_timezone']) {
193+
trigger_deprecation('symfony/form', '6.4', sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is deprecated.', $date::class, $date->getTimezone()->getName(), $options['model_timezone']));
194+
// throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', $date::class, $date->getTimezone()->getName(), $options['model_timezone']));
195+
}
196+
});
197+
}
181198
}
182199

183200
/**

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,21 @@ public function buildForm(FormBuilderInterface $builder, array $options)
208208
new DateTimeToArrayTransformer($options['model_timezone'], $options['model_timezone'], $parts, 'text' === $options['widget'], $options['reference_date'])
209209
));
210210
}
211+
212+
if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) {
213+
$builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void {
214+
$date = $event->getData();
215+
216+
if (!$date instanceof \DateTimeInterface) {
217+
return;
218+
}
219+
220+
if ($date->getTimezone()->getName() !== $options['model_timezone']) {
221+
trigger_deprecation('symfony/form', '6.4', sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is deprecated.', $date::class, $date->getTimezone()->getName(), $options['model_timezone']));
222+
// throw new LogicException(sprintf('Using a "%s" instance with a timezone ("%s") not matching the configured model timezone "%s" is not supported.', $date::class, $date->getTimezone()->getName(), $options['model_timezone']));
223+
}
224+
});
225+
}
211226
}
212227

213228
/**

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

Lines changed: 34 additions & 2 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 BaseTypeTestCase
1819
{
20+
use ExpectDeprecationTrait;
21+
1922
public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\DateTimeType';
2023

2124
private $defaultLocale;
@@ -154,7 +157,7 @@ public function testSubmitWithoutMinutes()
154157
'with_minutes' => false,
155158
]);
156159

157-
$form->setData(new \DateTime());
160+
$form->setData(new \DateTime('now', new \DateTimeZone('UTC')));
158161

159162
$input = [
160163
'date' => [
@@ -184,7 +187,7 @@ public function testSubmitWithSeconds()
184187
'with_seconds' => true,
185188
]);
186189

187-
$form->setData(new \DateTime());
190+
$form->setData(new \DateTime('now', new \DateTimeZone('UTC')));
188191

189192
$input = [
190193
'date' => [
@@ -748,6 +751,35 @@ public function testSubmitStringWithCustomInputFormat()
748751
$this->assertSame('14/01/2018 21:29:00 +00:00', $form->getData());
749752
}
750753

754+
/**
755+
* @group legacy
756+
*/
757+
public function testDateTimeInputTimezoneNotMatchingModelTimezone()
758+
{
759+
$this->expectDeprecation('Since symfony/form 6.4: Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.');
760+
// $this->expectException(LogicException::class);
761+
// $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.');
762+
763+
$this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [
764+
'model_timezone' => 'Europe/Berlin',
765+
]);
766+
}
767+
768+
/**
769+
* @group legacy
770+
*/
771+
public function testDateTimeImmutableInputTimezoneNotMatchingModelTimezone()
772+
{
773+
$this->expectDeprecation('Since symfony/form 6.4: Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.');
774+
// $this->expectException(LogicException::class);
775+
// $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.');
776+
777+
$this->factory->create(static::TESTED_TYPE, new \DateTimeImmutable('now', new \DateTimeZone('UTC')), [
778+
'input' => 'datetime_immutable',
779+
'model_timezone' => 'Europe/Berlin',
780+
]);
781+
}
782+
751783
protected function getTestOptions(): array
752784
{
753785
return ['widget' => 'choice'];

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

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

14+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1415
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
1516
use Symfony\Component\Form\FormError;
1617
use Symfony\Component\Form\FormInterface;
@@ -19,6 +20,8 @@
1920

2021
class DateTypeTest extends BaseTypeTestCase
2122
{
23+
use ExpectDeprecationTrait;
24+
2225
public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\DateType';
2326

2427
private $defaultTimezone;
@@ -654,7 +657,7 @@ public function testIsSynchronizedReturnsTrueIfChoiceAndCompletelyEmpty()
654657

655658
public function testIsSynchronizedReturnsTrueIfChoiceAndCompletelyFilled()
656659
{
657-
$form = $this->factory->create(static::TESTED_TYPE, new \DateTime(), [
660+
$form = $this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [
658661
'model_timezone' => 'UTC',
659662
'view_timezone' => 'UTC',
660663
'widget' => 'choice',
@@ -1112,6 +1115,35 @@ public function testSubmitStringWithCustomInputFormat()
11121115
$this->assertSame('14/01/2018', $form->getData());
11131116
}
11141117

1118+
/**
1119+
* @group legacy
1120+
*/
1121+
public function testDateTimeInputTimezoneNotMatchingModelTimezone()
1122+
{
1123+
$this->expectDeprecation('Since symfony/form 6.4: Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.');
1124+
// $this->expectException(LogicException::class);
1125+
// $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.');
1126+
1127+
$this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [
1128+
'model_timezone' => 'Europe/Berlin',
1129+
]);
1130+
}
1131+
1132+
/**
1133+
* @group legacy
1134+
*/
1135+
public function testDateTimeImmutableInputTimezoneNotMatchingModelTimezone()
1136+
{
1137+
$this->expectDeprecation('Since symfony/form 6.4: Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.');
1138+
// $this->expectException(LogicException::class);
1139+
// $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.');
1140+
1141+
$this->factory->create(static::TESTED_TYPE, new \DateTimeImmutable('now', new \DateTimeZone('UTC')), [
1142+
'input' => 'datetime_immutable',
1143+
'model_timezone' => 'Europe/Berlin',
1144+
]);
1145+
}
1146+
11151147
protected function getTestOptions(): array
11161148
{
11171149
return ['widget' => 'choice'];

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

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

14+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1415
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
1516
use Symfony\Component\Form\Exception\InvalidConfigurationException;
1617
use Symfony\Component\Form\Exception\LogicException;
@@ -20,6 +21,8 @@
2021

2122
class TimeTypeTest extends BaseTypeTestCase
2223
{
24+
use ExpectDeprecationTrait;
25+
2326
public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\TimeType';
2427

2528
public function testSubmitDateTime()
@@ -1161,6 +1164,35 @@ public static function provideEmptyData()
11611164
];
11621165
}
11631166

1167+
/**
1168+
* @group legacy
1169+
*/
1170+
public function testDateTimeInputTimezoneNotMatchingModelTimezone()
1171+
{
1172+
$this->expectDeprecation('Since symfony/form 6.4: Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.');
1173+
// $this->expectException(LogicException::class);
1174+
// $this->expectExceptionMessage('Using a "DateTime" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.');
1175+
1176+
$this->factory->create(static::TESTED_TYPE, new \DateTime('now', new \DateTimeZone('UTC')), [
1177+
'model_timezone' => 'Europe/Berlin',
1178+
]);
1179+
}
1180+
1181+
/**
1182+
* @group legacy
1183+
*/
1184+
public function testDateTimeImmutableInputTimezoneNotMatchingModelTimezone()
1185+
{
1186+
$this->expectDeprecation('Since symfony/form 6.4: Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is deprecated.');
1187+
// $this->expectException(LogicException::class);
1188+
// $this->expectExceptionMessage('Using a "DateTimeImmutable" instance with a timezone ("UTC") not matching the configured model timezone "Europe/Berlin" is not supported.');
1189+
1190+
$this->factory->create(static::TESTED_TYPE, new \DateTimeImmutable('now', new \DateTimeZone('UTC')), [
1191+
'input' => 'datetime_immutable',
1192+
'model_timezone' => 'Europe/Berlin',
1193+
]);
1194+
}
1195+
11641196
protected function getTestOptions(): array
11651197
{
11661198
return ['widget' => 'choice'];

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy