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

Skip to content

[Form] deprecate submitting non HTML5 formatted dates #28724

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,7 @@ public function testDateTimeWithWidgetSingleText()
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', '2011-02-03 04:05:06', array(
'input' => 'string',
'widget' => 'single_text',
'strict_format' => true,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
));
Expand All @@ -1589,6 +1590,7 @@ public function testDateTimeWithWidgetSingleTextIgnoreDateAndTimeWidgets()
'date_widget' => 'choice',
'time_widget' => 'choice',
'widget' => 'single_text',
'strict_format' => true,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
));
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bridge/Twig/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"symfony/asset": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
"symfony/form": "^4.1.5",
"symfony/form": "^4.2",
"symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0",
"symfony/polyfill-intl-icu": "~1.0",
Expand All @@ -42,7 +42,7 @@
},
"conflict": {
"symfony/console": "<3.4",
"symfony/form": "<4.1.2",
"symfony/form": "<4.2",
"symfony/translation": "<4.2"
},
"suggest": {
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"symfony/dom-crawler": "~3.4|~4.0",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/security": "~3.4|~4.0",
"symfony/form": "^4.1",
"symfony/form": "^4.2",
"symfony/expression-language": "~3.4|~4.0",
"symfony/messenger": "^4.2",
"symfony/process": "~3.4|~4.0",
Expand All @@ -66,7 +66,7 @@
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
"symfony/asset": "<3.4",
"symfony/console": "<3.4",
"symfony/form": "<4.1",
"symfony/form": "<4.2",
"symfony/messenger": "<4.2",
"symfony/property-info": "<3.4",
"symfony/serializer": "<4.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ class DateTimeToHtml5LocalDateTimeTransformer extends BaseDateTimeTransformer
{
const HTML5_FORMAT = 'Y-m-d\\TH:i:s';

private $strict;

public function __construct(string $inputTimezone = null, string $outputTimezone = null, bool $strict = false)
{
parent::__construct($inputTimezone, $outputTimezone);

$this->strict = $strict;

if (!$this->strict) {
@trigger_error(sprintf('Parsing dates in %s that are not formatted according to the HTML5 specifications is deprecated since Symfony 4.2.', self::class), E_USER_DEPRECATED);
}
}

/**
* Transforms a \DateTime into a local date and time string.
*
Expand Down Expand Up @@ -81,7 +94,15 @@ public function reverseTransform($dateTimeLocal)
return;
}

if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})[T ]\d{2}:\d{2}(?::\d{2})?$/', $dateTimeLocal, $matches)) {
// to maintain backwards compatibility we do not strictly validate the submitted date
// see https://github.com/symfony/symfony/issues/28699
if (!$this->strict) {
$regex = '/^(\d{4})-(\d{2})-(\d{2})[T ]\d{2}:\d{2}(?::\d{2})?/';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to maintain BC, shouldn't it use the old transformer instead (which did not have that regex either, so you are only partially fixing the BC break)

} else {
$regex = '/^(\d{4})-(\d{2})-(\d{2})[T ]\d{2}:\d{2}(?::\d{2})?$/';
}

if (!preg_match($regex, $dateTimeLocal, $matches)) {
throw new TransformationFailedException(sprintf('The date "%s" is not a valid date.', $dateTimeLocal));
}

Expand Down
12 changes: 11 additions & 1 deletion src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
if (self::HTML5_FORMAT === $pattern) {
$builder->addViewTransformer(new DateTimeToHtml5LocalDateTimeTransformer(
$options['model_timezone'],
$options['view_timezone']
$options['view_timezone'],
$options['strict_format']
));
} else {
$builder->addViewTransformer(new DateTimeToLocalizedStringTransformer(
Expand Down Expand Up @@ -218,6 +219,7 @@ public function configureOptions(OptionsResolver $resolver)
'model_timezone' => null,
'view_timezone' => null,
'format' => self::HTML5_FORMAT,
'strict_format' => false,
'date_format' => null,
'widget' => null,
'date_widget' => $dateWidget,
Expand Down Expand Up @@ -278,6 +280,14 @@ public function configureOptions(OptionsResolver $resolver)
'text',
'choice',
));

$resolver->setNormalizer('strict_format', function (Options $options, $strictFormat) {
if (!$strictFormat && 'single_text' === 'widget' && self::HTML5_FORMAT === $options['format']) {
@trigger_error(sprintf('Setting the "strict_format" option of %s to "false" is deprecated since Symfony 4.2.', self::class), E_USER_DEPRECATED);
}

return $strictFormat;
});
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,7 @@ public function testDateTimeWithWidgetSingleText()
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateTimeType', '2011-02-03 04:05:06', array(
'input' => 'string',
'widget' => 'single_text',
'strict_format' => true,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
));
Expand All @@ -1513,6 +1514,7 @@ public function testDateTimeWithWidgetSingleTextIgnoreDateAndTimeWidgets()
'date_widget' => 'choice',
'time_widget' => 'choice',
'widget' => 'single_text',
'strict_format' => true,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function reverseTransformProvider()
*/
public function testTransform($fromTz, $toTz, $from, $to)
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz);
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz, true);

