Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 53 additions & 12 deletions src/JsonSchema/Constraints/Constraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

namespace JsonSchema\Constraints;

use JsonSchema\Uri\Retrievers\FileGetContents;
use JsonSchema\Uri\Retrievers\UriRetrieverInterface;
use JsonSchema\Validator;
use JsonSchema\Exception\InvalidSchemaMediaTypeException;
use JsonSchema\Exception\JsonDecodingException;

/**
* The Base Constraints, all Validators should extend this class
*
Expand All @@ -18,18 +24,29 @@
abstract class Constraint implements ConstraintInterface
{
protected $checkMode = self::CHECK_MODE_NORMAL;
protected $uriRetriever;
protected $errors = array();
protected $inlineSchemaProperty = '$schema';

const CHECK_MODE_NORMAL = 1;
const CHECK_MODE_TYPE_CAST = 2;

/**
* @param int $checkMode
* @param int $checkMode
* @param UriRetrieverInterface $uriRetriever
*/
public function __construct($checkMode = self::CHECK_MODE_NORMAL, UriRetrieverInterface $uriRetriever = null)
{
$this->checkMode = $checkMode;
$this->uriRetriever = $uriRetriever;
}

/**
* @param UriRetrieverInterface $uriRetriever
*/
public function __construct($checkMode = self::CHECK_MODE_NORMAL)
public function setUriRetriever(UriRetrieverInterface $uriRetriever)
{
$this->checkMode = $checkMode;
$this->uriRetriever = $uriRetriever;
}

