Merge branch '3.4' into 4.1

* 3.4:
  [Validator] Added IBAN format for Vatican City State
  filter out invalid Intl values
  [Validator] Fixed grouped composite constraints
  [Form] Filter arrays out of scalar form types
This commit is contained in:
Nicolas Grekas 2018-12-09 17:19:55 +00:00
commit c600de0715
16 changed files with 112 additions and 32 deletions

View File

@ -101,11 +101,6 @@ class CountryType extends AbstractType implements ChoiceLoaderInterface
return array();
}
// If no callable is set, values are the same as choices
if (null === $value) {
return $values;
}
return $this->loadChoiceList($value)->getChoicesForValues($values);
}

View File

@ -101,11 +101,6 @@ class CurrencyType extends AbstractType implements ChoiceLoaderInterface
return array();
}
// If no callable is set, values are the same as choices
if (null === $value) {
return $values;
}
return $this->loadChoiceList($value)->getChoicesForValues($values);
}

View File

@ -101,11 +101,6 @@ class LanguageType extends AbstractType implements ChoiceLoaderInterface
return array();
}
// If no callable is set, values are the same as choices
if (null === $value) {
return $values;
}
return $this->loadChoiceList($value)->getChoicesForValues($values);
}

View File

@ -101,11 +101,6 @@ class LocaleType extends AbstractType implements ChoiceLoaderInterface
return array();
}
// If no callable is set, values are the same as choices
if (null === $value) {
return $values;
}
return $this->loadChoiceList($value)->getChoicesForValues($values);
}

View File

@ -532,11 +532,12 @@ class Form implements \IteratorAggregate, FormInterface
$submittedData = null;
} elseif (is_scalar($submittedData)) {
$submittedData = (string) $submittedData;
} elseif ($this->config->getOption('allow_file_upload')) {
// no-op
} elseif ($this->config->getRequestHandler()->isFileUpload($submittedData)) {
} elseif (!$this->config->getOption('allow_file_upload') && $this->config->getRequestHandler()->isFileUpload($submittedData)) {
$submittedData = null;
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.');
} elseif (\is_array($submittedData) && !$this->config->getCompound() && !$this->config->hasOption('multiple')) {
$submittedData = null;
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, array given.');
}
$dispatcher = $this->config->getEventDispatcher();

View File

