8000 [Validator] Added error codes to all constraints with multiple error … · symfony/symfony@7a47fa2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7a47fa2

Browse files
committed
[Validator] Added error codes to all constraints with multiple error causes
1 parent 69deac3 commit 7a47fa2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+903
-222
lines changed

src/Symfony/Component/Form/Extension/Validator/Constraints/Form.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,20 @@
1818
*/
1919
class Form extends Constraint
2020
{
21+
const ERROR_NOT_SYNCHRONIZED = 1;
22+
const ERROR_NO_SUCH_FIELD = 2;
23+
2124
/**
22-
* Violation code marking an invalid form.
25+
* @deprecated Deprecated since Symfony 2.6, to be removed in 3.0. Use
26+
* {@self ERROR_NOT_SYNCHRONIZED} instead.
2327
*/
2428
const ERR_INVALID = 1;
2529

30+
protected static $errorNames = array(
31+
self::ERROR_NOT_SYNCHRONIZED => 'ERROR_NOT_SYNCHRONIZED',
32+
self::ERROR_NO_SUCH_FIELD => 'ERROR_NO_SUCH_FIELD',
33+
);
34+
2635
/**
2736
* {@inheritdoc}
2837
*/

src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\Validator\Constraints;
1313

1414
use Symfony\Component\Form\FormInterface;
15+
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
1516
use Symfony\Component\Validator\Constraint;
1617
use Symfony\Component\Validator\ConstraintValidator;
1718
use Symfony\Component\Validator\Context\ExecutionContextInterface;
@@ -22,6 +23,22 @@
2223
*/
2324
class FormValidator extends ConstraintValidator
2425
{
26+
/**
27+
* @var ServerParams
28+
*/
29+
private $serverParams;
30+
31+
/**
32+
* Creates a validator with the given server parameters.
33+
*
34+
* @param ServerParams $params The server parameters. Default
35+
* parameters are created if null.
36+
*/
37+
public function __construct(ServerParams $params = null)
38+
{
39+
$this->serverParams = $params ?: new ServerParams();
40+
}
41+
2542
/**
2643
* {@inheritdoc}
2744
*/
@@ -102,7 +119,7 @@ public function validate($form, Constraint $constraint)
102119
$this->buildViolation($config->getOption('invalid_message'))
103120
->setParameters(array_replace(array('{{ value }}' => $clientDataAsString), $config->getOption('invalid_message_parameters')))
104121
->setInvalidValue($form->getViewData())
105-
->setCode(Form::ERR_INVALID)
122+
->setCode(Form::ERROR_NOT_SYNCHRONIZED)
106123
->addViolation();
107124
}
108125
}
@@ -112,8 +129,32 @@ public function validate($form, Constraint $constraint)
112129
$this->buildViolation($config->getOption('extra_fields_message'))
113130
->setParameter('{{ extra_fields }}', implode('", "', array_keys($form->getExtraData())))
114131
->setInvalidValue($form->getExtraData())
132+
->setCode(Form::ERROR_NO_SUCH_FIELD)
115133
->addViolation();
116134
}
135+
136+
// Mark the form with an error if the uploaded size was too large
137+
$length = $this->serverParams->getContentLength();
138+
139+
if ($form->isRoot() && null !== $length) {
140+
$max = $this->serverParams->getPostMaxSize();
141+
142+
if (!empty($max) && $length > $max) {
143+
if ($this->context instanceof ExecutionContextInterface) {
144+
$this->context->buildViolation($config->getOption('post_max_size_message'))
145+
->setParameter('{{ max }}', $this->serverParams->getNormalizedIniPostMaxSize())
146+
->setInvalidValue($length)
147+
->addViolation();
148+
} else {
149+
// 2.4 API
150+
$this->context->addViolation(
151+
$config->getOption('post_max_size_message'),
152+
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize()),
153+
$length
154+
);
155+
}
156+
}
157+
}
117158
}
118159

