[Form] Support \DateTimeImmutable
This commit is contained in:
parent
32cc2e06a3
commit
034f8b2f23
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
4.1.0
|
||||
-----
|
||||
|
||||
* added `input=datetime_immutable` to DateType, TimeType, DateTimeType
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
|
||||
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
|
||||
/**
|
||||
* Transforms between a DateTimeImmutable object and a DateTime object.
|
||||
*
|
||||
* @author Valentin Udaltsov <udaltsov.valentin@gmail.com>
|
||||
*/
|
||||
final class DateTimeImmutableToDateTimeTransformer implements DataTransformerInterface
|
||||
{
|
||||
/**
|
||||
* Transforms a DateTimeImmutable into a DateTime object.
|
||||
*
|
||||
* @param \DateTimeImmutable|null $value A DateTimeImmutable object
|
||||
*
|
||||
* @return \DateTime|null A \DateTime object
|
||||
*
|
||||
* @throws TransformationFailedException If the given value is not a \DateTimeImmutable
|
||||
*/
|
||||
public function transform($value)
|
||||
{
|
||||
if (null === $value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$value instanceof \DateTimeImmutable) {
|
||||
throw new TransformationFailedException('Expected a \DateTimeImmutable.');
|
||||
}
|
||||
|
||||
return \DateTime::createFromFormat(\DateTime::RFC3339, $value->format(\DateTime::RFC3339));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a DateTime object into a DateTimeImmutable object.
|
||||
*
|
||||
* @param \DateTime|null $value A DateTime object
|
||||
*
|
||||
* @return \DateTimeImmutable|null A DateTimeImmutable object
|
||||
*
|
||||
* @throws TransformationFailedException If the given value is not a \DateTime
|
||||
*/
|
||||
public function reverseTransform($value)
|
||||
{
|
||||
if (null === $value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$value instanceof \DateTime) {
|
||||
throw new TransformationFailedException('Expected a \DateTime.');
|
||||
}
|
||||
|
||||
return \DateTimeImmutable::createFromMutable($value);
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\ReversedTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
|
||||
@ -165,7 +166,9 @@ class DateTimeType extends AbstractType
|
||||
;
|
||||
}
|
||||
|
||||
if ('string' === $options['input']) {
|
||||
if ('datetime_immutable' === $options['input']) {
|
||||
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
|
||||
} elseif ('string' === $options['input']) {
|
||||
$builder->addModelTransformer(new ReversedTransformer(
|
||||
new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'])
|
||||
));
|
||||
@ -254,6 +257,7 @@ class DateTimeType extends AbstractType
|
||||
|
||||
$resolver->setAllowedValues('input', array(
|
||||
'datetime',
|
||||
'datetime_immutable',
|
||||
'string',
|
||||
'timestamp',
|
||||
'array',
|
||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
|
||||
@ -123,7 +124,9 @@ class DateType extends AbstractType
|
||||
;
|
||||
}
|
||||
|
||||
if ('string' === $options['input']) {
|
||||
if ('datetime_immutable' === $options['input']) {
|
||||
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
|
||||
} elseif ('string' === $options['input']) {
|
||||
$builder->addModelTransformer(new ReversedTransformer(
|
||||
new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'], 'Y-m-d')
|
||||
));
|
||||
@ -258,6 +261,7 @@ class DateType extends AbstractType
|
||||
|
||||
$resolver->setAllowedValues('input', array(
|
||||
'datetime',
|
||||
'datetime_immutable',
|
||||
'string',
|
||||
'timestamp',
|
||||
'array',
|
||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\ReversedTransformer;
|
||||
use Symfony\Component\Form\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
|
||||
@ -133,7 +134,9 @@ class TimeType extends AbstractType
|
||||
$builder->addViewTransformer(new DateTimeToArrayTransformer($options['model_timezone'], $options['view_timezone'], $parts, 'text' === $options['widget']));
|
||||
}
|
||||
|
||||
if ('string' === $options['input']) {
|
||||
if ('datetime_immutable' === $options['input']) {
|
||||
$builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer());
|
||||
} elseif ('string' === $options['input']) {
|
||||
$builder->addModelTransformer(new ReversedTransformer(
|
||||
new DateTimeToStringTransformer($options['model_timezone'], $options['model_timezone'], 'H:i:s')
|
||||
));
|
||||
@ -252,6 +255,7 @@ class TimeType extends AbstractType
|
||||
|
||||
$resolver->setAllowedValues('input', array(
|
||||
'datetime',
|
||||
'datetime_immutable',
|
||||
'string',
|
||||
'timestamp',
|
||||
'array',
|
||||
|
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer;
|
||||
|
||||
class DateTimeImmutableToDateTimeTransformerTest extends TestCase
|
||||
{
|
||||
public function testTransform()
|
||||
{
|
||||
$transformer = new DateTimeImmutableToDateTimeTransformer();
|
||||
|
||||
$input = new \DateTimeImmutable('2010-02-03 04:05:06 UTC');
|
||||
$expectedOutput = new \DateTime('2010-02-03 04:05:06 UTC');
|
||||
$actualOutput = $transformer->transform($input);
|
||||
|
||||
$this->assertInstanceOf(\DateTime::class, $actualOutput);
|
||||
$this->assertEquals($expectedOutput, $actualOutput);
|
||||
}
|
||||
|
||||
public function testTransformEmpty()
|
||||
{
|
||||
$transformer = new DateTimeImmutableToDateTimeTransformer();
|
||||
|
||||
$this->assertNull($transformer->transform(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
* @expectedExceptionMessage Expected a \DateTimeImmutable.
|
||||
*/
|
||||
public function testTransformFail()
|
||||
{
|
||||
$transformer = new DateTimeImmutableToDateTimeTransformer();
|
||||
$transformer->transform(new \DateTime());
|
||||
}
|
||||
|
||||
public function testReverseTransform()
|
||||
{
|
||||
$transformer = new DateTimeImmutableToDateTimeTransformer();
|
||||
|
||||
$input = new \DateTime('2010-02-03 04:05:06 UTC');
|
||||
$expectedOutput = new \DateTimeImmutable('2010-02-03 04:05:06 UTC');
|
||||
$actualOutput = $transformer->reverseTransform($input);
|
||||
|
||||
$this->assertInstanceOf(\DateTimeImmutable::class, $actualOutput);
|
||||
$this->assertEquals($expectedOutput, $actualOutput);
|
||||
}
|
||||
|
||||
public function testReverseTransformEmpty()
|
||||
{
|
||||
$transformer = new DateTimeImmutableToDateTimeTransformer();
|
||||
|
||||
$this->assertNull($transformer->reverseTransform(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
* @expectedExceptionMessage Expected a \DateTime.
|
||||
*/
|
||||
public function testReverseTransformFail()
|
||||
{
|
||||
$transformer = new DateTimeImmutableToDateTimeTransformer();
|
||||
$transformer->reverseTransform(new \DateTimeImmutable());
|
||||
}
|
||||
}
|
@ -52,6 +52,34 @@ class DateTimeTypeTest extends BaseTypeTest
|
||||
$this->assertEquals($dateTime, $form->getData());
|
||||
}
|
||||
|
||||
public function testSubmitDateTimeImmutable()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
'model_timezone' => 'UTC',
|
||||
'view_timezone' => 'UTC',
|
||||
'date_widget' => 'choice',
|
||||
'years' => array(2010),
|
||||
'time_widget' => 'choice',
|
||||
'input' => 'datetime_immutable',
|
||||
));
|
||||
|
||||
$form->submit(array(
|
||||
'date' => array(
|
||||
'day' => '2',
|
||||
'month' => '6',
|
||||
'year' => '2010',
|
||||
),
|
||||
'time' => array(
|
||||
'hour' => '3',
|
||||
'minute' => '4',
|
||||
),
|
||||
));
|
||||
|
||||
$dateTime = new \DateTimeImmutable('2010-06-02 03:04:00 UTC');
|
||||
|
||||
$this->assertEquals($dateTime, $form->getData());
|
||||
}
|
||||
|
||||
public function testSubmitString()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
@ -219,6 +247,26 @@ class DateTimeTypeTest extends BaseTypeTest
|
||||
$this->assertEquals('2010-06-02T03:04:00-10:00', $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitDifferentTimezonesDateTimeImmutable()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
'model_timezone' => 'America/New_York',
|
||||
'view_timezone' => 'Pacific/Tahiti',
|
||||
'widget' => 'single_text',
|
||||
'input' => 'datetime_immutable',
|
||||
));
|
||||
|
||||
$outputTime = new \DateTimeImmutable('2010-06-02 03:04:00 Pacific/Tahiti');
|
||||
|
||||
$form->submit('2010-06-02T03:04:00-10:00');
|
||||
|
||||
$outputTime = $outputTime->setTimezone(new \DateTimeZone('America/New_York'));
|
||||
|
||||
$this->assertInstanceOf(\DateTimeImmutable::class, $form->getData());
|
||||
$this->assertEquals($outputTime, $form->getData());
|
||||
$this->assertEquals('2010-06-02T03:04:00-10:00', $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitStringSingleText()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
|
@ -105,6 +105,28 @@ class DateTypeTest extends BaseTypeTest
|
||||
$this->assertEquals('02.06.2010', $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitFromSingleTextDateTimeImmutable()
|
||||
{
|
||||
// we test against "de_DE", so we need the full implementation
|
||||
IntlTestHelper::requireFullIntl($this, false);
|
||||
|
||||
\Locale::setDefault('de_DE');
|
||||
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
'format' => \IntlDateFormatter::MEDIUM,
|
||||
'model_timezone' => 'UTC',
|
||||
'view_timezone' => 'UTC',
|
||||
'widget' => 'single_text',
|
||||
'input' => 'datetime_immutable',
|
||||
));
|
||||
|
||||
$form->submit('2.6.2010');
|
||||
|
||||
$this->assertInstanceOf(\DateTimeImmutable::class, $form->getData());
|
||||
$this->assertEquals(new \DateTimeImmutable('2010-06-02 UTC'), $form->getData());
|
||||
$this->assertEquals('02.06.2010', $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitFromSingleTextString()
|
||||
{
|
||||
// we test against "de_DE", so we need the full implementation
|
||||
|
@ -39,6 +39,28 @@ class TimeTypeTest extends BaseTypeTest
|
||||
$this->assertEquals($input, $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitDateTimeImmutable()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
'model_timezone' => 'UTC',
|
||||
'view_timezone' => 'UTC',
|
||||
'input' => 'datetime_immutable',
|
||||
));
|
||||
|
||||
$input = array(
|
||||
'hour' => '3',
|
||||
'minute' => '4',
|
||||
);
|
||||
|
||||
$form->submit($input);
|
||||
|
||||
$dateTime = new \DateTimeImmutable('1970-01-01 03:04:00 UTC');
|
||||
|
||||
$this->assertInstanceOf(\DateTimeImmutable::class, $form->getData());
|
||||
$this->assertEquals($dateTime, $form->getData());
|
||||
$this->assertEquals($input, $form->getViewData());
|
||||
}
|
||||
|
||||
public function testSubmitString()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
|
Reference in New Issue
Block a user