8000 bug #10687 [Validator] Fixed string conversion in constraint violatio… · symfony/symfony@7d7b5c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7d7b5c7

Browse files
committed
bug #10687 [Validator] Fixed string conversion in constraint violations (eagleoneraptor, webmozart)
This PR was merged into the 2.3 branch. Discussion ---------- [Validator] Fixed string conversion in constraint violations | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #10675 | License | MIT | Doc PR | - Commits ------- 32ae95b [Validator] Added more detailed inline documentation 08ea6d3 [Validator] Removed information from the violation output if the value is an array, object or resource d6a783f [Validator] Renamed valueToString() to formatValue(); added missing formatValue() calls 71897d7 [Validator] Fixed CS cea4155 [Validator] Fixed date-to-string conversion tests to match ICU 51 5aa7e6d [Validator] Added "{{ value }}" parameters where they were missing f329552 [Validator] Simplified and explained the LuhnValidator bff09f2 [Validator] Simplified IssnValidator 224e70f [Validator] Fixed and simplified IsbnValidator fd58870 [Validator] Simplified IBAN validation algorithm 97243bc [Validator] Fixed value-to-string conversion in constraint violations 75e8815 [Validator] Fix constraint violation message parameterization
2 parents 71edf38 + 32ae95b commit 7d7b5c7

Some content is hidden

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

59 files changed

+544
-277
lines changed

src/Symfony/Component/Validator/ConstraintValidator.php

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,110 @@ public function initialize(ExecutionContextInterface $context)
3232
{
3333
$this->context = $context;
3434
}
35+
36+
/**
37+
* Returns a string representation of the type of the value.
38+
*
39+
* This method should be used if you pass the type of a value as
40+
* message parameter to a constraint violation. Note that such
41+
* parameters should usually not be included in messages aimed at
42+
* non-technical people.
43+
*
44+
* @param mixed $value The value to return the type of
45+
*
46+
* @return string The type of the value
47+
*/
48+
protected function formatTypeOf($value)
49+
{
50+
return is_object($value) ? get_class($value) : gettype($value);
51+
}
52+
53+
/**
54+
* Returns a string representation of the value.
55+
*
56+
* This method returns the equivalent PHP tokens for most scalar types
57+
* (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped
58+
* in double quotes ("). Objects, arrays and resources are formatted as
59+
* "object", "array" and "resource". If the parameter $prettyDateTime
60+
* is set to true, {@link \DateTime} objects will be formatted as
61+
* RFC-3339 dates ("Y-m-d H:i:s").
62+
*
63+
* Be careful when passing message parameters to a constraint violation
64+
* that (may) contain objects, arrays or resources. These parameters
65+
* should only be displayed for technical users. Non-technical users
66+
* won't know what an "object", "array" or "resource" is and will be
67+
* confused by the violation message.
68+
*
69+
* @param mixed $value The value to format as string
70+
* @param bool $prettyDateTime Whether to format {@link \DateTime}
71+
* objects as RFC-3339 dates ("Y-m-d H:i:s")
72+
*
73+
* @return string The string representation of the passed value
74+
*/
75+
protected function formatValue($value, $prettyDateTime = false)
76+
{
77+
if ($prettyDateTime && $value instanceof \DateTime) {
78+
if (class_exists('IntlDateFormatter')) {
79+
$locale = \Locale::getDefault();
80+
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
81+
82+
return $formatter->format($value);
83+
}
84+
85+
return $value->format('Y-m-d H:i:s');
86+
}
87+
88+
if (is_object($value)) {
89+
return 'object';
90+
}
91+
92+
if (is_array($value)) {
93+
return 'array';
94+
}
95+
96+
if (is_string($value)) {
97+
return '"'.$value.'"';
98+
}
99+
100+
if (is_resource($value)) {
101+
return 'resource';
102+
}
103+
104+
if (null === $value) {
105+
return 'null';
106+
}
107+
108+
if (false === $value) {
109+
return 'false';
110+
}
111+
112+
if (true === $value) {
113+
return 'true';
114+
}
115+
116+
return (string) $value;
117+
}
118+
119+
/**
120+
* Returns a string representation of a list of values.
121+
*
122+
* Each of the values is converted to a string using
123+
* {@link formatValue()}. The values are then concatenated with commas.
124+
*
125+
* @param array $values A list of values
126+
* @param bool $prettyDateTime Whether to format {@link \DateTime}
127+
* objects as RFC-3339 dates ("Y-m-d H:i:s")
128+
*
129+
* @return string The string representation of the value list
130+
*
131+
* @see formatValue()
132+
*/
133+
protected function formatValues(array $values, $prettyDateTime = false)
134+
{
135+
foreach ($values as $key => $value) {
136+
$values[$key] = $this->formatValue($value, $prettyDateTime);
137+
}
138+
139+
return implode(', ', $values);
140+
}
35141
}

