Skip to content

Commit af52ed9

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 e9c4506 commit af52ed9

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

src/JsonSchema/Constraints/BaseConstraint.php

+23
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
namespace JsonSchema\Constraints;
1111

1212
use JsonSchema\ConstraintError;
13+
use JsonSchema\Constraints\TypeCheck\LooseTypeCheck;
1314
use JsonSchema\Entity\JsonPointer;
15+
use JsonSchema\Exception\InvalidArgumentException;
1416
use JsonSchema\Exception\ValidationException;
1517

1618
/**
@@ -89,4 +91,25 @@ public function reset()
8991
{
9092
$this->errors = array();
9193
}
94+
95+
/**
96+
* Recursively cast an associative array to an object
97+
*
98+
* @param array $array
99+
*
100+
* @return object
101+
*/
102+
public static function arrayToObjectRecursive($array)
103+
{
104+
$json = json_encode($array);
105+
if (json_last_error() !== \JSON_ERROR_NONE) {
106+
$message = 'Unable to encode schema array as JSON';
107+
if (version_compare(phpversion(), '5.5.0', '>=')) {
108+
$message .= ': ' . json_last_error_msg();
109+
}
110+
throw new InvalidArgumentException($message);
111+
}
112+
113+
return json_decode($json);
114+
}
92115
}

src/JsonSchema/Validator.php

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public function validate(&$value, $schema = null, $checkMode = null)
4040
// reset errors prior to validation
4141
$this->reset();
4242

43+
// make sure $schema is an object
44+
if (is_array($schema)) {
45+
$schema = self::arrayToObjectRecursive($schema);
46+
}
47+
4348
// set checkMode
4449
$initialCheckMode = $this->factory->getConfig();
4550
if ($checkMode !== null) {

tests/ValidatorTest.php

+59
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)