8000 [Form] Add input=date_point to DateTimeType, DateType and TimeType · symfony/symfony@cb58650 · GitHub
[go: up one dir, main page]

Skip to content

Commit cb58650

Browse files
committed
[Form] Add input=date_point to DateTimeType, DateType and TimeType
1 parent ed7dba6 commit cb58650

File tree

8 files changed

+180
-6
lines changed

8 files changed

+180
-6
lines changed

src/Symfony/Component/Form/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add support for displaying nested options in DebugCommand
88
* Add support for strings as data for the `MoneyType`
9+
* Add `input=date_point` to DateTimeType, DateType and TimeType
910

1011
7.2
1112
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Form\Extension\Core\DataTransformer;
13+
14+
use Symfony\Component\Clock\DatePoint;
15+
use Symfony\Component\Form\DataTransformerInterface;
16+
use Symfony\Component\Form\Exception\TransformationFailedException;
17+
18+
/**
19+
* Transforms between a DatePoint object and a DateTime object.
20+
*
21+
* @implements DataTransformerInterface<DatePoint, \DateTime>
22+
*/
23+
final class DatePointToDateTimeTransformer implements DataTransformerInterface
24+
{
25+
/**
26+
* Transforms a DatePoint into a DateTime object.
27+
*
28+
* @param DatePoint|null $value A DatePoint object
29+
*
30+
* @throws TransformationFailedException If the given value is not a \DatePoint
31+
*/
32+
public function transform(mixed $value): ?\DateTime
33+
{
34+
if (null === $value) {
35+
return null;
36+
}
37+
38+
if (!$value instanceof DatePoint) {
39+
throw new TransformationFailedException(\sprintf('Expected a "%s".', DatePoint::class));
40+
}
41+
42+
return \DateTime::createFromImmutable($value);
43+
}
44+
45+
/**
46+
* Transforms a DateTime object into a DatePoint object.
47+
*
48+
* @param \DateTime|null $value A DateTime object
49+
*
50+
* @throws TransformationFailedException If the given value is not a \DateTime
51+
*/
52+
public function reverseTransform(mixed $value): ?DatePoint
53+
{
54+
if (null === $value) {
55+
return null;
56+
}
57+
58+
if (!$value instanceof \DateTime) {
59+
throw new TransformationFailedException('Expected a \DateTime.');
60+
}
61+
62+
return DatePoint::createFromMutable($value);
63+
}
64+
}

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

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

14+
use Symfony\Component\Clock\DatePoint;
1415
use Symfony\Component\Form\AbstractType;
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;
19+
use Symfony\Component\Form\Extension\Core\DataTransformer\DatePointToDateTimeTransformer;
1820
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
1921
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
2022
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToHtml5LocalDateTimeTransformer;
@@ -178,7 +180,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
178180
;
179181
}
180182

