Skip to content

Commit

Permalink
Merge pull request #245 from jojo1981/feature/ref-resolver
Browse files Browse the repository at this point in the history
#240 Fix RefResolver and make it compatible with draft-04
  • Loading branch information
bighappyface committed Apr 14, 2016
2 parents 61a95a1 + e265e9f commit 50901a4
Show file tree
Hide file tree
Showing 19 changed files with 1,294 additions and 579 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,12 @@ See [json-schema](http://json-schema.org/) for more details.
<?php

// Get the schema and data as objects
$retriever = new JsonSchema\Uri\UriRetriever;
$schema = $retriever->retrieve('file://' . realpath('schema.json'));
$data = json_decode(file_get_contents('data.json'));

// If you use $ref or if you are unsure, resolve those references here
// This modifies the $schema object
$refResolver = new JsonSchema\RefResolver($retriever);
$refResolver->resolve($schema, 'file://' . __DIR__);
$refResolver = new JsonSchema\RefResolver(new JsonSchema\Uri\UriRetriever(), new JsonSchema\Uri\UriResolver());
$schema = $refResolver->resolve('file://' . realpath('schema.json'));

$data = json_decode(file_get_contents('data.json'));

// Validate
$validator = new JsonSchema\Validator();
Expand Down
13 changes: 2 additions & 11 deletions bin/validate-json
Original file line number Diff line number Diff line change
Expand Up @@ -200,22 +200,14 @@ try {
echo $urlSchema . "\n";
exit();
}

$schema = $retriever->retrieve($urlSchema);
if ($schema === null) {
echo "Error loading JSON schema file\n";
echo $urlSchema . "\n";
showJsonError();
exit(2);
}
} catch (Exception $e) {
echo "Error loading JSON schema file\n";
echo $urlSchema . "\n";
echo $e->getMessage() . "\n";
exit(2);
}
$refResolver = new JsonSchema\RefResolver($retriever);
$refResolver->resolve($schema, $urlSchema);
$refResolver = new JsonSchema\RefResolver($retriever, $resolver);
$schema = $refResolver->resolve($urlSchema);

if (isset($arOptions['--dump-schema'])) {
$options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0;
Expand All @@ -242,4 +234,3 @@ try {
echo "Error code: " . $e->getCode() . "\n";
exit(24);
}
?>
4 changes: 2 additions & 2 deletions src/JsonSchema/Constraints/ObjectConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ protected function getProperty($element, $property, $fallback = null)
*/
protected function validateMinMaxConstraint($element, $objectDefinition, $path) {
// Verify minimum number of properties
if (isset($objectDefinition->minProperties)) {
if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) {
if (count(get_object_vars($element)) < $objectDefinition->minProperties) {
$this->addError($path, "Must contain a minimum of " . $objectDefinition->minProperties . " properties", 'minProperties', array('minProperties' => $objectDefinition->minProperties,));
}
}
// Verify maximum number of properties
if (isset($objectDefinition->maxProperties)) {
if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) {
if (count(get_object_vars($element)) > $objectDefinition->maxProperties) {
$this->addError($path, "Must contain no more than " . $objectDefinition->maxProperties . " properties", 'maxProperties', array('maxProperties' => $objectDefinition->maxProperties,));
}
Expand Down
118 changes: 118 additions & 0 deletions src/JsonSchema/Entity/JsonPointer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Entity;

/**
* @package JsonSchema\Entity
* @author Joost Nijhuis <[email protected]>
*/
class JsonPointer
{
/** @var string */
private $filename;

/** @var string[] */
private $propertyPaths = array();

/**
* @param string $value
* @throws \InvalidArgumentException when $value is not a string
*/
public function __construct($value)
{
if (!is_string($value)) {
throw new \InvalidArgumentException('Ref value must be a string');
}

$splitRef = explode('#', $value, 2);
$this->filename = $splitRef[0];
if (array_key_exists(1, $splitRef)) {
$this->propertyPaths = $this->decodePropertyPaths($splitRef[1]);
}
}

/**
* @param string $propertyPathString
* @return string[]
*/
private function decodePropertyPaths($propertyPathString)
{
$paths = array();
foreach (explode('/', trim($propertyPathString, '/')) as $path) {
$path = $this->decodePath($path);
if (is_string($path) && '' !== $path) {
$paths[] = $path;
}
}

return $paths;
}

/**
* @return array
*/
private function encodePropertyPaths()
{
return array_map(
array($this, 'encodePath'),
$this->getPropertyPaths()
);
}

/**
* @param string $path
* @return string
*/
private function decodePath($path)
{
return strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%'));
}

/**
* @param string $path
* @return string
*/
private function encodePath($path)
{
return strtr($path, array('/' => '~1', '~' => '~0', '%' => '%25'));
}

/**
* @return string
*/
public function getFilename()
{
return $this->filename;
}

/**
* @return string[]
*/
public function getPropertyPaths()
{
return $this->propertyPaths;
}

/**
* @return string
*/
public function getPropertyPathAsString()
{
return rtrim('#/' . implode('/', $this->encodePropertyPaths()), '/');
}

/**
* @return string
*/
public function __toString()
{
return $this->getFilename() . $this->getPropertyPathAsString();
}
}
18 changes: 18 additions & 0 deletions src/JsonSchema/Exception/UnresolvableJsonPointerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Exception;

/**
* @package JsonSchema\Exception
* @author Joost Nijhuis <[email protected]>
*/
class UnresolvableJsonPointerException extends \InvalidArgumentException
{
}
147 changes: 147 additions & 0 deletions src/JsonSchema/Iterator/ObjectIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Iterator;

/**
* @package JsonSchema\Iterator
* @author Joost Nijhuis <[email protected]>
*/
class ObjectIterator implements \Iterator, \Countable
{
/** @var object */
private $object;

/** @var int */
private $position = 0;

/** @var array */
private $data = array();

/** @var bool */
private $initialized = false;

/**
* @param object $object
*/
public function __construct($object)
{
$this->object = $object;
}

/**
* {@inheritdoc}
*/
public function current()
{
$this->initialize();

return $this->data[$this->position];
}

/**
* {@inheritdoc}
*/
public function next()
{
$this->initialize();
$this->position++;
}

/**
* {@inheritdoc}
*/
public function key()
{
$this->initialize();

return $this->position;
}

/**
* {@inheritdoc}
*/
public function valid()
{
$this->initialize();

return isset($this->data[$this->position]);
}

/**
* {@inheritdoc}
*/
public function rewind()
{
$this->initialize();
$this->position = 0;
}

/**
* {@inheritdoc}
*/
public function count()
{
$this->initialize();

return count($this->data);
}

/**
* Initializer
*/
private function initialize()
{
if (!$this->initialized) {
$this->data = $this->buildDataFromObject($this->object);
$this->initialized = true;
}
}

/**
* @param object $object
* @return array
*/
private function buildDataFromObject($object)
{
$result = array();

$stack = new \SplStack();
$stack->push($object);

while (!$stack->isEmpty()) {

$current = $stack->pop();
if (is_object($current)) {
array_push($result, $current);
}

foreach ($this->getDataFromItem($current) as $propertyName => $propertyValue) {
if (is_object($propertyValue) || is_array($propertyValue)) {
$stack->push($propertyValue);
}
}
}

return $result;
}

/**
* @param object|array $item
* @return array
*/
private function getDataFromItem($item)
{
if (!is_object($item) && !is_array($item)) {
return array();
}

return is_object($item) ? get_object_vars($item) : $item;
}
}
Loading

0 comments on commit 50901a4

Please sign in to comment.