diff --git a/src/JsonSchema/SchemaStorage.php b/src/JsonSchema/SchemaStorage.php index 6450572e..55d7985a 100644 --- a/src/JsonSchema/SchemaStorage.php +++ b/src/JsonSchema/SchemaStorage.php @@ -10,6 +10,8 @@ class SchemaStorage implements SchemaStorageInterface { + const INTERNAL_PROVIDED_SCHEMA_URI = 'internal://provided-schema'; + protected $uriRetriever; protected $uriResolver; protected $schemas = array(); @@ -43,7 +45,10 @@ public function getUriResolver() */ public function addSchema($id, $schema = null) { - if (is_null($schema)) { + if (is_null($schema) && $id !== self::INTERNAL_PROVIDED_SCHEMA_URI) { + // 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..9f44e512 100644 --- a/src/JsonSchema/Validator.php +++ b/src/JsonSchema/Validator.php @@ -12,6 +12,7 @@ use JsonSchema\Constraints\BaseConstraint; use JsonSchema\Constraints\Constraint; use JsonSchema\Exception\InvalidConfigException; +use JsonSchema\SchemaStorage; /** * A JsonSchema Constraint @@ -41,6 +42,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(SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI, $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 */