Skip to content

Commit f1160d6

Browse files
wkanianicolas-grekas
authored andcommitted
[Form] Add input=date_point to DateTimeType, DateType and TimeType
1 parent ed7dba6 commit f1160d6

File tree

9 files changed

+181
-6
lines changed

9 files changed

+181
-6
lines changed

src/Symfony/Component/Form/CHANGELOG.md

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

4+
7.4
5+
---
6+
7+
* Add `input=date_point` to `DateTimeType`, `DateType` and `TimeType`
8+
49
7.3
510
---
611

Lines changed: 64 additions & 0 deletions
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

Lines changed: 10 additions & 2 deletions
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

Lines changed: 10 additions & 2 deletions
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

Lines changed: 10 additions & 2 deletions
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

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\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,37 @@ public function testSubmitDateTime()
6263
$this->assertEquals($dateTime, $form->getData());
6364
}
6465

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

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

Lines changed: 22 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\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

Lines changed: 27 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\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+
'widget' => 'choice',
59+
'input' => 'date_point',
60+
]);
61+
62+
$input = [
63+
'hour' => '3',
64+
'minute' => '4',
65+
];
66+
67+
$form->submit($input);
68+
69+
$this->assertInstanceOf(DatePoint::class, $form->getData());
70+
$datePoint = DatePoint::createFromMutable(new \DateTime('1970-01-01 03:04:00 UTC'));
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, [

src/Symfony/Component/Form/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"symfony/validator": "^6.4|^7.0",
3232
"symfony/dependency-injection": "^6.4|^7.0",
3333
"symfony/expression-language": "^6.4|^7.0",
34+
"symfony/clock": "^6.4|^7.0",
3435
"symfony/config": "^6.4|^7.0",
3536
"symfony/console": "^6.4|^7.0",
3637
"symfony/html-sanitizer": "^6.4|^7.0",

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