Skip to content

Commit 18715e5

Browse files
committed
Don't coerce already-valid types (fixes jsonrainbow#379)
1 parent c7460a1 commit 18715e5

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

src/JsonSchema/Constraints/TypeConstraint.php

+12-7
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,23 @@ public function check(&$value = null, $schema = null, JsonPointer $path = null,
4444
{
4545
$type = isset($schema->type) ? $schema->type : null;
4646
$isValid = false;
47+
$coerce = $this->factory->getConfig(self::CHECK_MODE_COERCE_TYPES);
4748
$wording = array();
4849

4950
if (is_array($type)) {
50-
$this->validateTypesArray($value, $type, $wording, $isValid, $path);
51+
$this->validateTypesArray($value, $type, $wording, $isValid, $path, false);
52+
if (!$isValid && $coerce) {
53+
$this->validateTypesArray($value, $type, $wording, $isValid, $path, true);
54+
}
5155
} elseif (is_object($type)) {
5256
$this->checkUndefined($value, $type, $path);
5357

5458
return;
5559
} else {
56-
$isValid = $this->validateType($value, $type);
60+
$isValid = $this->validateType($value, $type, false);
61+
if (!$isValid && $coerce) {
62+
$isValid = $this->validateType($value, $type, true);
63+
}
5764
}
5865

5966
if ($isValid === false) {
@@ -79,7 +86,7 @@ public function check(&$value = null, $schema = null, JsonPointer $path = null,
7986
* @param bool $isValid The current validation value
8087
* @param $path
8188
*/
82-
protected function validateTypesArray(&$value, array $type, &$validTypesWording, &$isValid, $path)
89+
protected function validateTypesArray(&$value, array $type, &$validTypesWording, &$isValid, $path, $coerce = false)
8390
{
8491
foreach ($type as $tp) {
8592
// already valid, so no need to waste cycles looping over everything
@@ -103,7 +110,7 @@ protected function validateTypesArray(&$value, array $type, &$validTypesWording,
103110
$this->validateTypeNameWording($tp);
104111
$validTypesWording[] = self::$wording[$tp];
105112
if (!$isValid) {
106-
$isValid = $this->validateType($value, $tp);
113+
$isValid = $this->validateType($value, $tp, $coerce);
107114
}
108115
}
109116
}
@@ -162,7 +169,7 @@ protected function validateTypeNameWording($type)
162169
*
163170
* @return bool
164171
*/
165-
protected function validateType(&$value, $type)
172+
protected function validateType(&$value, $type, $coerce = false)
166173
{
167174
//mostly the case for inline schema
168175
if (!$type) {
@@ -181,8 +188,6 @@ protected function validateType(&$value, $type)
181188
return $this->getTypeCheck()->isArray($value);
182189
}
183190

184-
$coerce = $this->factory->getConfig(Constraint::CHECK_MODE_COERCE_TYPES);
185-
186191
if ('integer' === $type) {
187192
if ($coerce) {
188193
$value = $this->toInteger($value);

tests/Constraints/CoerciveTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public function testValidCoerceCases($input, $schema, $errors = array())
6767
$this->assertTrue(gettype($value->multitype1) == 'boolean');
6868
$this->assertTrue(gettype($value->multitype2) == 'double');
6969
$this->assertTrue(gettype($value->multitype3) == 'integer');
70+
$this->assertTrue(gettype($value->multitype4) == 'string');
7071

7172
$this->assertTrue($value->number === 1.5);
7273
$this->assertTrue($value->integer === 1);
@@ -134,6 +135,7 @@ public function getValidCoerceTests()
134135
"multitype1": "false",
135136
"multitype2": "1.2",
136137
"multitype3": "7",
138+
"multitype4": "45",
137139
"arrayOfIntegers":["-1","0","1"],
138140
"tupleTyping":["1","2.2","true"],
139141
"any1": 2.6,
@@ -163,6 +165,7 @@ public function getValidCoerceTests()
163165
"multitype1": {"type":["boolean","integer","number"]},
164166
"multitype2": {"type":["boolean","integer","number"]},
165167
"multitype3": {"type":["boolean","integer","number"]},
168+
"multitype4": {"type":["boolean","integer","string"]},
166169
"arrayOfIntegers":{
167170
"items":{
168171
"type":"integer"

0 commit comments

Comments
 (0)