@ -1039,6 +1039,22 @@ class CompoundFormTest extends AbstractFormTest
$this->assertFalse($submit->isSubmitted());
}
public function testArrayTransformationFailureOnSubmit()
{
$this->form->add($this->getBuilder('foo')->setCompound(false)->getForm());
$this->form->add($this->getBuilder('bar', null, null, array('multiple' => false))->setCompound(false)->getForm());
$this->form->submit(array(
'foo' => array('foo'),
'bar' => array('bar'),
));
$this->assertNull($this->form->get('foo')->getData());
$this->assertSame('Submitted data was expected to be text or number, array given.', $this->form->get('foo')->getTransformationFailure()->getMessage());
$this->assertSame(array('bar'), $this->form->get('bar')->getData());
}
public function testFileUpload()
{
$reqHandler = new HttpFoundationRequestHandler();

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Intl\Util\IntlTestHelper;
class CountryTypeTest extends BaseTypeTest
@ -80,4 +81,14 @@ class CountryTypeTest extends BaseTypeTest
{
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
}
/**
* @group legacy
*/
public function testInvalidChoiceValuesAreDropped()
{
$type = new CountryType();
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
use Symfony\Component\Intl\Util\IntlTestHelper;
class CurrencyTypeTest extends BaseTypeTest
@ -61,4 +62,14 @@ class CurrencyTypeTest extends BaseTypeTest
{
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
}
/**
* @group legacy
*/
public function testInvalidChoiceValuesAreDropped()
{
$type = new CurrencyType();
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
use Symfony\Component\Intl\Util\IntlTestHelper;
class LanguageTypeTest extends BaseTypeTest
@ -73,4 +74,14 @@ class LanguageTypeTest extends BaseTypeTest
{
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
}
/**
* @group legacy
*/
public function testInvalidChoiceValuesAreDropped()
{
$type = new LanguageType();
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
use Symfony\Component\Form\Extension\Core\Type\LocaleType;
use Symfony\Component\Intl\Util\IntlTestHelper;
class LocaleTypeTest extends BaseTypeTest
@ -61,4 +62,14 @@ class LocaleTypeTest extends BaseTypeTest
{
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
}
/**
* @group legacy
*/
public function testInvalidChoiceValuesAreDropped()
{
$type = new LocaleType();
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
}
}

View File

@ -83,14 +83,6 @@ class UrlTypeTest extends TextTypeTest
));
}
public function testSubmitWithNonStringDataDoesNotBreakTheFixUrlProtocolListener()
{
$form = $this->factory->create(static::TESTED_TYPE);
$form->submit(array('domain.com', 'www.domain.com'));
$this->assertSame(array('domain.com', 'www.domain.com'), $form->getData());
}
public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = 'http://empty')
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(

View File

@ -220,7 +220,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
->getForm();
// Launch transformer
$form->submit(array());
$form->submit('foo');
$this->expectNoValidate();

View File

@ -129,6 +129,7 @@ class IbanValidator extends ConstraintValidator
'TN' => 'TN59\d{2}\d{3}\d{13}\d{2}', // Tunisia
'TR' => 'TR\d{2}\d{5}[\dA-Z]{1}[\dA-Z]{16}', // Turkey
'UA' => 'UA\d{2}\d{6}[\dA-Z]{19}', // Ukraine
'VA' => 'VA\d{2}\d{3}\d{15}', // Vatican City State
'VG' => 'VG\d{2}[A-Z]{4}\d{16}', // Virgin Islands, British
'WF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // Wallis and Futuna Islands
'XK' => 'XK\d{2}\d{4}\d{10}\d{2}', // Republic of Kosovo

View File

@ -156,6 +156,7 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
array('TR330006100519786457841326'), //Turkey
array('UA213223130000026007233566001'), //Ukraine
array('AE260211000000230064016'), //United Arab Emirates
array('VA59001123000012345678'), //Vatican City State
);
}
@ -274,6 +275,7 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
array('TR3300061005197864578413261'), //Turkey
array('UA21AAAA1300000260072335660012'), //Ukraine
array('AE2602110000002300640161'), //United Arab Emirates
array('VA590011230000123456781'), //Vatican City State
);
}
@ -385,6 +387,7 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
array('TR330006100519786457841327'), //Turkey
array('UA213223130000026007233566002'), //Ukraine
array('AE260211000000230064017'), //United Arab Emirates
array('VA59001123000012345671'), //Vatican City State
);
}

View File

@ -12,6 +12,10 @@
namespace Symfony\Component\Validator\Tests\Validator;
use Symfony\Component\Translation\IdentityTranslator;
use Symfony\Component\Validator\Constraints\All;
use Symfony\Component\Validator\Constraints\Collection;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Context\ExecutionContextFactory;
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
@ -95,4 +99,38 @@ class RecursiveValidatorTest extends AbstractTest
$validator->validate($entity, null, array());
}
public function testCollectionConstraintValidateAllGroupsForNestedConstraints()
{
$this->metadata->addPropertyConstraint('data', new Collection(array('fields' => array(
'one' => array(new NotBlank(array('groups' => 'one')), new Length(array('min' => 2, 'groups' => 'two'))),
'two' => array(new NotBlank(array('groups' => 'two'))),
))));
$entity = new Entity();
$entity->data = array('one' => 't', 'two' => '');
$violations = $this->validator->validate($entity, null, array('one', 'two'));
$this->assertCount(2, $violations);
$this->assertInstanceOf(Length::class, $violations->get(0)->getConstraint());
$this->assertInstanceOf(NotBlank::class, $violations->get(1)->getConstraint());
}
public function testAllConstraintValidateAllGroupsForNestedConstraints()
{
$this->metadata->addPropertyConstraint('data', new All(array('constraints' => array(
new NotBlank(array('groups' => 'one')),
new Length(array('min' => 2, 'groups' => 'two')),
))));
$entity = new Entity();
$entity->data = array('one' => 't', 'two' => '');
$violations = $this->validator->validate($entity, null, array('one', 'two'));
$this->assertCount(2, $violations);
$this->assertInstanceOf(NotBlank::class, $violations->get(0)->getConstraint());
$this->assertInstanceOf(Length::class, $violations->get(1)->getConstraint());
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Composite;
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContext;
@ -787,6 +788,10 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
if (null !== $cacheKey) {
$constraintHash = spl_object_hash($constraint);
if ($constraint instanceof Composite) {
$constraintHash .= $group;
}
if ($context->isConstraintValidated($cacheKey, $constraintHash)) {
continue;
}