Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline references broken #301

Closed
thewilkybarkid opened this issue Aug 23, 2016 · 5 comments
Closed

Inline references broken #301

thewilkybarkid opened this issue Aug 23, 2016 · 5 comments

Comments

@thewilkybarkid
Copy link
Contributor

When passing a schema object, rather than a reference to a schema as the README now suggests, #277 now causes inline references to break.

Failing test case:

<?php

namespace JsonSchema\Tests;

use JsonSchema\Validator;

class ValidatorTest extends \PHPUnit_Framework_TestCase
{
    /** @var Validator */
    private $validator;

    /**
     * @before
     */
    final protected function setUpValidator()
    {
        $this->validator = new Validator();
    }

    /**
     * @dataProvider schemaProvider
     */
    public function testValidatesSchema(array $data, $schema)
    {
        $this->validator->check((object) $data, $schema);
    }

    public function schemaProvider()
    {
        $schema = realpath(__DIR__.'/fixtures/json-schema-draft-04.json');

        return array(
            'reference to schema' => array(array('foo' => 'bar'), (object) array('$ref' => 'file://'.$schema)),
            'decoded schema' => array(array('foo' => 'bar'), json_decode(file_get_contents($schema))),
        );
    }
}

causes:

JsonSchema\Tests\ValidatorTest::testValidatesSchema with data set "decoded schema" (array('bar'), stdClass Object (...))
JsonSchema\Exception\ResourceNotFoundException: file_get_contents(): Filename cannot be empty

/path/to/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php:38
/path/to/json-schema/src/JsonSchema/Uri/UriRetriever.php:173
/path/to/json-schema/src/JsonSchema/Uri/UriRetriever.php:146
/path/to/json-schema/src/JsonSchema/SchemaStorage.php:48
/path/to/json-schema/src/JsonSchema/SchemaStorage.php:67
/path/to/json-schema/src/JsonSchema/SchemaStorage.php:76
/path/to/json-schema/src/JsonSchema/SchemaStorage.php:102
/path/to/json-schema/src/JsonSchema/Constraints/Constraint.php:234
/path/to/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php:130
/path/to/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php:38
/path/to/json-schema/src/JsonSchema/Constraints/Constraint.php:202
/path/to/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php:66
/path/to/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php:41
/path/to/json-schema/src/JsonSchema/Constraints/Constraint.php:234
/path/to/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php:30
/path/to/json-schema/src/JsonSchema/Validator.php:37
/path/to/json-schema/tests/ValidatorTest.php:25
@psafarov
Copy link
Contributor

psafarov commented Aug 28, 2016

@thewilkybarkid I'll try to explain how it works now. Before we had to invoke RefResolver to resolve any schema with references, but now we have 2 options: we can pass schema path to Validator and all references are resolved automatically or if we have loaded schema we should add it to SchemaStorage and pass SchemaStorage to Validator

<?php
$schemaStorage = new SchemaStorage;
$schemaStorage->addSchema('file://schemaId', $schema);
$validator = new Validator(Validator::CHECK_MODE_NORMAL, $schemaStorage);

You should do it because all local references get converted into remote ones (its done by SchemaStorage and simplifies validation process), if you pass path to schema - Validator will call SchemaStorage, otherwise you should call it explicitly

@j-gao
Copy link

j-gao commented Oct 26, 2016

I was tring to use \JsonSchema\SchemaStorage:
($schema_filepath is the path to my JSON schema)

$schemaStorage = new \JsonSchema\SchemaStorage;
$schemaStorage->addSchema($schema_filepath, json_encode(file_get_contents($schema_filepath)));
$validator = new \JsonSchema\Validator(\JsonSchema\Validator::CHECK_MODE_NORMAL, $schemaStorage);

but it leads to error:
Argument 1 passed to JsonSchema\Constraints\Constraint::__construct() must be an instance of JsonSchema\Constraints\Factory, integer given, called in ...

I also tried to use JsonSchema\Constraints\Factory:

$schemaStorage = new \JsonSchema\SchemaStorage;
$factory = new \JsonSchema\Constraints\Factory($schemaStorage);
$schemaStorage->addSchema($schema_filepath, json_encode(file_get_contents($schema_filepath)));
$validator = new \JsonSchema\Validator(\JsonSchema\Constraints\Constraint::CHECK_MODE_NORMAL, $factory);

but there's still the same error. I'm not sure what's the proper way to do it.

@shmax
Copy link
Collaborator

shmax commented Oct 27, 2016

@jgao1 The error is telling you exactly what you're doing wrong. The \JsonSchema\Validator constructor now takes a single argument of type \JsonSchema\Constraints\Factory.

https://github.com/justinrainbow/json-schema/blob/master/src/JsonSchema/Constraints/Constraint.php#L40

You want to do something like this:

$schemaStorage = new \JsonSchema\SchemaStorage;
$factory = new \JsonSchema\Constraints\Factory($schemaStorage);
$schemaStorage->addSchema($schema_filepath, json_encode(file_get_contents($schema_filepath)));
$validator = new \JsonSchema\Validator($factory);

@j-gao
Copy link

j-gao commented Oct 27, 2016

@shmax Thanks for your reply! I tried your suggested way but still got the same JsonSchema\Exception\ResourceNotFoundException: file_get_contents(): Filename cannot be empty error as OP.
The solution worked for me at last was to change

$jsonValidator->check($jsonToValidateObject, $jsonSchemaObject);

to

$jsonValidator->check($jsonToValidateObject, (object)['$ref' => 'file://mySchema']);

Without doing this, although "$jsonSchemaObject is mutated to normalize the references (to file://mySchema#/definitions/integerData, etc)" after $schemaStorage->addSchema('file://mySchema', $jsonSchemaObject) as said in the README, it won't be recognized during $jsonValidator->check(). Unless we feed it into check() using (object)['$ref' => 'file://mySchema'].

@bighappyface
Copy link
Collaborator

bighappyface commented Oct 27, 2016

Resolved by #326

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants