From bf9e238f753f9f26081985d77359914dbc55c14a Mon Sep 17 00:00:00 2001 From: Eric GELOEN Date: Mon, 9 Apr 2012 17:25:41 +0200 Subject: [PATCH] [Form] Add options with_minutes to DateTimeType & TimeType --- .../views/Form/form_div_layout.html.twig | 2 +- .../Resources/views/Form/time_widget.html.php | 7 +- .../Form/Extension/Core/Type/DateTimeType.php | 11 ++- .../Form/Extension/Core/Type/TimeType.php | 49 ++++++++---- .../Extension/Core/Type/DateTimeTypeTest.php | 29 +++++++ .../Extension/Core/Type/TimeTypeTest.php | 77 +++++++++++++++++++ 6 files changed, 157 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index dea4d0be3e..d7be0986a9 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -148,7 +148,7 @@ {{ block('form_widget_simple') }} {% else %}
- {{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %} + {{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}{% if with_minutes %}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %}
{% endif %} {% endspaceless %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php index 591bbf797a..62424be57e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php @@ -6,8 +6,11 @@ // There should be no spaces between the colons and the widgets, that's why // this block is written in a single PHP tag echo $view['form']->widget($form['hour'], array('attr' => array('size' => 1))); - echo ':'; - echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1))); + + if ($with_minutes) { + echo ':'; + echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1))); + } if ($with_seconds) { echo ':'; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index 8151c3e7fb..1ffc0a155f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -69,9 +69,14 @@ class DateTimeType extends AbstractType */ public function buildForm(FormBuilderInterface $builder, array $options) { - $parts = array('year', 'month', 'day', 'hour', 'minute'); + $parts = array('year', 'month', 'day', 'hour'); $dateParts = array('year', 'month', 'day'); - $timeParts = array('hour', 'minute'); + $timeParts = array('hour'); + + if ($options['with_minutes']) { + $parts[] = 'minute'; + $timeParts[] = 'minute'; + } if ($options['with_seconds']) { $parts[] = 'second'; @@ -118,6 +123,7 @@ class DateTimeType extends AbstractType 'hours', 'minutes', 'seconds', + 'with_minutes', 'with_seconds', 'empty_value', 'required', @@ -223,6 +229,7 @@ class DateTimeType extends AbstractType 'widget' => null, 'date_widget' => $dateWidget, 'time_widget' => $timeWidget, + 'with_minutes' => true, 'with_seconds' => false, // Don't modify \DateTime classes by reference, we treat // them like immutable value objects diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 8973948a2f..bc661f66b9 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -15,6 +15,7 @@ use Symfony\Component\Form\AbstractType; 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\DateTimeToStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; @@ -29,10 +30,20 @@ class TimeType extends AbstractType */ public function buildForm(FormBuilderInterface $builder, array $options) { - $parts = array('hour', 'minute'); - $format = 'H:i'; + $parts = array('hour'); + $format = 'H'; + + if ($options['with_seconds'] && !$options['with_minutes']) { + throw new InvalidConfigurationException('You can not disable minutes if you have enabled seconds.'); + } + + if ($options['with_minutes']) { + $format .= ':i'; + $parts[] = 'minute'; + } + if ($options['with_seconds']) { - $format = 'H:i:s'; + $format .= ':s'; $parts[] = 'second'; } @@ -49,15 +60,19 @@ class TimeType extends AbstractType foreach ($options['hours'] as $hour) { $hours[$hour] = str_pad($hour, 2, '0', STR_PAD_LEFT); } - foreach ($options['minutes'] as $minute) { - $minutes[$minute] = str_pad($minute, 2, '0', STR_PAD_LEFT); - } // Only pass a subset of the options to children $hourOptions['choices'] = $hours; $hourOptions['empty_value'] = $options['empty_value']['hour']; - $minuteOptions['choices'] = $minutes; - $minuteOptions['empty_value'] = $options['empty_value']['minute']; + + if ($options['with_minutes']) { + foreach ($options['minutes'] as $minute) { + $minutes[$minute] = str_pad($minute, 2, '0', STR_PAD_LEFT); + } + + $minuteOptions['choices'] = $minutes; + $minuteOptions['empty_value'] = $options['empty_value']['minute']; + } if ($options['with_seconds']) { $seconds = array(); @@ -72,17 +87,23 @@ class TimeType extends AbstractType // Append generic carry-along options foreach (array('required', 'translation_domain') as $passOpt) { - $hourOptions[$passOpt] = $minuteOptions[$passOpt] = $options[$passOpt]; + $hourOptions[$passOpt] = $options[$passOpt]; + + if ($options['with_minutes']) { + $minuteOptions[$passOpt] = $options[$passOpt]; + } + if ($options['with_seconds']) { $secondOptions[$passOpt] = $options[$passOpt]; } } } - $builder - ->add('hour', $options['widget'], $hourOptions) - ->add('minute', $options['widget'], $minuteOptions) - ; + $builder->add('hour', $options['widget'], $hourOptions); + + if ($options['with_minutes']) { + $builder->add('minute', $options['widget'], $minuteOptions); + } if ($options['with_seconds']) { $builder->add('second', $options['widget'], $secondOptions); @@ -113,6 +134,7 @@ class TimeType extends AbstractType { $view->vars = array_replace($view->vars, array( 'widget' => $options['widget'], + 'with_minutes' => $options['with_minutes'], 'with_seconds' => $options['with_seconds'], )); @@ -167,6 +189,7 @@ class TimeType extends AbstractType 'seconds' => range(0, 59), 'widget' => 'choice', 'input' => 'datetime', + 'with_minutes' => true, 'with_seconds' => false, 'model_timezone' => $modelTimezone, 'view_timezone' => $viewTimezone, 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 e394315f3e..1db1850d85 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -94,6 +94,35 @@ class DateTimeTypeTest extends LocalizedTestCase $this->assertEquals($dateTime->format('U'), $form->getData()); } + public function testSubmit_withoutMinutes() + { + $form = $this->factory->create('datetime', null, array( + 'data_timezone' => 'UTC', + 'user_timezone' => 'UTC', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + 'input' => 'datetime', + 'with_minutes' => false, + )); + + $form->setData(new \DateTime('2010-06-02 03:04:05 UTC')); + + $input = array( + 'date' => array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ), + 'time' => array( + 'hour' => '3', + ), + ); + + $form->bind($input); + + $this->assertDateTimeEquals(new \DateTime('2010-06-02 03:00:00 UTC'), $form->getData()); + } + public function testSubmit_withSeconds() { $form = $this->factory->create('datetime', null, array( 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 1f51a9dc35..9b5f9ef714 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -111,6 +111,22 @@ class TimeTypeTest extends LocalizedTestCase $this->assertEquals('03:04', $form->getViewData()); } + public function testSubmit_datetimeSingleTextWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'data_timezone' => 'UTC', + 'user_timezone' => 'UTC', + 'input' => 'datetime', + 'widget' => 'single_text', + 'with_minutes' => false, + )); + + $form->bind('03'); + + $this->assertEquals(new \DateTime('1970-01-01 03:00:00 UTC'), $form->getData()); + $this->assertEquals('03', $form->getViewData()); + } + public function testSubmit_arraySingleText() { $form = $this->factory->create('time', null, array( @@ -131,6 +147,26 @@ class TimeTypeTest extends LocalizedTestCase $this->assertEquals('03:04', $form->getViewData()); } + public function testSubmit_arraySingleTextWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'data_timezone' => 'UTC', + 'user_timezone' => 'UTC', + 'input' => 'array', + 'widget' => 'single_text', + 'with_minutes' => false, + )); + + $data = array( + 'hour' => '3', + ); + + $form->bind('03'); + + $this->assertEquals($data, $form->getData()); + $this->assertEquals('03', $form->getViewData()); + } + public function testSubmit_arraySingleTextWithSeconds() { $form = $this->factory->create('time', null, array( @@ -168,6 +204,36 @@ class TimeTypeTest extends LocalizedTestCase $this->assertEquals('03:04', $form->getViewData()); } + public function testSubmit_stringSingleTextWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'data_timezone' => 'UTC', + 'user_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_minutes' => false, + )); + + $form->bind('03'); + + $this->assertEquals('03:00:00', $form->getData()); + $this->assertEquals('03', $form->getViewData()); + } + + public function testSetData_withoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'data_timezone' => 'UTC', + 'user_timezone' => 'UTC', + 'input' => 'datetime', + 'with_minutes' => false, + )); + + $form->setData(new \DateTime('03:04:05 UTC')); + + $this->assertEquals(array('hour' => 3), $form->getClientData()); + } + public function testSetData_withSeconds() { $form = $this->factory->create('time', null, array( @@ -561,4 +627,15 @@ class TimeTypeTest extends LocalizedTestCase $this->assertSame(array(), $form['second']->getErrors()); $this->assertSame(array($error), $form->getErrors()); } + + /** + * @expectedException Symfony\Component\Form\Exception\InvalidConfigurationException + */ + public function testInitializeWithSecondsAndWithoutMinutes() + { + $this->factory->create('time', null, array( + 'with_minutes' => false, + 'with_seconds' => true, + )); + } }