Skip to content

Commit 6400012

Browse files
committed
Allow the schema to be an associative array (jsonrainbow#389)
* Allow the schema to be an associative array Implements jsonrainbow#388. * Use json_decode(json_encode()) for array -> object cast * Skip exception check on PHP versions < 5.5.0 * Skip test on HHVM, as it's happy to encode resources
1 parent c53c87b commit 6400012

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

src/JsonSchema/Constraints/BaseConstraint.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace JsonSchema\Constraints;
1111

1212
use JsonSchema\Entity\JsonPointer;
13+
use JsonSchema\Exception\InvalidArgumentException;
1314
use JsonSchema\Exception\ValidationException;
1415

1516
/**
@@ -81,4 +82,25 @@ public function reset()
8182
{
8283
$this->errors = array();
8384
}
85+
86+
/**
87+
* Recursively cast an associative array to an object
88+
*
89+
* @param array $array
90+
*
91+
* @return object
92+
*/
93+
public static function arrayToObjectRecursive($array)
94+
{
95+
$json = json_encode($array);
96+
if (json_last_error() !== \JSON_ERROR_NONE) {
97+
$message = 'Unable to encode schema array as JSON';
98+
if (version_compare(phpversion(), '5.5.0', '>=')) {
99+
$message .= ': ' . json_last_error_msg();
100+
}
101+
throw new InvalidArgumentException($message);
102+
}
103+
104+
return json_decode($json);
105+
}
84106
}

src/JsonSchema/Validator.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ class Validator extends BaseConstraint
3737
*/
3838
public function validate(&$value, $schema = null, $checkMode = null)
3939
{
40+
// reset errors prior to validation
41+
$this->reset();
42+
43+
// make sure $schema is an object
44+
if (is_array($schema)) {
45+
$schema = self::arrayToObjectRecursive($schema);
46+
}
47+
48+
// set checkMode
4049
$initialCheckMode = $this->factory->getConfig();
4150
if ($checkMode !== null) {
4251
$this->factory->setConfig($checkMode);

tests/ValidatorTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace JsonSchema\Tests;
4+
5+
use JsonSchema\Constraints\Constraint;
6+
use JsonSchema\Validator;
7+
8+
class ValidatorTest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function testValidateWithAssocSchema()
11+
{
12+
$schema = json_decode('{"properties":{"propertyOne":{"type":"array","items":[{"type":"string"}]}}}', true);
13+
$data = json_decode('{"propertyOne":[42]}', true);
14+
15+
$validator = new Validator();
16+
$validator->validate($data, $schema);
17+
18+
$this->assertFalse($validator->isValid(), 'Validation succeeded, but should have failed.');
19+
}
20+
21+
public function testBadAssocSchemaInput()
22+
{
23+
if (version_compare(phpversion(), '5.5.0', '<')) {
24+
$this->markTestSkipped('PHP versions < 5.5.0 trigger an error on json_encode issues');
25+
}
26+
if (defined('HHVM_VERSION')) {
27+
$this->markTestSkipped('HHVM has no problem with encoding resources');
28+
}
29+
$schema = array('propertyOne' => fopen('php://stdout', 'w'));
30+
$data = json_decode('{"propertyOne":[42]}', true);
31+
32+
$validator = new Validator();
33+
34+
$this->setExpectedException('\JsonSchema\Exception\InvalidArgumentException');
35+
$validator->validate($data, $schema);
36+
}
37+
38+
public function testCheck()
39+
{
40+
$schema = json_decode('{"type":"string"}');
41+
$data = json_decode('42');
42+
43+
$validator = new Validator();
44+
$validator->check($data, $schema);
45+
46+
$this->assertFalse($validator->isValid(), 'Validation succeeded, but should have failed.');
47+
}
48+
49+
public function testCoerce()
50+
{
51+
$schema = json_decode('{"type":"integer"}');
52+
$data = json_decode('"42"');
53+
54+
$validator = new Validator();
55+
$validator->coerce($data, $schema);
56+
57+
$this->assertTrue($validator->isValid(), 'Validation failed, but should have succeeded.');
58+
}
59+
}

0 commit comments

Comments
 (0)