119160
/**

src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function validateForm(FormEvent $event)
6666
foreach ($violations as $violation) {
6767
// Allow the "invalid" constraint to be put onto
6868
// non-synchronized forms
69-
$allowNonSynchronized = Form::ERR_INVALID === $violation->getCode();
69+
$allowNonSynchronized = Form::ERROR_NOT_SYNCHRONIZED === $violation->getCode();
7070

7171
$this->violationMapper->mapViolation($violation, $form, $allowNonSynchronized);
7272
}

src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ function () { throw new TransformationFailedException(); }
229229
->setParameter('{{ value }}', 'foo')
230230
->setParameter('{{ foo }}', 'bar')
231231
->setInvalidValue('foo')
232-
->setCode(Form::ERR_INVALID)
232+
->setCode(Form::ERROR_NOT_SYNCHRONIZED)
233233
-> 10000 assertRaised();
234234
}
235235

@@ -263,7 +263,7 @@ function () { throw new TransformationFailedException(); }
263263
->setParameter('{{ value }}', 'foo')
264264
->setParameter('{{ foo }}', 'bar')
265265
->setInvalidValue('foo')
266-
->setCode(Form::ERR_INVALID)
266+
->setCode(Form::ERROR_NOT_SYNCHRONIZED)
267267
->assertRaised();
268268
}
269269

@@ -296,7 +296,7 @@ function () { throw new TransformationFailedException(); }
296296
$this->buildViolation('invalid_message_key')
297297
->setParameter('{{ value }}', 'foo')
298298
->setInvalidValue('foo')
299-
->setCode(Form::ERR_INVALID)
299+
->setCode(Form::ERROR_NOT_SYNCHRONIZED)
300300
->assertRaised();
301301
}
302302

@@ -549,9 +549,11 @@ public function testViolationIfExtraData()
549549

550550
$this->validator->validate($form, new Form());
551551

552-
$this->assertViolation('Extra!', array(
553-
'{{ extra_fields }}' => 'foo',
554-
), 'property.path', array('foo' => 'bar'));
552+
$this->buildViolation('Extra!')
553+
->setParameter('{{ extra_fields }}', 'foo')
554+
->setInvalidValue(array('foo' => 'bar'))
555+
->setCode(Form::ERROR_NO_SUCH_FIELD)
556+
->assertRaised();
555557
}
556558

557559
public function testNoViolationIfAllowExtraData()
@@ -576,6 +578,69 @@ public function testNoViolationIfAllowExtraData()
576578
$this->validator->validate($form, new Form());
577579
}
578580

581+
/**
582+
* @dataProvider getPostMaxSizeFixtures
583+
*/
584+
public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, array $params = array())
585+
{
586+
$this->serverParams->expects($this->once())
587+
->method('getContentLength')
588+
->will($this->returnValue($contentLength));
589+
$this->serverParams->expects($this->any())
590+
->method('getNormalizedIniPostMaxSize')
591+
->will($this->returnValue($iniMax));
592+
593+
$options = array('post_max_size_message' => 'Max {{ max }}!');
594+
$form = $this->getBuilder('name', null, $options)->getForm();
595+
596+
$this->validator->validate($form, new Form());
597+
598+
$violations = array();
599+
600+
for ($i = 0; $i < $nbViolation; ++$i) {
601+
$violations[] = $this->createViolation($options['post_max_size_message'], $params, 'property.path', $contentLength);
602+
}
603+
604+
$this->assertViolations($violations);
605+
}
606+
607+
public function getPostMaxSizeFixtures()
608+
{
609+
return array(
610+
array(pow(1024, 3) + 1, '1G', 1, array('{{ max }}' => '1G')),
611+
array(pow(1024, 3), '1G', 0),
612+
array(pow(1024, 2) + 1, '1M', 1, array('{{ max }}' => '1M')),
613< 10000 span class="diff-text-marker">+
array(pow(1024, 2), '1M', 0),
614+
array(1024 + 1, '1K', 1, array('{{ max }}' => '1K')),
615+
array(1024, '1K', 0),
616+
array(null, '1K', 0),
617+
array(1024, '', 0),
618+
array(1024, 0, 0),
619+
);
620+
}
621+
622+
public function testNoViolationIfNotRoot()
623+
{
624+
$this->serverParams->expects($this->once())
625+
->method('getContentLength')
626+
->will($this->returnValue(1025));
627+
$this->serverParams->expects($this->never())
628+
->method('getNormalizedIniPostMaxSize');
629+
630+
$parent = $this->getBuilder()
631+
->setCompound(true)
632+
->setDataMapper($this->getDataMapper())
633+
->getForm();
634+
$form = $this->getForm();
635+
$parent->add($form);
636+
637+
$this->expectNoValidate();
638+
639+
$this->validator->validate($form, new Form());
640+
641+
$this->assertNoViolation();
642+
}
643+
579644
/**
580645
* Access has to be public, as this method is called via callback array
581646
* in {@link testValidateFormDataCanHandleCallbackValidationGroups()}

src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function testMapViolation()
109109

110110
public function testMapViolationAllowsNonSyncIfInvalid()
111111
{
112-
$violation = $this->getConstraintViolation(Form::ERR_INVALID);
112+
$violation = $this->getConstraintViolation(Form::ERROR_NOT_SYNCHRONIZED);
113113
$form = $this->getForm('street');
114114

115115
$this->validator->expects($this->once())

src/Symfony/Component/Validator/Constraint.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Validator;
1313

1414
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
15+
use Symfony\Component\Validator\Exception\InvalidArgumentException;
1516
use Symfony\Component\Validator\Exception\InvalidOptionsException;
1617
use Symfony\Component\Validator\Exception\MissingOptionsException;
1718

@@ -51,10 +52,32 @@ abstract class Constraint
5152
const PROPERTY_CONSTRAINT = 'property';
5253

5354
/**
54-
* Domain-specific data attached to a constraint
55-
* @var mixed
55+
* Maps error codes to the names of their constants
56+
* @var array
5657
*/
57-
public $payload;
58+
protected static $errorNames = array();
59+
60+
/**
61+
* Returns the name of the given error code.
62+
97AE *
63+
* @param int $errorCode The error code
64+
*
65+
* @return string The name of the error code
66+
*
67+
* @throws InvalidArgumentException If the error code does not exist
68+
*/
69+
public static function getErrorName($errorCode)
70+
{
71+
if (!isset(static::$errorNames[$errorCode])) {
72+
throw new InvalidArgumentException(sprintf(
73+
'The error code "%s" does not exist for constraint of type "%s".',
74+
$errorCode,
75+
get_called_class()
76+
));
77+
}
78+
79+
return static::$errorNames[$errorCode];
80+
}
5881

