Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ec89ac8

Browse files
committed
feature #25582 [Form] Support \DateTimeImmutable (vudaltsov)
This PR was squashed before being merged into the 4.1-dev branch (closes #25582). Discussion ---------- [Form] Support \DateTimeImmutable | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #9508 | License | MIT | Doc PR | symfony/symfony-docs#8920 This PR implements `input=datetime_immutable`. Replaces #25273. Commits ------- 034f8b2 [Form] Support \DateTimeImmutable
2 parents 0c128f8 + 034f8b2 commit ec89ac8

File tree

9 files changed

+255
-3
lines changed

9 files changed

+255
-3
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+
4.1.0
5+
-----
6+
7+
* added `input=datetime_immutable` to DateType, TimeType, DateTimeType
8+
49
4.0.0
510
-----
611

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Form\DataTransformerInterface;
15+
use Symfony\Component\Form\Exception\TransformationFailedException;
16+
17+
/**
18+
* Transforms between a DateTimeImmutable object and a DateTime object.
19+
*
20+
* @author Valentin Udaltsov <[email protected]>
21+
*/
22+
final class DateTimeImmutableToDateTimeTransformer implements DataTransformerInterface
23+
{
24+
/**
25+
* Transforms a DateTimeImmutable into a DateTime object.
26+
*
27+
* @param \DateTimeImmutable|null $value A DateTimeImmutable object
28+
*
29+
* @return \DateTime|null A \DateTime object
30+
*
31+
* @throws TransformationFailedException If the given value is not a \DateTimeImmutable
32+
*/
33+
public function transform($value)
34+
{
35+
if (null === $value) {
36+
return null;
37+
}
38+
39+
if (!$value instanceof \DateTimeImmutable) {
40+
throw new TransformationFailedException('Expected a \DateTimeImmutable.');
41+
}
42+
43+
return \DateTime::createFromFormat(\DateTime::RFC3339, $value->format(\DateTime::RFC3339));
44+
}
45+
46+
/**
47+
* Transforms a DateTime object into a DateTimeImmutable object.
48+
*
49+
* @param \DateTime|null $value A DateTime object
50+
*
51+
* @return \DateTimeImmutable|null A DateTimeImmutable object
52+
*
53+
* @throws TransformationFailedException If the given value is not a \DateTime
54+
*/
55+
public function reverseTransform($value)
56+
{
57+
if (null === $value) {
58+
return null;
59+
}
60+
61+
if (!$value instanceof \DateTime) {
62+
throw new TransformationFailedException('Expected a \DateTime.');
63+
}
64+
65+
return \DateTimeImmutable::createFromMutable($value);
66+
}
67+
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Form\FormView;
1919
use Symfony\Component\Form\ReversedTransformer;
2020
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
21+
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
2122
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
2223
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
2324
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
@@ -165,7 +166,9 @@ public function buildForm(FormBuilderInterface $builder, array $options)
165166
;
166167
}
167168

168-
if ('string' === $options['input']) {
169+
if ('datetime_immutable' === $options['input']) {
170+
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
171+
} elseif ('string' === $options['input']) {
169172
$builder->addModelTransformer(new ReversedTransformer(
170173
new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'])
171174
));
@@ -254,6 +257,7 @@ public function configureOptions(OptionsResolver $resolver)
254257

255258
$resolver->setAllowedValues('input', array(
256259
'datetime',
260+
'datetime_immutable',
257261
'string',
258262
'timestamp',
259263
'array',

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Form\FormInterface;
1616
use Symfony\Component\Form\FormBuilderInterface;
1717
use Symfony\Component\Form\FormView;
18+
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
1819
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
1920
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
2021
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
@@ -123,7 +124,9 @@ class_exists('IntlTimeZone', false) ? \IntlTimeZone::createDefault() : null,
123124
;
124125
}
125126

126-
if ('string' === $options['input']) {
127+
if ('datetime_immutable' === $options['input']) {
128+
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
129+
} elseif ('string' === $options['input']) {
127130
$builder->addModelTransformer(new ReversedTransformer(
128131
new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'], 'Y-m-d')
129132
));
@@ -258,6 +261,7 @@ public function configureOptions(OptionsResolver $resolver)
258261

259262
$resolver->setAllowedValues('input', array(
260263
'datetime',
264+
'datetime_immutable',
261265
'string',
262266
'timestamp',
263267
'array',

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Form\FormBuilderInterface;
1919
use Symfony\Component\Form\ReversedTransformer;
2020
use Symfony\Component\Form\Exception\InvalidConfigurationException;
21+
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
2122
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
2223
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
2324
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
@@ -133,7 +134,9 @@ public function buildForm(FormBuilderInterface $builder, array $options)
133134
$builder->addViewTransformer(new DateTimeToArrayTransformer($options['model_timezone'], $options['view_timezone'], $parts, 'text' === $options['widget']));
134135
}
135136

136-
if ('string' === $options['input']) {
137+
if ('datetime_immutable' === $options['input']) {
138+
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
139+
} elseif ('string' === $options['input']) {
137140
$builder->addModelTransformer(new ReversedTransformer(
138141
new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'], 'H:i:s')
139142
));
@@ -252,6 +255,7 @@ public function configureOptions(OptionsResolver $resolver)
252255

253256
$resolver->setAllowedValues('input', array(
254257
'datetime',
258+
'datetime_immutable',
255259
'string',
256260
'timestamp',
257261
'array',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Tests\Extension\Core\DataTransformer;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
16+
17+
class DateTimeImmutableToDateTimeTransformerTest extends TestCase
18+
{
19+
public function testTransform()
20+
{
21+
$transformer = new DateTimeImmutableToDateTimeTransformer();
22+
23+
$input = new \DateTimeImmutable('2010-02-03 04:05:06 UTC');
24+
$expectedOutput = new \DateTime('2010-02-03 04:05:06 UTC');
25+
$actualOutput = $transformer->transform($input);
26+
27+
$this->assertInstanceOf(\DateTime::class, $actualOutput);
28+
$this->assertEquals($expectedOutput, $actualOutput);
29+
}
30+
31+
public function testTransformEmpty()
32+
{
33+
$transformer = new DateTimeImmutableToDateTimeTransformer();
34+
35+
$this->assertNull($transformer->transform(null));
36+
}
37+
38+
/**
39+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
40+
* @expectedExceptionMessage Expected a \DateTimeImmutable.
41+
*/
42+
public function testTransformFail()
43+
{
44+
$transformer = new DateTimeImmutableToDateTimeTransformer();
45+
$transformer->transform(new \DateTime());
46+
}
47+
48+
public function testReverseTransform()
49+
{
50+
$transformer = new DateTimeImmutableToDateTimeTransformer();
51+
52+
$input = new \DateTime('2010-02-03 04:05:06 UTC');
53+
$expectedOutput = new \DateTimeImmutable('2010-02-03 04:05:06 UTC');
54+
$actualOutput = $transformer->reverseTransform($input);
55+
56+
$this->assertInstanceOf(\DateTimeImmutable::class, $actualOutput);
57+
$this->assertEquals($expectedOutput, $actualOutput);
58+
}
59+
60+
public function testReverseTransformEmpty()
61+
{
62+
$transformer = new DateTimeImmutableToDateTimeTransformer();
63+
64+
$this->assertNull($transformer->reverseTransform(null));
65+
}
66+
67+
/**
68+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
69+
* @expectedExceptionMessage Expected a \DateTime.
70+
*/
71+
public function testReverseTransformFail()
72+
{
73+
$transformer = new DateTimeImmutableToDateTimeTransformer();
74+
$transformer->reverseTransform(new \DateTimeImmutable());
75+
}
76+
}

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ public function testSubmitDateTime()
5252
$this->assertEquals($dateTime, $form->getData());
5353
}
5454

55+
public function testSubmitDateTimeImmutable()
56+
{
57+
$form = $this->factory->create(static::TESTED_TYPE, null, array(
58+
'model_timezone' => 'UTC',
59+
'view_timezone' => 'UTC',
60+
'date_widget' => 'choice',
61+
'years' => array(2010),
62+
'time_widget' => 'choice',
63+
'input' => 'datetime_immutable',
64+
));
65+
66+
$form->submit(array(
67+
'date' => array(
68+
'day' => '2',
69+
'month' => '6',
70+
'year' => '2010',
71+
),
72+
'time' => array(
73+
'hour' => '3',
74+
'minute' => '4',
75+
),
76+
));
77+
78+
$dateTime = new \DateTimeImmutable('2010-06-02 03:04:00 UTC');
79+
80+
$this->assertEquals($dateTime, $form->getData());
81+
}
82+
5583
public function testSubmitString()
5684
{
5785
$form = $this->factory->create(static::TESTED_TYPE, null, array(
@@ -219,6 +247,26 @@ public function testSubmitDifferentTimezonesDateTime()
219247
$this->assertEquals('2010-06-02T03:04:00-10:00', $form->getViewData());
220248
}
221249

250+
public function testSubmitDifferentTimezonesDateTimeImmutable()
251+
{
252+
$form = $this->factory->create(static::TESTED_TYPE, null, array(
253+
'model_timezone' => 'America/New_York',
254+
'view_timezone' => 'Pacific/Tahiti',
255+
'widget' => 'single_text',
256+
'input' => 'datetime_immutable',
257+
));
258+
259+
$outputTime = new \DateTimeImmutable('2010-06-02 03:04:00 Pacific/Tahiti');
260+
261+
$form->submit('2010-06-02T03:04:00-10:00');
262+
263+
$outputTime = $outputTime->setTimezone(new \DateTimeZone('America/New_York'));
264+
265+
$this->assertInstanceOf(\DateTimeImmutable::class, $form->getData());
266+
$this->assertEquals($outputTime, $form->getData());
267+
$this->assertEquals('2010-06-02T03:04:00-10:00', $form->getViewData());
268+
}
269+
222270
public function testSubmitStringSingleText()
223271
{
224272
$form = $this->factory->create(static::TESTED_TYPE, null, array(

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,28 @@ public function testSubmitFromSingleTextDateTime()
105105
$this->assertEquals('02.06.2010', $form->getViewData());
106106
}
107107

108+
public function testSubmitFromSingleTextDateTimeImmutable()
109+
{
110+
// we test against "de_DE", so we need the full implementation
111+
IntlTestHelper::requireFullIntl($this, false);
112+
113+
\Locale::setDefault('de_DE');
114+
115+
$form = $this->factory->create(static::TESTED_TYPE, null, array(
116+
'format' => \IntlDateFormatter::MEDIUM,
117+
'model_timezone' => 'UTC',
118+
'view_timezone' => 'UTC',
119+
'widget' => 'single_text',
120+
'input' => 'datetime_immutable',
121+
));
122+
123+
$form->submit('2.6.2010');
124+
125+
$this->assertInstanceOf(\DateTimeImmutable::class, $form->getData());
126+
$this->assertEquals(new \DateTimeImmutable('2010-06-02 UTC'), $form->getData());
127+
$this->assertEquals('02.06.2010', $form->getViewData());
128+
}
129+
108130
public function testSubmitFromSingleTextString()
109131
{
110132
// we test against "de_DE", so we need the full implementation

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,28 @@ public function testSubmitDateTime()
3939
$this->assertEquals($input, $form->getViewData());
4040
}
4141

42+
public function testSubmitDateTimeImmutable()
43+
{
44+
$form = $this->factory->create(static::TESTED_TYPE, null, array(
45+
'model_timezone' => 'UTC',
46+
'view_timezone' => 'UTC',
47+
'input' => 'datetime_immutable',
48+
));
49+
50+
$input = array(
51+
'hour' => '3',
52+
'minute' => '4',
53+
);
54+
55+
$form->submit($input);
56+
57+
$dateTime = new \DateTimeImmutable('1970-01-01 03:04:00 UTC');
58+
59+
$this->assertInstanceOf(\DateTimeImmutable::class, $form->getData());
60+
$this->assertEquals($dateTime, $form->getData());
61+
$this->assertEquals($input, $form->getViewData());
62+
}
63+
4264
public function testSubmitString()
4365
{
4466
$form = $this->factory->create(static::TESTED_TYPE, null, array(

0 commit comments

Comments
 (0)