From f2f8b0cf0e7f6b9ed425b294e0d5dfc875076a65 Mon Sep 17 00:00:00 2001 From: Erayd Date: Sat, 11 Mar 2017 07:04:03 +1300 Subject: [PATCH] Add provided schema under a dummy / internal URI (fixes #376) In order to resolve internal $ref references within a user-provided schema, SchemaStorage needs to know about the schema. As user-supplied schemas do not have an associated URI, use a dummy / internal one instead. --- src/JsonSchema/SchemaStorage.php | 6 +++++- src/JsonSchema/Validator.php | 3 +++ tests/SchemaStorageTest.php | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/JsonSchema/SchemaStorage.php b/src/JsonSchema/SchemaStorage.php index 6450572e..fe0d1b38 100644 --- a/src/JsonSchema/SchemaStorage.php +++ b/src/JsonSchema/SchemaStorage.php @@ -3,6 +3,7 @@ namespace JsonSchema; use JsonSchema\Entity\JsonPointer; +use JsonSchema\Exception\InvalidArgumentException; use JsonSchema\Exception\UnresolvableJsonPointerException; use JsonSchema\Iterator\ObjectIterator; use JsonSchema\Uri\UriResolver; @@ -43,7 +44,10 @@ public function getUriResolver() */ public function addSchema($id, $schema = null) { - if (is_null($schema)) { + if (is_null($schema) && $id !== 'internal://provided-schema') { + // if the schema was user-provided to Validator and is still null, then assume this is + // what the user intended, as there's no way for us to retrieve anything else. User-supplied + // schemas do not have an associated URI when passed via Validator::validate(). $schema = $this->uriRetriever->retrieve($id); } $objectIterator = new ObjectIterator($schema); diff --git a/src/JsonSchema/Validator.php b/src/JsonSchema/Validator.php index e2a919bc..4deb8444 100644 --- a/src/JsonSchema/Validator.php +++ b/src/JsonSchema/Validator.php @@ -41,6 +41,9 @@ public function validate(&$value, $schema = null, $checkMode = null) $this->factory->setConfig($checkMode); } + // add provided schema to SchemaStorage with internal URI to allow internal $ref resolution + $this->factory->getSchemaStorage()->addSchema('internal://provided-schema', $schema); + $validator = $this->factory->createInstanceFor('schema'); $validator->check($value, $schema); diff --git a/tests/SchemaStorageTest.php b/tests/SchemaStorageTest.php index c3388bf4..92e1d5c3 100644 --- a/tests/SchemaStorageTest.php +++ b/tests/SchemaStorageTest.php @@ -11,6 +11,7 @@ use JsonSchema\SchemaStorage; use JsonSchema\Uri\UriRetriever; +use JsonSchema\Validator; use Prophecy\Argument; class SchemaStorageTest extends \PHPUnit_Framework_TestCase @@ -31,6 +32,15 @@ public function testResolveRef() ); } + public function testResolveTopRef() + { + $input = json_decode('{"propertyOne":"notANumber"}'); + $schema = json_decode('{"$ref":"#/definition","definition":{"properties":{"propertyOne":{"type":"number"}}}}'); + $v = new Validator(); + $v->validate($input, $schema); + $this->assertFalse($v->isValid()); + } + /** * @depends testResolveRef */