5982
/**
6083
* Initializes the constraint with options.

src/Symfony/Component/Validator/Constraints/CardScheme.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,18 @@
2020
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
2121
*
2222
* @author Tim Nagel <t.nagel@infinite.net.au>
23+
* @author Bernhard Schussek <bschussek@gmail.com>
2324
*/
2425
class CardScheme extends Constraint
2526
{
27+
const ERROR_NOT_NUMERIC = 1;
28+
const ERROR_INVALID_FORMAT = 2;
29+
30+
protected static $errorNames = array(
31+
self::ERROR_NOT_NUMERIC => 'ERROR_NOT_NUMERIC',
32+
self::ERROR_INVALID_FORMAT => 'ERROR_INVALID_FORMAT',
33+
);
34+
2635
public $message = 'Unsupported card type or invalid card number.';
2736
public $schemes;
2837

src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public function validate($value, Constraint $constraint)
117117
if (!is_numeric($value)) {
118118
$this->buildViolation($constraint->message)
119119
->setParameter('{{ value }}', $this->formatValue($value))
120+
->setCode(CardScheme::ERROR_NOT_NUMERIC)
120121
->addViolation();
121122

122123
return;
@@ -135,6 +136,7 @@ public function validate($value, Constraint $constraint)
135136

136137
$this->buildViolation($constraint->message)
137138
->setParameter('{{ value }}', $this->formatValue($value))
139+
->setCode(CardScheme::ERROR_INVALID_FORMAT)
138140
->addViolation();
139141
}
140142
}

