diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index f0b5ac2ac4df..2fcf2005185b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -57,16 +57,18 @@ public function buildForm(FormBuilderInterface $builder, array $options) if ('single_text' === $options['widget']) { $builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format)); - // handle seconds ignored by user's browser when with_seconds enabled - // https://codereview.chromium.org/450533009/ - if ($options['with_seconds']) { - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $e) { - $data = $e->getData(); - if ($data && preg_match('/^\d{2}:\d{2}$/', $data)) { - $e->setData($data.':00'); + $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $e) use ($options) { + $data = $e->getData(); + if ($data && preg_match('/^(?P\d{2}):(?P\d{2})(?::(?P\d{2})(?:\.\d+)?)?$/', $data, $matches)) { + if ($options['with_seconds']) { + // handle seconds ignored by user's browser when with_seconds enabled + // https://codereview.chromium.org/450533009/ + $e->setData(sprintf('%s:%s:%s', $matches['hours'], $matches['minutes'], isset($matches['seconds']) ? $matches['seconds'] : '00')); + } else { + $e->setData(sprintf('%s:%s', $matches['hours'], $matches['minutes'])); } - }); - } + } + }); } else { $hourOptions = $minuteOptions = $secondOptions = [ 'error_bubbling' => true, 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 1f0797f000db..3a911de8fe99 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -239,6 +239,54 @@ public function testSubmitWithSecondsAndBrowserOmissionSeconds() $this->assertEquals('03:04:00', $form->getViewData()); } + public function testSubmitWithoutSecondsAndBrowserAddingSeconds() + { + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_seconds' => false, + ]); + + $form->submit('03:04:00'); + + $this->assertEquals('03:04:00', $form->getData()); + $this->assertEquals('03:04', $form->getViewData()); + } + + public function testSubmitWithSecondsAndBrowserAddingMicroseconds() + { + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_seconds' => true, + ]); + + $form->submit('03:04:00.000'); + + $this->assertEquals('03:04:00', $form->getData()); + $this->assertEquals('03:04:00', $form->getViewData()); + } + + public function testSubmitWithoutSecondsAndBrowserAddingMicroseconds() + { + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_seconds' => false, + ]); + + $form->submit('03:04:00.000'); + + $this->assertEquals('03:04:00', $form->getData()); + $this->assertEquals('03:04', $form->getViewData()); + } + public function testSetDataWithoutMinutes() { $form = $this->factory->create(static::TESTED_TYPE, null, [