From e6b5595f7960a07884368b82da7886c449c24f90 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Mon, 9 Jul 2012 17:53:01 +0200 Subject: [PATCH] [Form] Fixed display of empty values in DateType, TimeType and DateTimeType if they are not required --- src/Symfony/Component/Form/CHANGELOG.md | 1 + .../Form/Extension/Core/Type/DateTimeType.php | 8 +- .../Form/Extension/Core/Type/DateType.php | 12 +- .../Form/Extension/Core/Type/TimeType.php | 12 +- .../Extension/Core/Type/DateTimeTypeTest.php | 115 ++++++++++++++++++ .../Extension/Core/Type/DateTypeTest.php | 84 +++++++++++++ .../Extension/Core/Type/TimeTypeTest.php | 90 ++++++++++++++ 7 files changed, 314 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 05e733584a..df2dd57195 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -142,3 +142,4 @@ CHANGELOG * [BC BREAK] compound forms now always need a data mapper * FormBuilder now maintains the order when explicitely adding form builders as children * ChoiceType now doesn't add the empty value anymore if the choices already contain an empty element + * DateType, TimeType and DateTimeType now show empty values again if not required diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index 1711a5009a..dc76d8f738 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -155,8 +155,6 @@ class DateTimeType extends AbstractType 'by_reference' => false, // This will overwrite "widget" child options 'widget' => null, - // This will overwrite "empty_value" child options - 'empty_value' => null, // If initialized with a \DateTime object, FormType initializes // this option to "\DateTime". Since the internal, normalized // representation is not \DateTime, but an array, we need to unset @@ -165,6 +163,12 @@ class DateTimeType extends AbstractType 'compound' => $compound, )); + // Don't add some defaults in order to preserve the defaults + // set in DateType and TimeType + $resolver->setOptional(array( + 'empty_value', + )); + $resolver->setAllowedValues(array( 'input' => array( 'datetime', diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index 23722371d1..e1bf5ebeb1 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -164,10 +164,16 @@ class DateType extends AbstractType return $options['widget'] !== 'single_text'; }; - $emptyValueFilter = function (Options $options, $emptyValue) { + $emptyValue = $emptyValueDefault = function (Options $options) { + return $options['required'] ? null : ''; + }; + + $emptyValueFilter = function (Options $options, $emptyValue) use ($emptyValueDefault) { if (is_array($emptyValue)) { + $default = $emptyValueDefault($options); + return array_merge( - array('year' => null, 'month' => null, 'day' => null), + array('year' => $default, 'month' => $default, 'day' => $default), $emptyValue ); } @@ -188,7 +194,7 @@ class DateType extends AbstractType 'format' => self::DEFAULT_FORMAT, 'data_timezone' => null, 'user_timezone' => null, - 'empty_value' => null, + 'empty_value' => $emptyValue, // Don't modify \DateTime classes by reference, we treat // them like immutable value objects 'by_reference' => false, diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 0c4c65e4cc..3d28e2a714 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -134,10 +134,16 @@ class TimeType extends AbstractType return $options['widget'] !== 'single_text'; }; - $emptyValueFilter = function (Options $options, $emptyValue) { + $emptyValue = $emptyValueDefault = function (Options $options) { + return $options['required'] ? null : ''; + }; + + $emptyValueFilter = function (Options $options, $emptyValue) use ($emptyValueDefault) { if (is_array($emptyValue)) { + $default = $emptyValueDefault($options); + return array_merge( - array('hour' => null, 'minute' => null, 'second' => null), + array('hour' => $default, 'minute' => $default, 'second' => $default), $emptyValue ); } @@ -158,7 +164,7 @@ class TimeType extends AbstractType 'with_seconds' => false, 'data_timezone' => null, 'user_timezone' => null, - 'empty_value' => null, + 'empty_value' => $emptyValue, // Don't modify \DateTime classes by reference, we treat // them like immutable value objects 'by_reference' => false, diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php index 64bd4299f6..f48ed69fa2 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -241,4 +241,119 @@ class DateTimeTypeTest extends LocalizedTestCase $view = $form->createView(); $this->assertEquals('datetime', $view->getVar('type')); } + + public function testPassDefaultEmptyValueToViewIfNotRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => false, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('', $view->get('date')->get('year')->getVar('empty_value')); + $this->assertSame('', $view->get('date')->get('month')->getVar('empty_value')); + $this->assertSame('', $view->get('date')->get('day')->getVar('empty_value')); + $this->assertSame('', $view->get('time')->get('hour')->getVar('empty_value')); + $this->assertSame('', $view->get('time')->get('minute')->getVar('empty_value')); + $this->assertSame('', $view->get('time')->get('second')->getVar('empty_value')); + } + + public function testPassNoEmptyValueToViewIfRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => true, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertNull($view->get('date')->get('year')->getVar('empty_value')); + $this->assertNull($view->get('date')->get('month')->getVar('empty_value')); + $this->assertNull($view->get('date')->get('day')->getVar('empty_value')); + $this->assertNull($view->get('time')->get('hour')->getVar('empty_value')); + $this->assertNull($view->get('time')->get('minute')->getVar('empty_value')); + $this->assertNull($view->get('time')->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsString() + { + $form = $this->factory->create('datetime', null, array( + 'empty_value' => 'Empty', + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty', $view->get('date')->get('year')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('date')->get('month')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('date')->get('day')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('time')->get('hour')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('time')->get('minute')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('time')->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsArray() + { + $form = $this->factory->create('datetime', null, array( + 'empty_value' => array( + 'year' => 'Empty year', + 'month' => 'Empty month', + 'day' => 'Empty day', + 'hour' => 'Empty hour', + 'minute' => 'Empty minute', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view->get('date')->get('year')->getVar('empty_value')); + $this->assertSame('Empty month', $view->get('date')->get('month')->getVar('empty_value')); + $this->assertSame('Empty day', $view->get('date')->get('day')->getVar('empty_value')); + $this->assertSame('Empty hour', $view->get('time')->get('hour')->getVar('empty_value')); + $this->assertSame('Empty minute', $view->get('time')->get('minute')->getVar('empty_value')); + $this->assertSame('Empty second', $view->get('time')->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsPartialArray_addEmptyIfNotRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => false, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view->get('date')->get('year')->getVar('empty_value')); + $this->assertSame('', $view->get('date')->get('month')->getVar('empty_value')); + $this->assertSame('Empty day', $view->get('date')->get('day')->getVar('empty_value')); + $this->assertSame('Empty hour', $view->get('time')->get('hour')->getVar('empty_value')); + $this->assertSame('', $view->get('time')->get('minute')->getVar('empty_value')); + $this->assertSame('Empty second', $view->get('time')->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsPartialArray_addNullIfRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => true, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view->get('date')->get('year')->getVar('empty_value')); + $this->assertNull($view->get('date')->get('month')->getVar('empty_value')); + $this->assertSame('Empty day', $view->get('date')->get('day')->getVar('empty_value')); + $this->assertSame('Empty hour', $view->get('time')->get('hour')->getVar('empty_value')); + $this->assertNull($view->get('time')->get('minute')->getVar('empty_value')); + $this->assertSame('Empty second', $view->get('time')->get('second')->getVar('empty_value')); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php index 705a64a943..29ed44ea21 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php @@ -546,4 +546,88 @@ class DateTypeTest extends LocalizedTestCase $view = $form->createView(); $this->assertEquals('date', $view->getVar('type')); } + + public function testPassDefaultEmptyValueToViewIfNotRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => false, + )); + + $view = $form->createView(); + $this->assertSame('', $view->get('year')->getVar('empty_value')); + $this->assertSame('', $view->get('month')->getVar('empty_value')); + $this->assertSame('', $view->get('day')->getVar('empty_value')); + } + + public function testPassNoEmptyValueToViewIfRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => true, + )); + + $view = $form->createView(); + $this->assertNull($view->get('year')->getVar('empty_value')); + $this->assertNull($view->get('month')->getVar('empty_value')); + $this->assertNull($view->get('day')->getVar('empty_value')); + } + + public function testPassEmptyValueAsString() + { + $form = $this->factory->create('date', null, array( + 'empty_value' => 'Empty', + )); + + $view = $form->createView(); + $this->assertSame('Empty', $view->get('year')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('month')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('day')->getVar('empty_value')); + } + + public function testPassEmptyValueAsArray() + { + $form = $this->factory->create('date', null, array( + 'empty_value' => array( + 'year' => 'Empty year', + 'month' => 'Empty month', + 'day' => 'Empty day', + ), + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view->get('year')->getVar('empty_value')); + $this->assertSame('Empty month', $view->get('month')->getVar('empty_value')); + $this->assertSame('Empty day', $view->get('day')->getVar('empty_value')); + } + + public function testPassEmptyValueAsPartialArray_addEmptyIfNotRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => false, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + ), + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view->get('year')->getVar('empty_value')); + $this->assertSame('', $view->get('month')->getVar('empty_value')); + $this->assertSame('Empty day', $view->get('day')->getVar('empty_value')); + } + + public function testPassEmptyValueAsPartialArray_addNullIfRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => true, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + ), + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view->get('year')->getVar('empty_value')); + $this->assertNull($view->get('month')->getVar('empty_value')); + $this->assertSame('Empty day', $view->get('day')->getVar('empty_value')); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php index ad26b6281c..262e8907ed 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -416,4 +416,94 @@ class TimeTypeTest extends LocalizedTestCase $view = $form->createView(); $this->assertEquals('time', $view->getVar('type')); } + + public function testPassDefaultEmptyValueToViewIfNotRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => false, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('', $view->get('hour')->getVar('empty_value')); + $this->assertSame('', $view->get('minute')->getVar('empty_value')); + $this->assertSame('', $view->get('second')->getVar('empty_value')); + } + + public function testPassNoEmptyValueToViewIfRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => true, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertNull($view->get('hour')->getVar('empty_value')); + $this->assertNull($view->get('minute')->getVar('empty_value')); + $this->assertNull($view->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsString() + { + $form = $this->factory->create('time', null, array( + 'empty_value' => 'Empty', + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty', $view->get('hour')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('minute')->getVar('empty_value')); + $this->assertSame('Empty', $view->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsArray() + { + $form = $this->factory->create('time', null, array( + 'empty_value' => array( + 'hour' => 'Empty hour', + 'minute' => 'Empty minute', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty hour', $view->get('hour')->getVar('empty_value')); + $this->assertSame('Empty minute', $view->get('minute')->getVar('empty_value')); + $this->assertSame('Empty second', $view->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsPartialArray_addEmptyIfNotRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => false, + 'empty_value' => array( + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty hour', $view->get('hour')->getVar('empty_value')); + $this->assertSame('', $view->get('minute')->getVar('empty_value')); + $this->assertSame('Empty second', $view->get('second')->getVar('empty_value')); + } + + public function testPassEmptyValueAsPartialArray_addNullIfRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => true, + 'empty_value' => array( + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty hour', $view->get('hour')->getVar('empty_value')); + $this->assertNull($view->get('minute')->getVar('empty_value')); + $this->assertSame('Empty second', $view->get('second')->getVar('empty_value')); + } }