Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch '2.1'

* 2.1: (24 commits)
  forced Travis to use source to workaround their not-up-to-date Composer on PHP 5.3.3
  [Routing] removed irrelevant string cast in Route
  Fixed typo
  Make YamlFileLoader and XmlFileLoader file loading extensible
  [HttpKernel] fix typo
  Fixed singularization of "prices"
  [Form] Removed an exception that prevented valid formats from being passed, e.g. "h" for the hour, "L" for the month etc.
  [HttpKernel] fixed Client when using StreamedResponses (closes #5370)
  fixed PDO session handler for Oracle (closes #5829)
  [HttpFoundation] fixed PDO session handler for Oracle (closes #5829)
  [Locale] removed a check that is done too early (and it is done twice anyways)
  Update src/Symfony/Component/Validator/Resources/translations/validators.fa.xlf
  Adding new localized strings for farsi validation.
  [HttpFoundation] moved the HTTP protocol check from StreamedResponse to Response (closes #5937)
  [Form] Fixed forms not to be marked invalid if their children are already marked invalid
  [Form] Excluded some tests in NumberToLocalizedStringTransformerTest which fail on ICU 4.4, but work on ICU 4.8
  added missing tests from previous merge
  [Form] Fixed NumberToLocalizedStringTransformer to accept both comma and dot as decimal separator, if possible
  Fix export-ignore on Windows
  Show correct class name InputArgument in error message
  ...

Conflicts:
	.travis.yml
	src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php
  • Loading branch information...
commit 650f43fee442a3f2e7cc33016d750d2539bf4a9d 2 parents 518e80a + 47bfc61
@fabpot fabpot authored
View
2  .gitattributes
@@ -1,2 +1,2 @@
-Tests/ export-ignore
+/Tests export-ignore
phpunit.xml.dist export-ignore
View
11 Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php
@@ -109,6 +109,17 @@ public function reverseTransform($value)
$position = 0;
$formatter = $this->getNumberFormatter();
+ $groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
+ $decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
+
+ if ('.' !== $decSep && (!$this->grouping || '.' !== $groupSep)) {
+ $value = str_replace('.', $decSep, $value);
+ }
+
+ if (',' !== $decSep && (!$this->grouping || ',' !== $groupSep)) {
+ $value = str_replace(',', $decSep, $value);
+ }
+
$result = $formatter->parse($value, \NumberFormatter::TYPE_DOUBLE, $position);
if (intl_is_failure($formatter->getErrorCode())) {
View
4 Extension/Core/Type/DateTimeType.php
@@ -87,10 +87,6 @@ public function buildForm(FormBuilderInterface $builder, array $options)
throw new InvalidOptionsException('The "date_format" option must be one of the IntlDateFormatter constants (FULL, LONG, MEDIUM, SHORT) or a string representing a custom format.');
}
- if (null !== $pattern && (false === strpos($pattern, 'y') || false === strpos($pattern, 'M') || false === strpos($pattern, 'd') || false === strpos($pattern, 'H') || false === strpos($pattern, 'm'))) {
- throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M", "d", "H" and "m". Its current value is "%s".', $pattern));
- }
-
if ('single_text' === $options['widget']) {
if (self::HTML5_FORMAT === $pattern) {
$builder->addViewTransformer(new DateTimeToRfc3339Transformer(
View
39 Extension/Validator/Constraints/FormValidator.php
@@ -80,18 +80,35 @@ public function validate($form, Constraint $constraint)
}
}
} else {
- $clientDataAsString = is_scalar($form->getViewData())
- ? (string) $form->getViewData()
- : gettype($form->getViewData());
+ $childrenSynchronized = true;
- // Mark the form with an error if it is not synchronized
- $this->context->addViolation(
- $config->getOption('invalid_message'),
- array_replace(array('{{ value }}' => $clientDataAsString), $config->getOption('invalid_message_parameters')),
- $form->getViewData(),
- null,
- Form::ERR_INVALID
- );
+ foreach ($form as $child) {
+ if (!$child->isSynchronized()) {
+ $childrenSynchronized = false;
+ break;
+ }
+ }
+
+ // Mark the form with an error if it is not synchronized BUT all
+ // of its children are synchronized. If any child is not
+ // synchronized, an error is displayed there already and showing
+ // a second error in its parent form is pointless, or worse, may
+ // lead to duplicate errors if error bubbling is enabled on the
+ // child.
+ // See also https://github.com/symfony/symfony/issues/4359
+ if ($childrenSynchronized) {
+ $clientDataAsString = is_scalar($form->getViewData())
+ ? (string) $form->getViewData()
+ : gettype($form->getViewData());
+
+ $this->context->addViolation(
+ $config->getOption('invalid_message'),
+ array_replace(array('{{ value }}' => $clientDataAsString), $config->getOption('invalid_message_parameters')),
+ $form->getViewData(),
+ null,
+ Form::ERR_INVALID
+ );
+ }
}
// Mark the form with an error if it contains extra fields
View
114 Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
@@ -86,12 +86,126 @@ public function testReverseTransformWithGrouping()
{
$transformer = new NumberToLocalizedStringTransformer(null, true);
+ // completely valid format
$this->assertEquals(1234.5, $transformer->reverseTransform('1.234,5'));
$this->assertEquals(12345.912, $transformer->reverseTransform('12.345,912'));
+ // omit group separator
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(12345.912, $transformer->reverseTransform('12345,912'));
}
+ public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot()
+ {
+ if ($this->isLowerThanIcuVersion('4.5')) {
+ $this->markTestSkipped('Please upgrade ICU version to 4.5+');
+ }
+
+ \Locale::setDefault('fr');
+ $transformer = new NumberToLocalizedStringTransformer(null, true);
+
+ // completely valid format
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5'));
+ // accept dots
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5'));
+ // omit group separator
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
+ */
+ public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot()
+ {
+ if ($this->isLowerThanIcuVersion('4.5')) {
+ $this->markTestSkipped('Please upgrade ICU version to 4.5+');
+ }
+
+ $transformer = new NumberToLocalizedStringTransformer(null, true);
+
+ $transformer->reverseTransform('1.234.5');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
+ */
+ public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot_noGroupSep()
+ {
+ if ($this->isLowerThanIcuVersion('4.5')) {
+ $this->markTestSkipped('Please upgrade ICU version to 4.5+');
+ }
+
+ $transformer = new NumberToLocalizedStringTransformer(null, true);
+
+ $transformer->reverseTransform('1234.5');
+ }
+
+ public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed()
+ {
+ \Locale::setDefault('fr');
+ $transformer = new NumberToLocalizedStringTransformer();
+
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
+ }
+
+ public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma()
+ {
+ if ($this->isLowerThanIcuVersion('4.5')) {
+ $this->markTestSkipped('Please upgrade ICU version to 4.5+');
+ }
+
+ \Locale::setDefault('ak');
+ $transformer = new NumberToLocalizedStringTransformer(null, true);
+
+ // completely valid format
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5'));
+ // accept commas
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5'));
+ // omit group separator
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
+ */
+ public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma()
+ {
+ if ($this->isLowerThanIcuVersion('4.5')) {
+ $this->markTestSkipped('Please upgrade ICU version to 4.5+');
+ }
+
+ \Locale::setDefault('en');
+ $transformer = new NumberToLocalizedStringTransformer(null, true);
+
+ $transformer->reverseTransform('1,234,5');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
+ */
+ public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma_noGroupSep()
+ {
+ if ($this->isLowerThanIcuVersion('4.5')) {
+ $this->markTestSkipped('Please upgrade ICU version to 4.5+');
+ }
+
+ \Locale::setDefault('en');
+ $transformer = new NumberToLocalizedStringTransformer(null, true);
+
+ $transformer->reverseTransform('1234,5');
+ }
+
+ public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGroupingUsed()
+ {
+ \Locale::setDefault('en');
+ $transformer = new NumberToLocalizedStringTransformer();
+
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
+ $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
+ }
+
/**
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
View
31 Tests/Extension/Validator/Constraints/FormValidatorTest.php
@@ -250,6 +250,37 @@ function () { throw new TransformationFailedException(); }
$this->validator->validate($form, new Form());
}
+ // https://github.com/symfony/symfony/issues/4359
+ public function testDontMarkInvalidIfAnyChildIsNotSynchronized()
+ {
+ $context = $this->getExecutionContext();
+ $object = $this->getMock('\stdClass');
+
+ $failingTransformer = new CallbackTransformer(
+ function ($data) { return $data; },
+ function () { throw new TransformationFailedException(); }
+ );
+
+ $form = $this->getBuilder('name', '\stdClass')
+ ->setData($object)
+ ->addViewTransformer($failingTransformer)
+ ->setCompound(true)
+ ->setDataMapper($this->getDataMapper())
+ ->add(
+ $this->getBuilder('child')
+ ->addViewTransformer($failingTransformer)
+ )
+ ->getForm();
+
+ // Launch transformer
+ $form->bind(array('child' => 'foo'));
+
+ $this->validator->initialize($context);
+ $this->validator->validate($form, new Form());
+
+ $this->assertCount(0, $context->getViolations());
+ }
+
public function testHandleCallbackValidationGroups()
{
$context = $this->getExecutionContext();
View
7 Tests/Util/FormUtilTest.php
@@ -25,8 +25,9 @@ public function singularifyProvider()
array('funguses', array('fungus', 'funguse', 'fungusis')),
array('fungi', 'fungus'),
array('axes', array('ax', 'axe', 'axis')),
- array('appendices', array('appendex', 'appendix')),
- array('indices', array('index', 'indix')),
+ array('appendices', array('appendex', 'appendix', 'appendice')),
+ array('indices', array('index', 'indix', 'indice')),
+ array('prices', array('prex', 'prix', 'price')),
array('indexes', 'index'),
array('children', 'child'),
array('men', 'man'),
@@ -45,7 +46,7 @@ public function singularifyProvider()
array('foci', 'focus'),
array('focuses', array('focus', 'focuse', 'focusis')),
array('oases', array('oas', 'oase', 'oasis')),
- array('matrices', array('matrex', 'matrix')),
+ array('matrices', array('matrex', 'matrix', 'matrice')),
array('matrixes', 'matrix'),
array('bureaus', 'bureau'),
array('bureaux', 'bureau'),
View
4 Util/FormUtil.php
@@ -55,8 +55,8 @@ class FormUtil
// oxen (ox)
array('nexo', 4, false, false, 'ox'),
- // indices (index), appendices (appendix)
- array('seci', 4, false, true, array('ex', 'ix')),
+ // indices (index), appendices (appendix), prices (price)
+ array('seci', 4, false, true, array('ex', 'ix', 'ice')),
// babies (baby)
array('sei', 3, false, true, 'y'),
Please sign in to comment.
Something went wrong with that request. Please try again.