src/Symfony/Component/Validator/Constraints/Choice.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323
*/
2424
class Choice extends Constraint
2525
{
26+
const ERROR_NO_SUCH_CHOICE = 1;
27+
const ERROR_TOO_FEW = 2;
28+
const ERROR_TOO_MANY = 3;
29+
30+
protected static $errorNames = array(
31+
self::ERROR_NO_SUCH_CHOICE => 'ERROR_NO_SUCH_CHOICE',
32+
self::ERROR_TOO_FEW => 'ERROR_TOO_FEW',
33+
self::ERROR_TOO_MANY => 'ERROR_TOO_MANY',
34+
);
35+
2636
public $choices;
2737
public $callback;
2838
public $multiple = false;

src/Symfony/Component/Validator/Constraints/ChoiceValidator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public function validate($value, Constraint $constraint)
6565
if (!in_array($_value, $choices, $constraint->strict)) {
6666
$this->buildViolation($constraint->multipleMessage)
6767
->setParameter('{{ value }}', $this->formatValue($_value))
68+
->setCode(Choice::ERROR_NO_SUCH_CHOICE)
6869
->setInvalidValue($_value)
6970
->addViolation();
7071

@@ -78,6 +79,7 @@ public function validate($value, Constraint $constraint)
7879
$this->buildViolation($constraint->minMessage)
7980
->setParameter('{{ limit }}', $constraint->min)
8081
->setPlural((int) $constraint->min)
82+
->setCode(Choice::ERROR_TOO_FEW)
8183
->addViolation();
8284

8385
return;
@@ -87,13 +89,15 @@ public function validate($value, Constraint $constraint)
8789
$this->buildViolation($constraint->maxMessage)
8890
->setParameter('{{ limit }}', $constraint->max)
8991
->setPlural((int) $constraint->max)
92+
->setCode(Choice::ERROR_TOO_MANY)
9093
->addViolation();
9194

9295
return;
9396
}
9497
} elseif (!in_array($value, $choices, $constraint->strict)) {
9598
$this->buildViolation($constraint->message)
9699
->setParameter('{{ value }}', $this->formatValue($value))
100+
->setCode(Choice::ERROR_NO_SUCH_CHOICE)
97101
->addViolation();
98102
}
99103
}

src/Symfony/Component/Validator/Constraints/Collection.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Component\Validator\Constraints;
1313

14-
use Symfony\Component\Validator\Constraint;
1514
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1615

1716
/**
@@ -24,6 +23,14 @@
2423
*/
2524
class Collection extends Composite
2625
{
26+
const ERROR_MISSING_FIELD = 1;
27+
const ERROR_NO_SUCH_FIELD = 2;
28+
29+
protected static $errorNames = array(
30+
self::ERROR_MISSING_FIELD => 'ERROR_MISSING_FIELD',
31+
self::ERROR_NO_SUCH_FIELD => 'ERROR_NO_SUCH_FIELD',
32+
);
33+
2734
public $fields = array();
2835
public $allowExtraFields = false;
2936
public $allowMissingFields = false;

src/Symfony/Component/Validator/Constraints/CollectionValidator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public function validate($value, Constraint $constraint)
7373
->atPath('['.$field.']')
7474
->setParameter('{{ field }}', $this->formatValue($field))
7575
->setInvalidValue(null)
76+
->setCode(Collection::ERROR_MISSING_FIELD)
7677
->addViolation();
7778
}
7879
}
@@ -84,6 +85,7 @@ public function validate($value, Constraint $constraint)
8485
->atPath('['.$field.']')
8586
->setParameter('{{ field }}', $this->formatValue($field))
8687
->setInvalidValue($fieldValue)
88+
->setCode(Collection::ERROR_NO_SUCH_FIELD)
8789
->addViolation();
8890
}
8991
}

0 commit comments

Comments
 (0)
0