diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index 9d50e9432d..ea1b091348 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -66,7 +66,9 @@ class DateType extends AbstractType $pattern )); } else { - $yearOptions = $monthOptions = $dayOptions = array(); + $yearOptions = $monthOptions = $dayOptions = array( + 'error_bubbling' => true, + ); $formatter = new \IntlDateFormatter( \Locale::getDefault(), @@ -80,18 +82,12 @@ class DateType extends AbstractType if ('choice' === $options['widget']) { // Only pass a subset of the options to children - $yearOptions = array( - 'choices' => $this->formatTimestamps($formatter, '/y+/', $this->listYears($options['years'])), - 'empty_value' => $options['empty_value']['year'], - ); - $monthOptions = array( - 'choices' => $this->formatTimestamps($formatter, '/M+/', $this->listMonths($options['months'])), - 'empty_value' => $options['empty_value']['month'], - ); - $dayOptions = array( - 'choices' => $this->formatTimestamps($formatter, '/d+/', $this->listDays($options['days'])), - 'empty_value' => $options['empty_value']['day'], - ); + $yearOptions['choices'] = $this->formatTimestamps($formatter, '/y+/', $this->listYears($options['years'])); + $yearOptions['empty_value'] = $options['empty_value']['year']; + $monthOptions['choices'] = $this->formatTimestamps($formatter, '/M+/', $this->listMonths($options['months'])); + $monthOptions['empty_value'] = $options['empty_value']['month']; + $dayOptions['choices'] = $this->formatTimestamps($formatter, '/d+/', $this->listDays($options['days'])); + $dayOptions['empty_value'] = $options['empty_value']['day']; } // Append generic carry-along options diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 84e5a35988..99617ddf40 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -39,7 +39,9 @@ class TimeType extends AbstractType if ('single_text' === $options['widget']) { $builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format)); } else { - $hourOptions = $minuteOptions = $secondOptions = array(); + $hourOptions = $minuteOptions = $secondOptions = array( + 'error_bubbling' => true, + ); if ('choice' === $options['widget']) { $hours = $minutes = array(); @@ -52,14 +54,10 @@ class TimeType extends AbstractType } // Only pass a subset of the options to children - $hourOptions = array( - 'choices' => $hours, - 'empty_value' => $options['empty_value']['hour'], - ); - $minuteOptions = array( - 'choices' => $minutes, - 'empty_value' => $options['empty_value']['minute'], - ); + $hourOptions['choices'] = $hours; + $hourOptions['empty_value'] = $options['empty_value']['hour']; + $minuteOptions['choices'] = $minutes; + $minuteOptions['empty_value'] = $options['empty_value']['minute']; if ($options['with_seconds']) { $seconds = array(); @@ -68,10 +66,8 @@ class TimeType extends AbstractType $seconds[$second] = str_pad($second, 2, '0', STR_PAD_LEFT); } - $secondOptions = array( - 'choices' => $seconds, - 'empty_value' => $options['empty_value']['second'], - ); + $secondOptions['choices'] = $seconds; + $secondOptions['empty_value'] = $options['empty_value']['second']; } // Append generic carry-along options 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 d184b9fdca..cd99217597 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Form\FormError; class DateTypeTest extends LocalizedTestCase { @@ -686,4 +687,57 @@ class DateTypeTest extends LocalizedTestCase $view = $form->createView(); $this->assertNull($view->getVar('type')); } + + public function provideCompoundWidgets() + { + return array( + array('text'), + array('choice'), + ); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testYearErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('date', null, array( + 'widget' => $widget, + )); + $form->get('year')->addError($error); + + $this->assertSame(array(), $form->get('year')->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testMonthErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('date', null, array( + 'widget' => $widget, + )); + $form->get('month')->addError($error); + + $this->assertSame(array(), $form->get('month')->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testDayErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('date', null, array( + 'widget' => $widget, + )); + $form->get('day')->addError($error); + + $this->assertSame(array(), $form->get('day')->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } } 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 912323e7df..8e6118123c 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Form\FormError; class TimeTypeTest extends LocalizedTestCase { @@ -506,4 +507,58 @@ class TimeTypeTest extends LocalizedTestCase $this->assertNull($view->get('minute')->getVar('empty_value')); $this->assertSame('Empty second', $view->get('second')->getVar('empty_value')); } + + public function provideCompoundWidgets() + { + return array( + array('text'), + array('choice'), + ); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testHourErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('time', null, array( + 'widget' => $widget, + )); + $form->get('hour')->addError($error); + + $this->assertSame(array(), $form->get('hour')->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testMinuteErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('time', null, array( + 'widget' => $widget, + )); + $form->get('minute')->addError($error); + + $this->assertSame(array(), $form->get('minute')->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testSecondErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('time', null, array( + 'widget' => $widget, + 'with_seconds' => true, + )); + $form->get('second')->addError($error); + + $this->assertSame(array(), $form->get('second')->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } }