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

#240 Fix RefResolver and make it compatible with draft-04 #245

Merged
merged 1 commit into from
Apr 14, 2016
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
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