merged branch bschussek/issue4596 (PR #4804)

Commits
-------

e6b5595 [Form] Fixed display of empty values in DateType, TimeType and DateTimeType if they are not required
14e293f [Form] Refactored processing of the "empty_value" option in DateType

Discussion
----------

[Form] Fixed display of empty values in DateType, TimeType and DateTimeType

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #4596
Todo: -
This commit is contained in:
Fabien Potencier 2012-07-09 18:00:20 +02:00
commit 377b850272
7 changed files with 331 additions and 12 deletions

View File

@ -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

View File

@ -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',

View File

@ -69,12 +69,6 @@ class DateType extends AbstractType
$yearOptions = $monthOptions = $dayOptions = array();
if ('choice' === $options['widget']) {
if (is_array($options['empty_value'])) {
$options['empty_value'] = array_merge(array('year' => null, 'month' => null, 'day' => null), $options['empty_value']);
} else {
$options['empty_value'] = array('year' => $options['empty_value'], 'month' => $options['empty_value'], 'day' => $options['empty_value']);
}
$years = $months = $days = array();
foreach ($options['years'] as $year) {
@ -170,6 +164,27 @@ class DateType extends AbstractType
return $options['widget'] !== 'single_text';
};
$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' => $default, 'month' => $default, 'day' => $default),
$emptyValue
);
}
return array(
'year' => $emptyValue,
'month' => $emptyValue,
'day' => $emptyValue
);
};
$resolver->setDefaults(array(
'years' => range(date('Y') - 5, date('Y') + 5),
'months' => range(1, 12),
@ -179,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,
@ -192,6 +207,10 @@ class DateType extends AbstractType
'compound' => $compound,
));
$resolver->setFilters(array(
'empty_value' => $emptyValueFilter,
));
$resolver->setAllowedValues(array(
'input' => array(
'datetime',

View File

@ -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,

View File

@ -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'));
}
}

View File

@ -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'));
}
}

View File

@ -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'));
}
}