$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null));
}
Expand All @@ -69,7 +69,7 @@ public function testTransform($fromTz, $toTz, $from, $to)
*/
public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to)
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz);
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz, true);

$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTimeImmutable($from) : null));
}
Expand All @@ -79,14 +79,29 @@ public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to)
*/
public function testTransformRequiresValidDateTime()
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer();
$transformer = new DateTimeToHtml5LocalDateTimeTransformer(null, null, true);
$transformer->transform('2010-01-01');
}

/**
* @dataProvider reverseTransformProvider
*/
public function testReverseTransform($toTz, $fromTz, $to, $from)
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($toTz, $fromTz, true);

if (null !== $to) {
$this->assertEquals(new \DateTime($to), $transformer->reverseTransform($from));
} else {
$this->assertNull($transformer->reverseTransform($from));
}
}

/**
* @group legacy
* @dataProvider nonHtml5DatesProvider
*/
public function testReverseTransformNonHtml5Dates($toTz, $fromTz, $to, $from)
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer($toTz, $fromTz);

Expand All @@ -97,12 +112,22 @@ public function testReverseTransform($toTz, $fromTz, $to, $from)
}
}

public function nonHtml5DatesProvider()
{
return array(
array('UTC', 'UTC', '2018-09-15T10:00:00Z', '2018-09-15T10:00:00Z'),
array('Europe/Berlin', 'Europe/Berlin', '2018-09-15T10:00:00+02:00', '2018-09-15T10:00:00+02:00'),
array('Europe/Berlin', 'Europe/Berlin', '2018-09-15T10:00:00+0200', '2018-09-15T10:00:00+0200'),
array('UTC', 'UTC', '2018-10-03T10:00:00.000Z', '2018-10-03T10:00:00.000Z'),
);
}

/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testReverseTransformRequiresString()
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer();
$transformer = new DateTimeToHtml5LocalDateTimeTransformer(null, null, true);
$transformer->reverseTransform(12345);
}

Expand All @@ -111,7 +136,7 @@ public function testReverseTransformRequiresString()
*/
public function testReverseTransformWithNonExistingDate()
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer('UTC', 'UTC');
$transformer = new DateTimeToHtml5LocalDateTimeTransformer('UTC', 'UTC', true);

$transformer->reverseTransform('2010-04-31T04:05');
}
Expand All @@ -121,7 +146,7 @@ public function testReverseTransformWithNonExistingDate()
*/
public function testReverseTransformExpectsValidDateString()
{
$transformer = new DateTimeToHtml5LocalDateTimeTransformer('UTC', 'UTC');
$transformer = new DateTimeToHtml5LocalDateTimeTransformer('UTC', 'UTC', true);

$transformer->reverseTransform('2010-2010-2010');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ public function testSubmitDifferentTimezonesDateTime()
'view_timezone' => 'Pacific/Tahiti',
'widget' => 'single_text',
'input' => 'datetime',
'strict_format' => true,
));

$outputTime = new \DateTime('2010-06-02 03:04:00 Pacific/Tahiti');
Expand All @@ -254,6 +255,7 @@ public function testSubmitDifferentTimezonesDateTimeImmutable()
'view_timezone' => 'Pacific/Tahiti',
'widget' => 'single_text',
'input' => 'datetime_immutable',
'strict_format' => true,
));

$outputTime = new \DateTimeImmutable('2010-06-02 03:04:00 Pacific/Tahiti');
Expand All @@ -274,6 +276,7 @@ public function testSubmitStringSingleText()
'view_timezone' => 'UTC',
'input' => 'string',
'widget' => 'single_text',
'strict_format' => true,
));

$form->submit('2010-06-02T03:04:00');
Expand All @@ -290,6 +293,7 @@ public function testSubmitStringSingleTextWithSeconds()
'input' => 'string',
'widget' => 'single_text',
'with_seconds' => true,
'strict_format' => true,
));

$form->submit('2010-06-02T03:04:05');
Expand Down Expand Up @@ -328,6 +332,7 @@ public function testSingleTextWidgetShouldUseTheRightInputType()
{
$view = $this->factory->create(static::TESTED_TYPE, null, array(
'widget' => 'single_text',
'strict_format' => true,
))
->createView();

Expand Down Expand Up @@ -453,6 +458,7 @@ public function testPassHtml5TypeIfSingleTextAndHtml5Format()
{
$view = $this->factory->create(static::TESTED_TYPE, null, array(
'widget' => 'single_text',
'strict_format' => true,
))
->createView();

Expand All @@ -464,6 +470,7 @@ public function testDontPassHtml5TypeIfHtml5NotAllowed()
$view = $this->factory->create(static::TESTED_TYPE, null, array(
'widget' => 'single_text',
'html5' => false,
'strict_format' => true,
))
->createView();

Expand Down Expand Up @@ -621,6 +628,7 @@ public function testSubmitNullWithSingleText()
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(
'widget' => 'single_text',
'strict_format' => true,
));
$form->submit(null);

Expand Down