/**
Expand Down Expand Up @@ -111,7 +128,7 @@ protected function incrementPath($path, $i)
*/
protected function checkArray($value, $schema = null, $path = null, $i = null)
{
$validator = new Collection($this->checkMode);
$validator = new Collection($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -128,7 +145,7 @@ protected function checkArray($value, $schema = null, $path = null, $i = null)
*/
protected function checkObject($value, $schema = null, $path = null, $i = null, $patternProperties = null)
{
$validator = new Object($this->checkMode);
$validator = new Object($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i, $patternProperties);

$this->addErrors($validator->getErrors());
Expand All @@ -144,7 +161,7 @@ protected function checkObject($value, $schema = null, $path = null, $i = null,
*/
protected function checkType($value, $schema = null, $path = null, $i = null)
{
$validator = new Type($this->checkMode);
$validator = new Type($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -160,7 +177,7 @@ protected function checkType($value, $schema = null, $path = null, $i = null)
*/
protected function checkUndefined($value, $schema = null, $path = null, $i = null)
{
$validator = new Undefined($this->checkMode);
$validator = new Undefined($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -176,7 +193,7 @@ protected function checkUndefined($value, $schema = null, $path = null, $i = nul
*/
protected function checkString($value, $schema = null, $path = null, $i = null)
{
$validator = new String($this->checkMode);
$validator = new String($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -192,7 +209,7 @@ protected function checkString($value, $schema = null, $path = null, $i = null)
*/
protected function checkNumber($value, $schema = null, $path = null, $i = null)
{
$validator = new Number($this->checkMode);
$validator = new Number($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -208,17 +225,41 @@ protected function checkNumber($value, $schema = null, $path = null, $i = null)
*/
protected function checkEnum($value, $schema = null, $path = null, $i = null)
{
$validator = new Enum($this->checkMode);
$validator = new Enum($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}

protected function checkFormat($value, $schema = null, $path = null, $i = null)
{
$validator = new Format($this->checkMode);
$validator = new Format($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}
}

/**
* @param string $uri JSON Schema URI
* @return string JSON Schema contents
* @throws InvalidSchemaMediaType for invalid media types
*/
protected function retrieveUri($uri)
{
if (null === $this->uriRetriever) {
$this->setUriRetriever(new FileGetContents);
}
$contents = $this->uriRetriever->retrieve($uri);
if (Validator::SCHEMA_MEDIA_TYPE !== $this->uriRetriever->getContentType()) {
throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE));
}
$jsonSchema = json_decode($contents);
if (JSON_ERROR_NONE < $error = json_last_error()) {
throw new JsonDecodingException($error);
}

// TODO validate using schema)
$jsonSchema->id = $uri;
return $jsonSchema;
}
}
2 changes: 1 addition & 1 deletion src/JsonSchema/Constraints/Undefined.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ protected function validateUri($schemaUri = null, $schema, $path = null, $i = nu

if ($resolver->isValid($schemaUri)) {
$schemaId = property_exists($schema, 'id') ? $schema->id : null;
return Validator::retrieveUri($resolver->resolve($schemaUri, $schemaId));
return $this->retrieveUri($resolver->resolve($schemaUri, $schemaId));
}
}
}
59 changes: 59 additions & 0 deletions src/JsonSchema/Uri/Retrievers/PredefinedArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace JsonSchema\Uri\Retrievers;

use JsonSchema\Uri\Retrievers\UriRetrieverInterface;
use JsonSchema\Exception\ResourceNotFoundException;

/**
* URI retrieved based on a predefined array of schemas
*
* @example
*
* $retriever = new PredefinedArray(array(
* 'http://acme.com/schemas/person#' => '{ ... }',
* 'http://acme.com/schemas/address#' => '{ ... }',
* ))
*
* $schema = $retriever->retrieve('http://acme.com/schemas/person#');
*/
class PredefinedArray implements UriRetrieverInterface
{
private $schemas;
private $contentType;

/**
* Constructor
*
* @param array $schemas
* @param string $contentType
*/
public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE)
{
$this->schemas = $schemas;
$this->contentType = $contentType;
}

/**
* {@inheritDoc}
*/
public function retrieve($uri)
{
if (!array_key_exists($uri, $this->schemas)) {
throw new ResourceNotFoundException(sprintf(
'The JSON schema "%s" was not found.',
$uri
));
}

return $this->schemas[$uri];
}

/**
* {@inheritDoc}
*/
public function getContentType()
{
return $this->contentType;
}
}
40 changes: 2 additions & 38 deletions src/JsonSchema/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
class Validator extends Constraint
{
const SCHEMA_MEDIA_TYPE = 'application/schema+json';

private static $uriRetriever;

/**
* Validates the given data against the schema and returns an object containing the results
Expand All @@ -39,43 +37,9 @@ class Validator extends Constraint
*/
public function check($value, $schema = null, $path = null, $i = null)
{
$validator = new Schema($this->checkMode);
$validator = new Schema($this->checkMode, $this->uriRetriever);
$validator->check($value, $schema);

$this->addErrors($validator->getErrors());
}

/**
* Sets the URI retriever the validator will use. FileGetContents by default
*
* @param UriRetrieverInterface $retriever
*/
public static function setUriRetriever(UriRetrieverInterface $retriever)
{
self::$uriRetriever = $retriever;
}

/**
* @param string $uri JSON Schema URI
* @return string JSON Schema contents
* @throws InvalidSchemaMediaType for invalid media types
*/
public static function retrieveUri($uri)
{
if (null === self::$uriRetriever) {
self::setUriRetriever(new Uri\Retrievers\FileGetContents);
}
$contents = self::$uriRetriever->retrieve($uri);
if (self::SCHEMA_MEDIA_TYPE !== self::$uriRetriever->getContentType()) {
throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', self::SCHEMA_MEDIA_TYPE));
}
$jsonSchema = json_decode($contents);
if (JSON_ERROR_NONE < $error = json_last_error()) {
throw new JsonDecodingException($error);
}

// TODO validate using schema)
$jsonSchema->id = $uri;
return $jsonSchema;
}
}
}
40 changes: 40 additions & 0 deletions tests/JsonSchema/Tests/Uri/Retrievers/PredefinedArrayTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace JsonSchema\Tests\Uri\Retrievers;

use JsonSchema\Uri\Retrievers\PredefinedArray;

class PredefinedArrayTest extends \PHPUnit_Framework_TestCase
{
private $retriever;

public function setUp()
{
$this->retriever = new PredefinedArray(
array(
'http://acme.com/schemas/person#' => 'THE_PERSON_SCHEMA',
'http://acme.com/schemas/address#' => 'THE_ADDRESS_SCHEMA',
),
'THE_CONTENT_TYPE'
);
}

public function testRetrieve()
{
$this->assertEquals('THE_PERSON_SCHEMA', $this->retriever->retrieve('http://acme.com/schemas/person#'));
$this->assertEquals('THE_ADDRESS_SCHEMA', $this->retriever->retrieve('http://acme.com/schemas/address#'));
}

/**
* @expectedException JsonSchema\Exception\ResourceNotFoundException
*/
public function testRetrieveNonExistsingSchema()
{
$this->retriever->retrieve('http://acme.com/schemas/plop#');
}

public function testGetContentType()
{
$this->assertEquals('THE_CONTENT_TYPE', $this->retriever->getContentType());
}
}
Loading