181-
if ('datetime_immutable' === $options['input']) {
183+
if ('date_point' === $options['input']) {
184+
if (!class_exists(DatePoint::class)) {
185+
throw new LogicException(\sprintf('The "symfony/clock" component is required to use "%s" with option "input=date_point". Try running "composer require symfony/clock".', self::class));
186+
}
187+
$builder->addModelTransformer(new DatePointToDateTimeTransformer());
188+
} elseif ('datetime_immutable' === $options['input']) {
182189
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
183190
} elseif ('string' === $options['input']) {
184191
$builder->addModelTransformer(new ReversedTransformer(
@@ -194,7 +201,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
194201
));
195202
}
196203

197-
if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) {
204+
if (\in_array($options['input'], ['datetime', 'datetime_immutable', 'date_point'], true) && null !== $options['model_timezone']) {
198205
$builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void {
199206
$date = $event->getData();
200207

@@ -283,6 +290,7 @@ public function configureOptions(OptionsResolver $resolver): void
283290
$resolver->setAllowedValues('input', [
284291
'datetime',
285292
'datetime_immutable',
293+
'date_point',
286294
'string',
287295
'timestamp',
288296
'array',

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

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

14+
use Symfony\Component\Clock\DatePoint;
1415
use Symfony\Component\Form\AbstractType;
1516
use Symfony\Component\Form\Exception\LogicException;
17+
use Symfony\Component\Form\Extension\Core\DataTransformer\DatePointToDateTimeTransformer;
1618
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
1719
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
1820
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
@@ -156,7 +158,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
156158
;
157159
}
158160

159-
if ('datetime_immutable' === $options['input']) {
161+
if ('date_point' === $options['input']) {
162+
if (!class_exists(DatePoint::class)) {
163+
throw new LogicException(\sprintf('The "symfony/clock" component is required to use "%s" with option "input=date_point". Try running "composer require symfony/clock".', self::class));
164+
}
165+
$builder->addModelTransformer(new DatePointToDateTimeTransformer());
166+
} elseif ('datetime_immutable' === $options['input']) {
160167
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
161168
} elseif ('string' === $options['input']) {
162169
$builder->addModelTransformer(new ReversedTransformer(
@@ -172,7 +179,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
172179
));
173180
}
174181

175-
if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) {
182+
if (\in_array($options['input'], ['datetime', 'datetime_immutable', 'date_point'], true) && null !== $options['model_timezone']) {
176183
$builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void {
177184
$date = $event->getData();
178185

@@ -298,6 +305,7 @@ public function configureOptions(OptionsResolver $resolver): void
298305
$resolver->setAllowedValues('input', [
299306
'datetime',
300307
'datetime_immutable',
308+
'date_point',
301309
'string',
302310
'timestamp',
303311
'array',

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

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

14+
use Symfony\Component\Clock\DatePoint;
1415
use Symfony\Component\Form\AbstractType;
1516
use Symfony\Component\Form\Exception\InvalidConfigurationException;
1617
use Symfony\Component\Form\Exception\LogicException;
18+
use Symfony\Component\Form\Extension\Core\DataTransformer\DatePointToDateTimeTransformer;
1719
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
1820
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
1921
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
@@ -190,7 +192,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
190192
$builder->addViewTransformer(new DateTimeToArrayTransformer($options['model_timezone'], $options['view_timezone'], $parts, 'text' === $options['widget'], $options['reference_date']));
191193
}
192194

193-
if ('datetime_immutable' === $options['input']) {
195+
if ('date_point' === $options['input']) {
196+
if (!class_exists(DatePoint::class)) {
197+
throw new LogicException(\sprintf('The "symfony/clock" component is required to use "%s" with option "input=date_point". Try running "composer require symfony/clock".', self::class));
198+
}
199+
$builder->addModelTransformer(new DatePointToDateTimeTransformer());
200+
} elseif ('datetime_immutable' === $options['input']) {
194201
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
195202
} elseif ('string' === $options['input']) {
196203
$builder->addModelTransformer(new ReversedTransformer(
@@ -206,7 +213,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
206213
));
207214
}
208215

209-
if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) {
216+
if (\in_array($options['input'], ['datetime', 'datetime_immutable', 'date_point'], true) && null !== $options['model_timezone']) {
210217
$builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void {
211218
$date = $event->getData();
212219

@@ -354,6 +361,7 @@ public function configureOptions(OptionsResolver $resolver): void
354361
$resolver->setAllowedValues('input', [
355362
'datetime',
356363
'datetime_immutable',
364+
'date_point',
357365
'string',
358366
'timestamp',
359367
'array',

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

+36
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\Component\Clock\DatePoint;
1415
use Symfony\Component\Form\Exception\LogicException;
1516
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
1617
use Symfony\Component\Form\FormError;
@@ -62,6 +63,41 @@ public function testSubmitDateTime()
6263
$this->assertEquals($dateTime, $form->getData());
6364
}
6465

66+
public function testSubmitDatePoint()
67+
{
68+
if (!class_exists(DatePoint::class)) {
69+
self::markTestSkipped('The DatePoint class is not available.');
70+
}
71+
72+
$form = $this->factory->create(static::TESTED_TYPE, null, [
73+
'model_timezone' => 'UTC',
74+
'view_timezone' => 'UTC',
75+
'date_widget' => 'choice',
76+
'years' => [2010],
77+
'time_widget' => 'choice',
78+
'input' => 'date_point',
79+
]);
80+
81+
$input = [
82+
'date' => [
83+
'day' => '2',
84+
'month' => '6',
85+
'year' => '2010',
86+
],
87+
'time' => [
88+
'hour' => '3',
89+
'minute' => '4',
90+
],
91+
];
92+
93+
$form->submit($input);
94+
95+
$this->assertInstanceOf(DatePoint::class, $form->getData());
96+
$datePoint = DatePoint::createFromMutable(new \DateTime('2010-06-02 03:04:00 UTC'));
97+
$this->assertEquals($datePoint, $form->getData());
98+
$this->assertEquals($input, $form->getViewData());
99+
}
100+
65101
public function testSubmitDateTimeImmutable()
66102
{
67103
$form = $this->factory->create(static::TESTED_TYPE, null, [

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

+22
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\Component\Clock\DatePoint;
1415
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
1516
use Symfony\Component\Form\Exception\LogicException;
1617
use Symfony\Component\Form\Extension\Core\Type\DateType;
@@ -115,6 +116,27 @@ public function testSubmitFromSingleTextDateTime()
115116
$this->assertEquals('02.06.2010', $form->getViewData());
116117
}
117118

119+
public function testSubmitFromSingleTextDatePoint()
120+
{
121+
if (!class_exists(DatePoint::class)) {
122+
self::markTestSkipped('The DatePoint class is not available.');
123+
}
124+
125+
$form = $this->factory->create(static::TESTED_TYPE, null, [
126+
'html5' => false,
127+
'model_timezone' => 'UTC',
128+
'view_timezone' => 'UTC',
129+
'widget' => 'single_text',
130+
'input' => 'date_point',
131+
]);
132+
133+
$form->submit('2010-06-02');
134+
135+
$this->assertInstanceOf(DatePoint::class, $form->getData());
136+
$this->assertEquals(DatePoint::createFromMutable(new \DateTime('2010-06-02 UTC')), $form->getData());
137+
$this->assertEquals('2010-06-02', $form->getViewData());
138+
}
139+
118140
public function testSubmitFromSingleTextDateTimeImmutable()
119141
{
120142
// we test against "de_DE", so we need the full implementation

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

+27
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\Component\Clock\DatePoint;
1415
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
1516
use Symfony\Component\Form\Exception\InvalidConfigurationException;
1617
use Symfony\Component\Form\Exception\LogicException;
@@ -45,6 +46,32 @@ public function testSubmitDateTime()
4546
$this->assertEquals($input, $form->getViewData());
4647
}
4748

49+
public function testSubmitDatePoint()
50+
{
51+
if (!class_exists(DatePoint::class)) {
52+
self::markTestSkipped('The DatePoint class is not available.');
53+
}
54+
55+
$form = $this->factory->create(static::TESTED_TYPE, null, [
56+
'model_timezone' => 'UTC',
57+
'view_timezone' => 'UTC',
58+
'input' => 'date_point',
59+
'widget' => 'choice',
60+
]);
61+
62+
$input = [
63+
'hour' => '3',
64+
'minute' => '4',
65+
];
66+
67+
$form->submit($input);
68+
69+
$datePoint = DatePoint::createFromMutable(new \DateTime('1970-01-01 03:04:00 UTC'));
70+
$this->assertInstanceOf(DatePoint::class, $form->getData());
71+
$this->assertEquals($datePoint, $form->getData());
72+
$this->assertEquals($input, $form->getViewData());
73+
}
74+
4875
public function testSubmitDateTimeImmutable()
4976
{
5077
$form = $this->factory->create(static::TESTED_TYPE, null, [

0 commit comments

Comments
 (0)
0