src/Symfony/Component/Validator/ConstraintViolation.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ public function __construct($message, $messageTemplate, array $messageParameters
9696
public function __toString()
9797
{
9898
if (is_object($this->root)) {
99-
$class = get_class($this->root);
99+
$class = 'Object('.get_class($this->root).')';
100100
} elseif (is_array($this->root)) {
101-
$class = "Array";
101+
$class = 'Array';
102102
} else {
103103
$class = (string) $this->root;
104104
}

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

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,41 +32,13 @@ public function validate($value, Constraint $constraint)
3232

3333
if (!$this->compareValues($value, $constraint->value)) {
3434
$this->context->addViolation($constraint->message, array(
35-
'{{ value }}' => $this->valueToString($constraint->value),
36-
'{{ compared_value }}' => $this->valueToString($constraint->value),
37-
'{{ compared_value_type }}' => $this->valueToType($constraint->value)
35+
'{{ value }}' => $this->formatValue($value, true),
36+
'{{ compared_value }}' => $this->formatValue($constraint->value, true),
37+
'{{ compared_value_type }}' => $this->formatTypeOf($constraint->value)
3838
));
3939
}
4040
}
4141

42-
/**
43-
* Returns a string representation of the type of the value.
44-
*
45-
* @param mixed $value
46-
*
47-
* @return string
48-
*/
49-
private function valueToType($value)
50-
{
51-
return is_object($value) ? get_class($value) : gettype($value);
52-
}
53-
54-
/**
55-
* Returns a string representation of the value.
56-
*
57-
* @param mixed $value
58-
*
59-
* @return string
60-
*/
61-
private function valueToString($value)
62-
{
63-
if ($value instanceof \DateTime) {
64-
return $value->format('Y-m-d H:i:s');
65-
}
66-
67-
return var_export($value, true);
68-
}
69-
7042
/**
7143
* Compares the two given values to find if their relationship is valid
7244
*

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ class BlankValidator extends ConstraintValidator
2727
public function validate($value, Constraint $constraint)
2828
{
2929
if ('' !== $value && null !== $value) {
30-
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
30+
$this->context->addViolation($constraint->message, array(
31+
'{{ value }}' => $this->formatValue($value)
32+
));
3133
}
3234
}
3335
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ public function validate($value, Constraint $constraint)
108108
}
109109

110110
if (!is_numeric($value)) {
111-
$this->context->addViolation($constraint->message);
111+
$this->context->addViolation($constraint->message, array(
112+
'{{ value }}' => $this->formatValue($value),
113+
));
112114

113115
return;
114116
}
@@ -124,6 +126,8 @@ public function validate($value, Constraint $constraint)
124126
}
125127
}
126128

127-
$this->context->addViolation($constraint->message);
129+
$this->context->addViolation($constraint->message, array(
130+
'{{ value }}' => $this->formatValue($value),
131+
));
128132
}
129133
}

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,33 @@ public function validate($value, Constraint $constraint)
5959
if ($constraint->multiple) {
6060
foreach ($value as $_value) {
6161
if (!in_array($_value, $choices, $constraint->strict)) {
62-
$this->context->addViolation($constraint->multipleMessage, array('{{ value }}' => $_value));
62+
$this->context->addViolation($constraint->multipleMessage, array(
63+
'{{ value }}' => $this->formatValue($_value),
64+
));
6365
}
6466
}
6567

6668
$count = count($value);
6769

6870
if ($constraint->min !== null && $count < $constraint->min) {
69-
$this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min), null, (int) $constraint->min);
71+
$this->context->addViolation($constraint->minMessage, array(
72+
'{{ limit }}' => $constraint->min
73+
), null, (int) $constraint->min);
7074

7175
return;
7276
}
7377

7478
if ($constraint->max !== null && $count > $constraint->max) {
75-
$this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max), null, (int) $constraint->max);
79+
$this->context->addViolation($constraint->maxMessage, array(
80+
'{{ limit }}' => $constraint->max
81+
), null, (int) $constraint->max);
7682

7783
return;
7884
}
7985
} elseif (!in_array($value, $choices, $constraint->strict)) {
80-
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
86+
$this->context->addViolation($constraint->message, array(
87+
'{{ value }}' => $this->formatValue($value)
88+
));
8189
}
8290
}
8391
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function validate($value, Constraint $constraint)
4848
}
4949
} elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) {
5050
$this->context->addViolationAt('['.$field.']', $constraint->missingFieldsMessage, array(
51-
'{{ field }}' => $field
51+
'{{ field }}' => $this->formatValue($field)
5252
), null);
5353
}
5454
}
@@ -57,7 +57,7 @@ public function validate($value, Constraint $constraint)
5757
foreach ($value as $field => $fieldValue) {
5858
if (!isset($constraint->fields[$field])) {
5959
$this->context->addViolationAt('['.$field.']', $constraint->extraFieldsMessage, array(
60-
'{{ field }}' => $field
60+
'{{ field }}' => $this->formatValue($field)
6161
), $fieldValue);
6262
}
6363
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ public function validate($value, Constraint $constraint)
4242
$countries = Intl::getRegionBundle()->getCountryNames();
4343

4444
if (!isset($countries[$value])) {
45-
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
45+
$this->context->addViolation($constraint->message, array(
46+
'{{ value }}' => $this->formatValue($value),
47+
));
4648
}
4749
}
4850
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ public function validate($value, Constraint $constraint)
4242
$currencies = Intl::getCurrencyBundle()->getCurrencyNames();
4343

4444
if (!isset($currencies[$value])) {
45-
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
45+
$this->context->addViolation($constraint->message, array(
46+
'{{ value }}' => $this->formatValue($value),
47+
));
4648
}
4749
}
4850
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ public function validate($value, Constraint $constraint)
4040
$value = (string) $value;
4141

4242
if (!preg_match(static::PATTERN, $value, $matches) || !checkdate($matches[2], $matches[3], $matches[1])) {
43-
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
43+
$this->context->addViolation($constraint->message, array(
44+
'{{ value }}' => $this->formatValue($value),
45+
));
4446
}
4547
}
4648
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ public function validate($value, Constraint $constraint)
5050
}
5151

5252
if (!$valid) {
53-
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
53+
$this->context->addViolation($constraint->message, array(
54+
'{{ value }}' => $this->formatValue($value),
55+
));
5456
}
5557
}
5658

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public function validate($value, Constraint $constraint)
3030
return;
3131
}
3232

33-
$this->context->addViolation($constraint->message);
33+
$this->context->addViolation($constraint->message, array(
34+
'{{ value }}' => $this->formatValue($value),
35+
));
3436
}
3537
}

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,17 @@ public function validate($value, Constraint $constraint)
9696
$path = $value instanceof FileObject ? $value->getPathname() : (string) $value;
9797

9898
if (!is_file($path)) {
99-
$this->context->addViolation($constraint->notFoundMessage, array('{{ file }}' => $path));
99+
$this->context->addViolation($constraint->notFoundMessage, array(
100+
'{{ file }}' => $this->formatValue($path)
101+
));
100102

101103
return;
102104
}
103105

104106
if (!is_readable($path)) {
105-
$this->context->addViolation($constraint->notReadableMessage, array('{{ file }}' => $path));
107+
$this->context->addViolation($constraint->notReadableMessage, array(
108+
'{{ file }}' => $this->formatValue($path)
109+
));
106110

107111
return;
108112
}
@@ -126,10 +130,10 @@ public function validate($value, Constraint $constraint)
126130

127131
if ($size > $limit) {
128132
$this->context->addViolation($constraint->maxSizeMessage, array(
129-
'{{ size }}' => $size,
130-
'{{ limit }}' => $limit,
131-
'{{ suffix }}' => $suffix,
132-
'{{ file }}' => $path,
133+
'{{ size }}' => $size,
134+
'{{ limit }}' => $limit,
135+
'{{ suffix }}' => $suffix,
136+
'{{ file }}' => $this->formatValue($path),
133137
));
134138

135139
return;
@@ -161,9 +165,9 @@ public function validate($value, Constraint $constraint)
161165

162166
if (false === $valid) {
163167
$this->context->addViolation($constraint->mimeTypesMessage, array(
164-
'{{ type }}' => '"'.$mime.'"',
165-
'{{ types }}' => '"'.implode('", "', $mimeTypes) .'"',
166-
'{{ file }}' => $path,
168+
'{{ type }}' => $this->formatValue($mime),
169+
'{{ types }}' => $this->formatValues($mimeTypes),
170+
'{{ file }}' => $this->formatValue($path),
167171
));
168172
}
169173
}

0 commit comments

Comments
 (0)
0