diff options
| author | Eole <josselin.35@live.fr> | 2016-01-21 10:29:26 +0100 |
|---|---|---|
| committer | Eole <josselin.35@live.fr> | 2016-01-21 10:29:26 +0100 |
| commit | a44cc1d2e3c0f147e91a5c052ac7fd879e34e706 (patch) | |
| tree | bdd6f72e0ba732c4fcc0479d1cfcf4d0baa5885d /server/vendor/justinrainbow/json-schema | |
| parent | 35db27b0e62b4cdcb03b0d21bceb4efc769e6161 (diff) | |
Init Server Composer Components
Diffstat (limited to 'server/vendor/justinrainbow/json-schema')
33 files changed, 3136 insertions, 0 deletions
diff --git a/server/vendor/justinrainbow/json-schema/.gitattributes b/server/vendor/justinrainbow/json-schema/.gitattributes new file mode 100644 index 0000000..beeff5b --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/.gitattributes @@ -0,0 +1,5 @@ +/docs export-ignore +/tests export-ignore +.gitignore export-ignore +.travis.yml export-ignore +phpunit.dist.xml export-ignore diff --git a/server/vendor/justinrainbow/json-schema/LICENSE b/server/vendor/justinrainbow/json-schema/LICENSE new file mode 100644 index 0000000..6210e7c --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2008, Gradua Networks +Author: Bruno Prieto Reis +All rights reserved. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the Gradua Networks nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/server/vendor/justinrainbow/json-schema/README.md b/server/vendor/justinrainbow/json-schema/README.md new file mode 100644 index 0000000..3f9c58c --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/README.md @@ -0,0 +1,55 @@ +# JSON Schema for PHP + +[](https://travis-ci.org/justinrainbow/json-schema) +[](https://packagist.org/packages/justinrainbow/json-schema) +[](https://packagist.org/packages/justinrainbow/json-schema) + +A PHP Implementation for validating `JSON` Structures against a given `Schema`. + +See [json-schema](http://json-schema.org/) for more details. + +## Installation + +### Library + + $ git clone https://github.com/justinrainbow/json-schema.git + +### Dependencies + +#### [`Composer`](https://github.com/composer/composer) (*will use the Composer ClassLoader*) + + $ wget http://getcomposer.org/composer.phar + $ php composer.phar require justinrainbow/json-schema:~1.3 + +## Usage + +```php +<?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__); + +// Validate +$validator = new JsonSchema\Validator(); +$validator->check($data, $schema); + +if ($validator->isValid()) { + echo "The supplied JSON validates against the schema.\n"; +} else { + echo "JSON does not validate. Violations:\n"; + foreach ($validator->getErrors() as $error) { + echo sprintf("[%s] %s\n", $error['property'], $error['message']); + } +} +``` + +## Running the tests + + $ vendor/bin/phpunit diff --git a/server/vendor/justinrainbow/json-schema/bin/validate-json b/server/vendor/justinrainbow/json-schema/bin/validate-json new file mode 100755 index 0000000..e93d53a --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/bin/validate-json @@ -0,0 +1,245 @@ +#!/usr/bin/env php +<?php +/** + * JSON schema validator + * + * @author Christian Weiske <christian.weiske@netresearch.de> + */ + +/** + * Dead simple autoloader + * + * @param string $className Name of class to load + * + * @return void + */ +function __autoload($className) +{ + $className = ltrim($className, '\\'); + $fileName = ''; + $namespace = ''; + if ($lastNsPos = strrpos($className, '\\')) { + $namespace = substr($className, 0, $lastNsPos); + $className = substr($className, $lastNsPos + 1); + $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; + } + $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; + if (stream_resolve_include_path($fileName)) { + require_once $fileName; + } +} + +/** + * Show the json parse error that happened last + * + * @return void + */ +function showJsonError() +{ + $constants = get_defined_constants(true); + $json_errors = array(); + foreach ($constants['json'] as $name => $value) { + if (!strncmp($name, 'JSON_ERROR_', 11)) { + $json_errors[$value] = $name; + } + } + + echo 'JSON parse error: ' . $json_errors[json_last_error()] . "\n"; +} + +function getUrlFromPath($path) +{ + if (parse_url($path, PHP_URL_SCHEME) !== null) { + //already an URL + return $path; + } + if ($path{0} == '/') { + //absolute path + return 'file://' . $path; + } + + //relative path: make absolute + return 'file://' . getcwd() . '/' . $path; +} + +/** + * Take a HTTP header value and split it up into parts. + * + * @return array Key "_value" contains the main value, all others + * as given in the header value + */ +function parseHeaderValue($headerValue) +{ + if (strpos($headerValue, ';') === false) { + return array('_value' => $headerValue); + } + + $parts = explode(';', $headerValue); + $arData = array('_value' => array_shift($parts)); + foreach ($parts as $part) { + list($name, $value) = explode('=', $part); + $arData[$name] = trim($value, ' "\''); + } + return $arData; +} + + +// support running this tool from git checkout +if (is_dir(__DIR__ . '/../src/JsonSchema')) { + set_include_path(__DIR__ . '/../src' . PATH_SEPARATOR . get_include_path()); +} + +$arOptions = array(); +$arArgs = array(); +array_shift($argv);//script itself +foreach ($argv as $arg) { + if ($arg{0} == '-') { + $arOptions[$arg] = true; + } else { + $arArgs[] = $arg; + } +} + +if (count($arArgs) == 0 + || isset($arOptions['--help']) || isset($arOptions['-h']) +) { + echo <<<HLP +Validate schema +Usage: validate-json data.json + or: validate-json data.json schema.json + +Options: + --dump-schema Output full schema and exit + --dump-schema-url Output URL of schema + -h --help Show this help + +HLP; + exit(1); +} + +if (count($arArgs) == 1) { + $pathData = $arArgs[0]; + $pathSchema = null; +} else { + $pathData = $arArgs[0]; + $pathSchema = getUrlFromPath($arArgs[1]); +} + +$urlData = getUrlFromPath($pathData); + +$context = stream_context_create( + array( + 'http' => array( + 'header' => array( + 'Accept: */*', + 'Connection: Close' + ), + 'max_redirects' => 5 + ) + ) +); +$dataString = file_get_contents($pathData, false, $context); +if ($dataString == '') { + echo "Data file is not readable or empty.\n"; + exit(3); +} + +$data = json_decode($dataString); +unset($dataString); +if ($data === null) { + echo "Error loading JSON data file\n"; + showJsonError(); + exit(5); +} + +if ($pathSchema === null) { + if (isset($http_response_header)) { + array_shift($http_response_header);//HTTP/1.0 line + foreach ($http_response_header as $headerLine) { + list($hName, $hValue) = explode(':', $headerLine, 2); + $hName = strtolower($hName); + if ($hName == 'link') { + //Link: <http://example.org/schema#>; rel="describedBy" + $hParts = parseHeaderValue($hValue); + if (isset($hParts['rel']) && $hParts['rel'] == 'describedBy') { + $pathSchema = trim($hParts['_value'], ' <>'); + } + } else if ($hName == 'content-type') { + //Content-Type: application/my-media-type+json; + // profile=http://example.org/schema# + $hParts = parseHeaderValue($hValue); + if (isset($hParts['profile'])) { + $pathSchema = $hParts['profile']; + } + + } + } + } + if (is_object($data) && property_exists($data, '$schema')) { + $pathSchema = $data->{'$schema'}; + } + + //autodetect schema + if ($pathSchema === null) { + echo "JSON data must be an object and have a \$schema property.\n"; + echo "You can pass the schema file on the command line as well.\n"; + echo "Schema autodetection failed.\n"; + exit(6); + } +} +if ($pathSchema{0} == '/') { + $pathSchema = 'file://' . $pathSchema; +} + +$resolver = new JsonSchema\Uri\UriResolver(); +$retriever = new JsonSchema\Uri\UriRetriever(); +try { + $urlSchema = $resolver->resolve($pathSchema, $urlData); + + if (isset($arOptions['--dump-schema-url'])) { + 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); + +if (isset($arOptions['--dump-schema'])) { + $options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0; + echo json_encode($schema, $options) . "\n"; + exit(); +} + +try { + $validator = new JsonSchema\Validator(); + $validator->check($data, $schema); + + if ($validator->isValid()) { + echo "OK. The supplied JSON validates against the schema.\n"; + } else { + echo "JSON does not validate. Violations:\n"; + foreach ($validator->getErrors() as $error) { + echo sprintf("[%s] %s\n", $error['property'], $error['message']); + } + exit(23); + } +} catch (Exception $e) { + echo "JSON does not validate. Error:\n"; + echo $e->getMessage() . "\n"; + echo "Error code: " . $e->getCode() . "\n"; + exit(24); +} +?> diff --git a/server/vendor/justinrainbow/json-schema/composer.json b/server/vendor/justinrainbow/json-schema/composer.json new file mode 100644 index 0000000..c45891a --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/composer.json @@ -0,0 +1,58 @@ +{ + "name": "justinrainbow/json-schema", + "description": "A library to validate a json schema.", + "keywords": ["json", "schema"], + "homepage": "https://github.com/justinrainbow/json-schema", + "type": "library", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "repositories": [{ + "type": "package", + "package": { + "name": "json-schema/JSON-Schema-Test-Suite", + "version": "1.1.0", + "source": { + "url": "https://github.com/json-schema/JSON-Schema-Test-Suite", + "type": "git", + "reference": "1.1.0" + } + } + }], + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "json-schema/JSON-Schema-Test-Suite": "1.1.0", + "phpunit/phpunit": "~3.7", + "phpdocumentor/phpdocumentor": "~2" + }, + "autoload": { + "psr-4": { "JsonSchema\\": "src/JsonSchema/" } + }, + "autoload-dev": { + "psr-4": { "JsonSchema\\Tests\\": "tests/JsonSchema/Tests/" } + }, + "bin": ["bin/validate-json"], + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + } +} diff --git a/server/vendor/justinrainbow/json-schema/phpunit.xml.dist b/server/vendor/justinrainbow/json-schema/phpunit.xml.dist new file mode 100644 index 0000000..0136d8e --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/phpunit.xml.dist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + bootstrap="vendor/autoload.php" + verbose="true" +> + <testsuites> + <testsuite name="JSON Schema Test Suite"> + <directory>tests</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./src/JsonSchema/</directory> + </whitelist> + </filter> +</phpunit> diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php new file mode 100644 index 0000000..b43bace --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php @@ -0,0 +1,112 @@ +<?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\Constraints; + +/** + * The CollectionConstraint Constraints, validates an array against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class CollectionConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($value, $schema = null, $path = null, $i = null) + { + // Verify minItems + if (isset($schema->minItems) && count($value) < $schema->minItems) { + $this->addError($path, "There must be a minimum of " . $schema->minItems . " items in the array", 'minItems', array('minItems' => $schema->minItems,)); + } + + // Verify maxItems + if (isset($schema->maxItems) && count($value) > $schema->maxItems) { + $this->addError($path, "There must be a maximum of " . $schema->maxItems . " items in the array", 'maxItems', array('maxItems' => $schema->maxItems,)); + } + + // Verify uniqueItems + if (isset($schema->uniqueItems) && $schema->uniqueItems) { + $unique = $value; + if (is_array($value) && count($value)) { + $unique = array_map(function($e) { return var_export($e, true); }, $value); + } + if (count(array_unique($unique)) != count($value)) { + $this->addError($path, "There are no duplicates allowed in the array", 'uniqueItems'); + } + } + + // Verify items + if (isset($schema->items)) { + $this->validateItems($value, $schema, $path, $i); + } + } + + /** + * Validates the items + * + * @param array $value + * @param \stdClass $schema + * @param string $path + * @param string $i + */ + protected function validateItems($value, $schema = null, $path = null, $i = null) + { + if (is_object($schema->items)) { + // just one type definition for the whole array + foreach ($value as $k => $v) { + $initErrors = $this->getErrors(); + + // First check if its defined in "items" + $this->checkUndefined($v, $schema->items, $path, $k); + + // Recheck with "additionalItems" if the first test fails + if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) { + $secondErrors = $this->getErrors(); + $this->checkUndefined($v, $schema->additionalItems, $path, $k); + } + + // Reset errors if needed + if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) { + $this->errors = $secondErrors; + } else if (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) { + $this->errors = $initErrors; + } + } + } else { + // Defined item type definitions + foreach ($value as $k => $v) { + if (array_key_exists($k, $schema->items)) { + $this->checkUndefined($v, $schema->items[$k], $path, $k); + } else { + // Additional items + if (property_exists($schema, 'additionalItems')) { + if ($schema->additionalItems !== false) { + $this->checkUndefined($v, $schema->additionalItems, $path, $k); + } else { + $this->addError( + $path, 'The item ' . $i . '[' . $k . '] is not defined and the definition does not allow additional items', 'additionalItems', array('additionalItems' => $schema->additionalItems,)); + } + } else { + // Should be valid against an empty schema + $this->checkUndefined($v, new \stdClass(), $path, $k); + } + } + } + + // Treat when we have more schema definitions than values, not for empty arrays + if(count($value) > 0) { + for ($k = count($value); $k < count($schema->items); $k++) { + $this->checkUndefined(new UndefinedConstraint(), $schema->items[$k], $path, $k); + } + } + } + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php new file mode 100644 index 0000000..cb3ee80 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php @@ -0,0 +1,291 @@ +<?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\Constraints; + +use JsonSchema\Uri\UriRetriever; + +/** + * The Base Constraints, all Validators should extend this class + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +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; + + /** + * @var null|Factory + */ + private $factory; + + /** + * @param int $checkMode + * @param UriRetriever $uriRetriever + * @param Factory $factory + */ + public function __construct($checkMode = self::CHECK_MODE_NORMAL, UriRetriever $uriRetriever = null, Factory $factory = null) + { + $this->checkMode = $checkMode; + $this->uriRetriever = $uriRetriever; + $this->factory = $factory; + } + + /** + * @return UriRetriever $uriRetriever + */ + public function getUriRetriever() + { + if (is_null($this->uriRetriever)) + { + $this->setUriRetriever(new UriRetriever); + } + + return $this->uriRetriever; + } + + /** + * @return Factory + */ + public function getFactory() + { + if (!$this->factory) { + $this->factory = new Factory($this->getUriRetriever()); + } + + return $this->factory; + } + + /** + * @param UriRetriever $uriRetriever + */ + public function setUriRetriever(UriRetriever $uriRetriever) + { + $this->uriRetriever = $uriRetriever; + } + + /** + * {@inheritDoc} + */ + public function addError($path, $message, $constraint='', array $more=null) + { + $error = array( + 'property' => $path, + 'message' => $message, + 'constraint' => $constraint, + ); + + if (is_array($more) && count($more) > 0) + { + $error += $more; + } + + $this->errors[] = $error; + } + + /** + * {@inheritDoc} + */ + public function addErrors(array $errors) + { + $this->errors = array_merge($this->errors, $errors); + } + + /** + * {@inheritDoc} + */ + public function getErrors() + { + return $this->errors; + } + + /** + * {@inheritDoc} + */ + public function isValid() + { + return !$this->getErrors(); + } + + /** + * Clears any reported errors. Should be used between + * multiple validation checks. + */ + public function reset() + { + $this->errors = array(); + } + + /** + * Bubble down the path + * + * @param string $path Current path + * @param mixed $i What to append to the path + * + * @return string + */ + protected function incrementPath($path, $i) + { + if ($path !== '') { + if (is_int($i)) { + $path .= '[' . $i . ']'; + } elseif ($i == '') { + $path .= ''; + } else { + $path .= '.' . $i; + } + } else { + $path = $i; + } + + return $path; + } + + /** + * Validates an array + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + protected function checkArray($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('collection'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Validates an object + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + * @param mixed $patternProperties + */ + protected function checkObject($value, $schema = null, $path = null, $i = null, $patternProperties = null) + { + $validator = $this->getFactory()->createInstanceFor('object'); + $validator->check($value, $schema, $path, $i, $patternProperties); + + $this->addErrors($validator->getErrors()); + } + + /** + * Validates the type of a property + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + protected function checkType($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('type'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a undefined element + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + protected function checkUndefined($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('undefined'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a string element + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + protected function checkString($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('string'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a number element + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + protected function checkNumber($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('number'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * Checks a enum element + * + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + protected function checkEnum($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('enum'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + protected function checkFormat($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('format'); + $validator->check($value, $schema, $path, $i); + + $this->addErrors($validator->getErrors()); + } + + /** + * @param string $uri JSON Schema URI + * @return string JSON Schema contents + */ + protected function retrieveUri($uri) + { + if (null === $this->uriRetriever) { + $this->setUriRetriever(new UriRetriever); + } + $jsonSchema = $this->uriRetriever->retrieve($uri); + // TODO validate using schema + return $jsonSchema; + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php new file mode 100644 index 0000000..34280f4 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php @@ -0,0 +1,60 @@ +<?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\Constraints; + +/** + * The Constraints Interface + * + * @author Robert Schönthal <seroscho@googlemail.com> + */ +interface ConstraintInterface +{ + /** + * returns all collected errors + * + * @return array + */ + public function getErrors(); + + /** + * adds errors to this validator + * + * @param array $errors + */ + public function addErrors(array $errors); + + /** + * adds an error + * + * @param string $path + * @param string $message + * @param string $constraint the constraint/rule that is broken, e.g.: 'minLength' + * @param array $more more array elements to add to the error + */ + public function addError($path, $message, $constraint='', array $more=null); + + /** + * checks if the validator has not raised errors + * + * @return boolean + */ + public function isValid(); + + /** + * invokes the validation of an element + * + * @abstract + * @param mixed $value + * @param mixed $schema + * @param mixed $path + * @param mixed $i + */ + public function check($value, $schema = null, $path = null, $i = null); +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php new file mode 100644 index 0000000..df413e4 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php @@ -0,0 +1,46 @@ +<?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\Constraints; + +/** + * The EnumConstraint Constraints, validates an element against a given set of possibilities + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class EnumConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, $path = null, $i = null) + { + // Only validate enum if the attribute exists + if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) { + return; + } + + foreach ($schema->enum as $enum) { + $type = gettype($element); + if ($type === gettype($enum)) { + if ($type == "object") { + if ($element == $enum) + return; + } else { + if ($element === $enum) + return; + + } + } + } + + $this->addError($path, "Does not have a value in the enumeration " . print_r($schema->enum, true), 'enum', array('enum' => $schema->enum,)); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php new file mode 100644 index 0000000..a4570f6 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php @@ -0,0 +1,81 @@ +<?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\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; +use JsonSchema\Uri\UriRetriever; +use JsonSchema\Validator; + +/** + * Factory for centralize constraint initialization. + */ +class Factory +{ + /** + * @var UriRetriever + */ + protected $uriRetriever; + + /** + * @param UriRetriever $uriRetriever + */ + public function __construct(UriRetriever $uriRetriever = null) + { + if (!$uriRetriever) { + $uriRetriever = new UriRetriever(); + } + + $this->uriRetriever = $uriRetriever; + } + + /** + * @return UriRetriever + */ + public function getUriRetriever() + { + return $this->uriRetriever; + } + + /** + * Create a constraint instance for the given constraint name. + * + * @param string $constraintName + * @return ConstraintInterface|ObjectConstraint + * @throws InvalidArgumentException if is not possible create the constraint instance. + */ + public function createInstanceFor($constraintName) + { + switch ($constraintName) { + case 'array': + case 'collection': + return new CollectionConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'object': + return new ObjectConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'type': + return new TypeConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'undefined': + return new UndefinedConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'string': + return new StringConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'number': + return new NumberConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'enum': + return new EnumConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'format': + return new FormatConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'schema': + return new SchemaConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + case 'validator': + return new Validator(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this); + } + + throw new InvalidArgumentException('Unknown constraint ' . $constraintName); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php new file mode 100644 index 0000000..c789753 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php @@ -0,0 +1,181 @@ +<?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\Constraints; + +/** + * Validates against the "format" property + * + * @author Justin Rainbow <justin.rainbow@gmail.com> + * @link http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.23 + */ +class FormatConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, $path = null, $i = null) + { + if (!isset($schema->format)) { + return; + } + + switch ($schema->format) { + case 'date': + if (!$date = $this->validateDateTime($element, 'Y-m-d')) { + $this->addError($path, sprintf('Invalid date %s, expected format YYYY-MM-DD', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'time': + if (!$this->validateDateTime($element, 'H:i:s')) { + $this->addError($path, sprintf('Invalid time %s, expected format hh:mm:ss', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'date-time': + if (!$this->validateDateTime($element, 'Y-m-d\TH:i:s\Z') && + !$this->validateDateTime($element, 'Y-m-d\TH:i:s.u\Z') && + !$this->validateDateTime($element, 'Y-m-d\TH:i:sP') && + !$this->validateDateTime($element, 'Y-m-d\TH:i:sO') + ) { + $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'utc-millisec': + if (!$this->validateDateTime($element, 'U')) { + $this->addError($path, sprintf('Invalid time %s, expected integer of milliseconds since Epoch', json_encode($element)), 'format', array('format' => $schema->format,)); + } + break; + + case 'regex': + if (!$this->validateRegex($element)) { + $this->addError($path, 'Invalid regex format ' . $element, 'format', array('format' => $schema->format,)); + } + break; + + case 'color': + if (!$this->validateColor($element)) { + $this->addError($path, "Invalid color", 'format', array('format' => $schema->format,)); + } + break; + + case 'style': + if (!$this->validateStyle($element)) { + $this->addError($path, "Invalid style", 'format', array('format' => $schema->format,)); + } + break; + + case 'phone': + if (!$this->validatePhone($element)) { + $this->addError($path, "Invalid phone number", 'format', array('format' => $schema->format,)); + } + break; + + case 'uri': + if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) { + $this->addError($path, "Invalid URL format", 'format', array('format' => $schema->format,)); + } + break; + + case 'email': + if (null === filter_var($element, FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE)) { + $this->addError($path, "Invalid email", 'format', array('format' => $schema->format,)); + } + break; + + case 'ip-address': + case 'ipv4': + if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV4)) { + $this->addError($path, "Invalid IP address", 'format', array('format' => $schema->format,)); + } + break; + + case 'ipv6': + if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV6)) { + $this->addError($path, "Invalid IP address", 'format', array('format' => $schema->format,)); + } + break; + + case 'host-name': + case 'hostname': + if (!$this->validateHostname($element)) { + $this->addError($path, "Invalid hostname", 'format', array('format' => $schema->format,)); + } + break; + + default: + // Empty as it should be: + // The value of this keyword is called a format attribute. It MUST be a string. + // A format attribute can generally only validate a given set of instance types. + // If the type of the instance to validate is not in this set, validation for + // this format attribute and instance SHOULD succeed. + // http://json-schema.org/latest/json-schema-validation.html#anchor105 + break; + } + } + + protected function validateDateTime($datetime, $format) + { + $dt = \DateTime::createFromFormat($format, $datetime); + + if (!$dt) { + return false; + } + + if ($datetime === $dt->format($format)) { + return true; + } + + // handles the case where a non-6 digit microsecond datetime is passed + // which will fail the above string comparison because the passed + // $datetime may be '2000-05-01T12:12:12.123Z' but format() will return + // '2000-05-01T12:12:12.123000Z' + if ((strpos('u', $format) !== -1) && (intval($dt->format('u')) > 0)) { + return true; + } + + return false; + } + + protected function validateRegex($regex) + { + return false !== @preg_match('/' . $regex . '/', ''); + } + + protected function validateColor($color) + { + if (in_array(strtolower($color), array('aqua', 'black', 'blue', 'fuchsia', + 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', + 'red', 'silver', 'teal', 'white', 'yellow'))) { + return true; + } + + return preg_match('/^#([a-f0-9]{3}|[a-f0-9]{6})$/i', $color); + } + + protected function validateStyle($style) + { + $properties = explode(';', rtrim($style, ';')); + $invalidEntries = preg_grep('/^\s*[-a-z]+\s*:\s*.+$/i', $properties, PREG_GREP_INVERT); + + return empty($invalidEntries); + } + + protected function validatePhone($phone) + { + return preg_match('/^\+?(\(\d{3}\)|\d{3}) \d{3} \d{4}$/', $phone); + } + + protected function validateHostname($host) + { + return preg_match('/^[_a-z]+\.([_a-z]+\.?)+$/i', $host); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php new file mode 100644 index 0000000..0a34bdc --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php @@ -0,0 +1,83 @@ +<?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\Constraints; + +/** + * The NumberConstraint Constraints, validates an number against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class NumberConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, $path = null, $i = null) + { + // Verify minimum + if (isset($schema->exclusiveMinimum)) { + if (isset($schema->minimum)) { + if ($schema->exclusiveMinimum && $element === $schema->minimum) { + $this->addError($path, "Must have a minimum value greater than boundary value of " . $schema->minimum, 'exclusiveMinimum', array('minimum' => $schema->minimum,)); + } else if ($element < $schema->minimum) { + $this->addError($path, "Must have a minimum value of " . $schema->minimum, 'minimum', array('minimum' => $schema->minimum,)); + } + } else { + $this->addError($path, "Use of exclusiveMinimum requires presence of minimum", 'missingMinimum'); + } + } else if (isset($schema->minimum) && $element < $schema->minimum) { + $this->addError($path, "Must have a minimum value of " . $schema->minimum, 'minimum', array('minimum' => $schema->minimum,)); + } + + // Verify maximum + if (isset($schema->exclusiveMaximum)) { + if (isset($schema->maximum)) { + if ($schema->exclusiveMaximum && $element === $schema->maximum) { + $this->addError($path, "Must have a maximum value less than boundary value of " . $schema->maximum, 'exclusiveMaximum', array('maximum' => $schema->maximum,)); + } else if ($element > $schema->maximum) { + $this->addError($path, "Must have a maximum value of " . $schema->maximum, 'maximum', array('maximum' => $schema->maximum,)); + } + } else { + $this->addError($path, "Use of exclusiveMaximum requires presence of maximum", 'missingMinimum'); + } + } else if (isset($schema->maximum) && $element > $schema->maximum) { + $this->addError($path, "Must have a maximum value of " . $schema->maximum, 'maximum', array('maximum' => $schema->maximum,)); + } + + // Verify divisibleBy - Draft v3 + if (isset($schema->divisibleBy) && $this->fmod($element, $schema->divisibleBy) != 0) { + $this->addError($path, "Is not divisible by " . $schema->divisibleBy, 'divisibleBy', array('divisibleBy' => $schema->divisibleBy,)); + } + + // Verify multipleOf - Draft v4 + if (isset($schema->multipleOf) && $this->fmod($element, $schema->multipleOf) != 0) { + $this->addError($path, "Must be a multiple of " . $schema->multipleOf, 'multipleOf', array('multipleOf' => $schema->multipleOf,)); + } + + $this->checkFormat($element, $schema, $path, $i); + } + + private function fmod($number1, $number2) + { + $modulus = fmod($number1, $number2); + $precision = abs(0.0000000001); + $diff = (float)($modulus - $number2); + + if (-$precision < $diff && $diff < $precision) { + return 0.0; + } + + $decimals1 = mb_strpos($number1, ".") ? mb_strlen($number1) - mb_strpos($number1, ".") - 1 : 0; + $decimals2 = mb_strpos($number2, ".") ? mb_strlen($number2) - mb_strpos($number2, ".") - 1 : 0; + + return (float)round($modulus, max($decimals1, $decimals2)); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php new file mode 100644 index 0000000..0e5cf1b --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php @@ -0,0 +1,149 @@ +<?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\Constraints; + +/** + * The ObjectConstraint Constraints, validates an object against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class ObjectConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + function check($element, $definition = null, $path = null, $additionalProp = null, $patternProperties = null) + { + if ($element instanceof UndefinedConstraint) { + return; + } + + $matches = array(); + if ($patternProperties) { + $matches = $this->validatePatternProperties($element, $path, $patternProperties); + } + + if ($definition) { + // validate the definition properties + $this->validateDefinition($element, $definition, $path); + } + + // additional the element properties + $this->validateElement($element, $matches, $definition, $path, $additionalProp); + } + + public function validatePatternProperties($element, $path, $patternProperties) + { + $try = array('/','#','+','~','%'); + $matches = array(); + foreach ($patternProperties as $pregex => $schema) { + $delimiter = '/'; + // Choose delimiter. Necessary for patterns like ^/ , otherwise you get error + foreach ($try as $delimiter) { + if (strpos($pregex, $delimiter) === false) { // safe to use + break; + } + } + + // Validate the pattern before using it to test for matches + if (@preg_match($delimiter. $pregex . $delimiter, '') === false) { + $this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array('pregex' => $pregex,)); + continue; + } + foreach ($element as $i => $value) { + if (preg_match($delimiter . $pregex . $delimiter, $i)) { + $matches[] = $i; + $this->checkUndefined($value, $schema ? : new \stdClass(), $path, $i); + } + } + } + return $matches; + } + + /** + * Validates the element properties + * + * @param \stdClass $element Element to validate + * @param array $matches Matches from patternProperties (if any) + * @param \stdClass $objectDefinition ObjectConstraint definition + * @param string $path Path to test? + * @param mixed $additionalProp Additional properties + */ + public function validateElement($element, $matches, $objectDefinition = null, $path = null, $additionalProp = null) + { + foreach ($element as $i => $value) { + + $property = $this->getProperty($element, $i, new UndefinedConstraint()); + $definition = $this->getProperty($objectDefinition, $i); + + // no additional properties allowed + if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) { + $this->addError($path, "The property " . $i . " is not defined and the definition does not allow additional properties", 'additionalProp'); + } + + // additional properties defined + if (!in_array($i, $matches) && $additionalProp && !$definition) { + if ($additionalProp === true) { + $this->checkUndefined($value, null, $path, $i); + } else { + $this->checkUndefined($value, $additionalProp, $path, $i); + } + } + + // property requires presence of another + $require = $this->getProperty($definition, 'requires'); + if ($require && !$this->getProperty($element, $require)) { + $this->addError($path, "The presence of the property " . $i . " requires that " . $require . " also be present", 'requires'); + } + + if (!$definition) { + // normal property verification + $this->checkUndefined($value, new \stdClass(), $path, $i); + } + } + } + + /** + * Validates the definition properties + * + * @param \stdClass $element Element to validate + * @param \stdClass $objectDefinition ObjectConstraint definition + * @param string $path Path? + */ + public function validateDefinition($element, $objectDefinition = null, $path = null) + { + foreach ($objectDefinition as $i => $value) { + $property = $this->getProperty($element, $i, new UndefinedConstraint()); + $definition = $this->getProperty($objectDefinition, $i); + $this->checkUndefined($property, $definition, $path, $i); + } + } + + /** + * retrieves a property from an object or array + * + * @param mixed $element Element to validate + * @param string $property Property to retrieve + * @param mixed $fallback Default value if property is not found + * + * @return mixed + */ + protected function getProperty($element, $property, $fallback = null) + { + if (is_array($element) /*$this->checkMode == self::CHECK_MODE_TYPE_CAST*/) { + return array_key_exists($property, $element) ? $element[$property] : $fallback; + } elseif (is_object($element)) { + return property_exists($element, $property) ? $element->$property : $fallback; + } + + return $fallback; + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php new file mode 100644 index 0000000..b856a11 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php @@ -0,0 +1,37 @@ +<?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\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; + +/** + * The SchemaConstraint Constraints, validates an element against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class SchemaConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, $path = null, $i = null) + { + if ($schema !== null) { + // passed schema + $this->checkUndefined($element, $schema, '', ''); + } elseif (property_exists($element, $this->inlineSchemaProperty)) { + // inline schema + $this->checkUndefined($element, $element->{$this->inlineSchemaProperty}, '', ''); + } else { + throw new InvalidArgumentException('no schema found to verify against'); + } + } +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php new file mode 100644 index 0000000..f57f64c --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php @@ -0,0 +1,57 @@ +<?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\Constraints; + +/** + * The StringConstraint Constraints, validates an string against a given schema + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class StringConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($element, $schema = null, $path = null, $i = null) + { + // Verify maxLength + if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) { + $this->addError($path, "Must be at most " . $schema->maxLength . " characters long", 'maxLength', array( + 'maxLength' => $schema->maxLength, + )); + } + + //verify minLength + if (isset($schema->minLength) && $this->strlen($element) < $schema->minLength) { + $this->addError($path, "Must be at least " . $schema->minLength . " characters long", 'minLength', array( + 'minLength' => $schema->minLength, + )); + } + + // Verify a regex pattern + if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#', $element)) { + $this->addError($path, "Does not match the regex pattern " . $schema->pattern, 'pattern', array( + 'pattern' => $schema->pattern, + )); + } + + $this->checkFormat($element, $schema, $path, $i); + } + + private function strlen($string) + { + if (extension_loaded('mbstring')) { + return mb_strlen($string, mb_detect_encoding($string)); + } else { + return strlen($string); + } + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php new file mode 100644 index 0000000..837cfd8 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php @@ -0,0 +1,145 @@ +<?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\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; +use UnexpectedValueException as StandardUnexpectedValueException; + +/** + * The TypeConstraint Constraints, validates an element against a given type + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class TypeConstraint extends Constraint +{ + /** + * @var array|string[] type wordings for validation error messages + */ + static $wording = array( + 'integer' => 'an integer', + 'number' => 'a number', + 'boolean' => 'a boolean', + 'object' => 'an object', + 'array' => 'an array', + 'string' => 'a string', + 'null' => 'a null', + 'any' => NULL, // validation of 'any' is always true so is not needed in message wording + 0 => NULL, // validation of a false-y value is always true, so not needed as well + ); + + /** + * {@inheritDoc} + */ + public function check($value = null, $schema = null, $path = null, $i = null) + { + $type = isset($schema->type) ? $schema->type : null; + $isValid = true; + + if (is_array($type)) { + // @TODO refactor + $validatedOneType = false; + $errors = array(); + foreach ($type as $tp) { + $validator = new TypeConstraint($this->checkMode); + $subSchema = new \stdClass(); + $subSchema->type = $tp; + $validator->check($value, $subSchema, $path, null); + $error = $validator->getErrors(); + + if (!count($error)) { + $validatedOneType = true; + break; + } + + $errors = $error; + } + + if (!$validatedOneType) { + $this->addErrors($errors); + + return; + } + } elseif (is_object($type)) { + $this->checkUndefined($value, $type, $path); + } else { + $isValid = $this->validateType($value, $type); + } + + if ($isValid === false) { + if (!isset(self::$wording[$type])) { + throw new StandardUnexpectedValueException( + sprintf( + "No wording for %s available, expected wordings are: [%s]", + var_export($type, true), + implode(', ', array_filter(self::$wording))) + ); + } + $this->addError($path, ucwords(gettype($value)) . " value found, but " . self::$wording[$type] . " is required", 'type'); + } + } + + /** + * Verifies that a given value is of a certain type + * + * @param mixed $value Value to validate + * @param string $type TypeConstraint to check against + * + * @return boolean + * + * @throws InvalidArgumentException + */ + protected function validateType($value, $type) + { + //mostly the case for inline schema + if (!$type) { + return true; + } + + if ('integer' === $type) { + return is_int($value); + } + + if ('number' === $type) { + return is_numeric($value) && !is_string($value); + } + + if ('boolean' === $type) { + return is_bool($value); + } + + if ('object' === $type) { + return is_object($value); + //return ($this::CHECK_MODE_TYPE_CAST == $this->checkMode) ? is_array($value) : is_object($value); + } + + if ('array' === $type) { + return is_array($value); + } + + if ('string' === $type) { + return is_string($value); + } + + if ('email' === $type) { + return is_string($value); + } + + if ('null' === $type) { + return is_null($value); + } + + if ('any' === $type) { + return true; + } + + throw new InvalidArgumentException((is_object($value) ? 'object' : $value) . ' is an invalid type for ' . $type); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php new file mode 100644 index 0000000..c033720 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php @@ -0,0 +1,307 @@ +<?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\Constraints; + +use JsonSchema\Exception\InvalidArgumentException; +use JsonSchema\Uri\UriResolver; + +/** + * The UndefinedConstraint Constraints + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + */ +class UndefinedConstraint extends Constraint +{ + /** + * {@inheritDoc} + */ + public function check($value, $schema = null, $path = null, $i = null) + { + if (is_null($schema)) { + return; + } + + if (!is_object($schema)) { + throw new InvalidArgumentException( + 'Given schema must be an object in ' . $path + . ' but is a ' . gettype($schema) + ); + } + + $i = is_null($i) ? "" : $i; + $path = $this->incrementPath($path, $i); + + // check special properties + $this->validateCommonProperties($value, $schema, $path); + + // check allOf, anyOf, and oneOf properties + $this->validateOfProperties($value, $schema, $path); + + // check known types + $this->validateTypes($value, $schema, $path, $i); + } + + /** + * Validates the value against the types + * + * @param mixed $value + * @param mixed $schema + * @param string $path + * @param string $i + */ + public function validateTypes($value, $schema = null, $path = null, $i = null) + { + // check array + if (is_array($value)) { + $this->checkArray($value, $schema, $path, $i); + } + + // check object + if (is_object($value) && (isset($schema->properties) || isset($schema->patternProperties) || isset($schema->additionalProperties))) { + $this->checkObject( + $value, + isset($schema->properties) ? $schema->properties : null, + $path, + isset($schema->additionalProperties) ? $schema->additionalProperties : null, + isset($schema->patternProperties) ? $schema->patternProperties : null + ); + } + + // check string + if (is_string($value)) { + $this->checkString($value, $schema, $path, $i); + } + + // check numeric + if (is_numeric($value)) { + $this->checkNumber($value, $schema, $path, $i); + } + + // check enum + if (isset($schema->enum)) { + $this->checkEnum($value, $schema, $path, $i); + } + } + + /** + * Validates common properties + * + * @param mixed $value + * @param mixed $schema + * @param string $path + * @param string $i + */ + protected function validateCommonProperties($value, $schema = null, $path = null, $i = "") + { + // if it extends another schema, it must pass that schema as well + if (isset($schema->extends)) { + if (is_string($schema->extends)) { + $schema->extends = $this->validateUri($schema, $schema->extends); + } + if (is_array($schema->extends)) { + foreach ($schema->extends as $extends) { + $this->checkUndefined($value, $extends, $path, $i); + } + } else { + $this->checkUndefined($value, $schema->extends, $path, $i); + } + } + + // Verify required values + if (is_object($value)) { + if (!($value instanceof UndefinedConstraint) && isset($schema->required) && is_array($schema->required) ) { + // Draft 4 - Required is an array of strings - e.g. "required": ["foo", ...] + foreach ($schema->required as $required) { + if (!property_exists($value, $required)) { + $this->addError((!$path) ? $required : "$path.$required", "The property " . $required . " is required", 'required'); + } + } + } else if (isset($schema->required) && !is_array($schema->required)) { + // Draft 3 - Required attribute - e.g. "foo": {"type": "string", "required": true} + if ( $schema->required && $value instanceof UndefinedConstraint) { + $this->addError($path, "Is missing and it is required", 'required'); + } + } + } + + // Verify type + if (!($value instanceof UndefinedConstraint)) { + $this->checkType($value, $schema, $path); + } + + // Verify disallowed items + if (isset($schema->disallow)) { + $initErrors = $this->getErrors(); + + $typeSchema = new \stdClass(); + $typeSchema->type = $schema->disallow; + $this->checkType($value, $typeSchema, $path); + + // if no new errors were raised it must be a disallowed value + if (count($this->getErrors()) == count($initErrors)) { + $this->addError($path, "Disallowed value was matched", 'disallow'); + } else { + $this->errors = $initErrors; + } + } + + if (isset($schema->not)) { + $initErrors = $this->getErrors(); + $this->checkUndefined($value, $schema->not, $path, $i); + + // if no new errors were raised then the instance validated against the "not" schema + if (count($this->getErrors()) == count($initErrors)) { + $this->addError($path, "Matched a schema which it should not", 'not'); + } else { + $this->errors = $initErrors; + } + } + + // Verify minimum and maximum number of properties + if (is_object($value)) { + if (isset($schema->minProperties)) { + if (count(get_object_vars($value)) < $schema->minProperties) { + $this->addError($path, "Must contain a minimum of " . $schema->minProperties . " properties", 'minProperties', array('minProperties' => $schema->minProperties,)); + } + } + if (isset($schema->maxProperties)) { + if (count(get_object_vars($value)) > $schema->maxProperties) { + $this->addError($path, "Must contain no more than " . $schema->maxProperties . " properties", 'maxProperties', array('maxProperties' => $schema->maxProperties,)); + } + } + } + + // Verify that dependencies are met + if (is_object($value) && isset($schema->dependencies)) { + $this->validateDependencies($value, $schema->dependencies, $path); + } + } + + /** + * Validate allOf, anyOf, and oneOf properties + * + * @param mixed $value + * @param mixed $schema + * @param string $path + * @param string $i + */ + protected function validateOfProperties($value, $schema, $path, $i = "") + { + // Verify type + if ($value instanceof UndefinedConstraint) { + return; + } + + if (isset($schema->allOf)) { + $isValid = true; + foreach ($schema->allOf as $allOf) { + $initErrors = $this->getErrors(); + $this->checkUndefined($value, $allOf, $path, $i); + $isValid = $isValid && (count($this->getErrors()) == count($initErrors)); + } + if (!$isValid) { + $this->addError($path, "Failed to match all schemas", 'allOf'); + } + } + + if (isset($schema->anyOf)) { + $isValid = false; + $startErrors = $this->getErrors(); + foreach ($schema->anyOf as $anyOf) { + $initErrors = $this->getErrors(); + $this->checkUndefined($value, $anyOf, $path, $i); + if ($isValid = (count($this->getErrors()) == count($initErrors))) { + break; + } + } + if (!$isValid) { + $this->addError($path, "Failed to match at least one schema", 'anyOf'); + } else { + $this->errors = $startErrors; + } + } + + if (isset($schema->oneOf)) { + $allErrors = array(); + $matchedSchemas = 0; + $startErrors = $this->getErrors(); + foreach ($schema->oneOf as $oneOf) { + $this->errors = array(); + $this->checkUndefined($value, $oneOf, $path, $i); + if (count($this->getErrors()) == 0) { + $matchedSchemas++; + } + $allErrors = array_merge($allErrors, array_values($this->getErrors())); + } + if ($matchedSchemas !== 1) { + $this->addErrors( + array_merge( + $allErrors, + array(array( + 'property' => $path, + 'message' => "Failed to match exactly one schema", + 'constraint' => 'oneOf', + ),), + $startErrors + ) + ); + } else { + $this->errors = $startErrors; + } + } + } + + /** + * Validate dependencies + * + * @param mixed $value + * @param mixed $dependencies + * @param string $path + * @param string $i + */ + protected function validateDependencies($value, $dependencies, $path, $i = "") + { + foreach ($dependencies as $key => $dependency) { + if (property_exists($value, $key)) { + if (is_string($dependency)) { + // Draft 3 string is allowed - e.g. "dependencies": {"bar": "foo"} + if (!property_exists($value, $dependency)) { + $this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies'); + } + } else if (is_array($dependency)) { + // Draft 4 must be an array - e.g. "dependencies": {"bar": ["foo"]} + foreach ($dependency as $d) { + if (!property_exists($value, $d)) { + $this->addError($path, "$key depends on $d and $d is missing", 'dependencies'); + } + } + } else if (is_object($dependency)) { + // Schema - e.g. "dependencies": {"bar": {"properties": {"foo": {...}}}} + $this->checkUndefined($value, $dependency, $path, $i); + } + } + } + } + + protected function validateUri($schema, $schemaUri = null) + { + $resolver = new UriResolver(); + $retriever = $this->getUriRetriever(); + + $jsonSchema = null; + if ($resolver->isValid($schemaUri)) { + $schemaId = property_exists($schema, 'id') ? $schema->id : null; + $jsonSchema = $retriever->retrieve($schemaId, $schemaUri); + } + + return $jsonSchema; + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..ec702a7 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php @@ -0,0 +1,17 @@ +<?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; + +/** + * Wrapper for the InvalidArgumentException + */ +class InvalidArgumentException extends \InvalidArgumentException +{ +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php new file mode 100644 index 0000000..2e94677 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php @@ -0,0 +1,17 @@ +<?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; + +/** + * Wrapper for the InvalidSchemaMediaType + */ +class InvalidSchemaMediaTypeException extends \RuntimeException +{ +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php new file mode 100644 index 0000000..37db121 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php @@ -0,0 +1,17 @@ +<?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; + +/** + * Wrapper for the InvalidSourceUriException + */ +class InvalidSourceUriException extends InvalidArgumentException +{ +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php new file mode 100644 index 0000000..2c22881 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php @@ -0,0 +1,40 @@ +<?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; + +/** + * Wrapper for the JsonDecodingException + */ +class JsonDecodingException extends \RuntimeException +{ + public function __construct($code = JSON_ERROR_NONE, \Exception $previous = null) + { + switch ($code) { + case JSON_ERROR_DEPTH: + $message = 'The maximum stack depth has been exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $message = 'Invalid or malformed JSON'; + break; + case JSON_ERROR_CTRL_CHAR: + $message = 'Control character error, possibly incorrectly encoded'; + break; + case JSON_ERROR_UTF8: + $message = 'Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + case JSON_ERROR_SYNTAX: + $message = 'JSON syntax is malformed'; + break; + default: + $message = 'Syntax error'; + } + parent::__construct($message, $code, $previous); + } +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php new file mode 100644 index 0000000..87b4ac1 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php @@ -0,0 +1,17 @@ +<?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; + +/** + * Wrapper for the ResourceNotFoundException + */ +class ResourceNotFoundException extends \RuntimeException +{ +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php new file mode 100644 index 0000000..6d0b094 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php @@ -0,0 +1,17 @@ +<?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; + +/** + * Wrapper for the UriResolverException + */ +class UriResolverException extends \RuntimeException +{ +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/RefResolver.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/RefResolver.php new file mode 100644 index 0000000..ea0fafd --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/RefResolver.php @@ -0,0 +1,277 @@ +<?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; + +use JsonSchema\Exception\JsonDecodingException; +use JsonSchema\Uri\Retrievers\UriRetrieverInterface; +use JsonSchema\Uri\UriRetriever; + +/** + * Take in an object that's a JSON schema and take care of all $ref references + * + * @author Tyler Akins <fidian@rumkin.com> + * @see README.md + */ +class RefResolver +{ + /** + * HACK to prevent too many recursive expansions. + * Happens e.g. when you want to validate a schema against the schema + * definition. + * + * @var integer + */ + protected static $depth = 0; + + /** + * maximum references depth + * @var integer + */ + public static $maxDepth = 7; + + /** + * @var UriRetrieverInterface + */ + protected $uriRetriever = null; + + /** + * @var object + */ + protected $rootSchema = null; + + /** + * @param UriRetriever $retriever + */ + public function __construct($retriever = null) + { + $this->uriRetriever = $retriever; + } + + /** + * Retrieves a given schema given a ref and a source URI + * + * @param string $ref Reference from schema + * @param string $sourceUri URI where original schema was located + * @return object Schema + */ + public function fetchRef($ref, $sourceUri) + { + $retriever = $this->getUriRetriever(); + $jsonSchema = $retriever->retrieve($ref, $sourceUri); + $this->resolve($jsonSchema); + + return $jsonSchema; + } + + /** + * Return the URI Retriever, defaulting to making a new one if one + * was not yet set. + * + * @return UriRetriever + */ + public function getUriRetriever() + { + if (is_null($this->uriRetriever)) { + $this->setUriRetriever(new UriRetriever); + } + + return $this->uriRetriever; + } + + /** + * Resolves all $ref references for a given schema. Recurses through + * the object to resolve references of any child schemas. + * + * The 'format' property is omitted because it isn't required for + * validation. Theoretically, this class could be extended to look + * for URIs in formats: "These custom formats MAY be expressed as + * an URI, and this URI MAY reference a schema of that format." + * + * The 'id' property is not filled in, but that could be made to happen. + * + * @param object $schema JSON Schema to flesh out + * @param string $sourceUri URI where this schema was located + */ + public function resolve($schema, $sourceUri = null) + { + if (self::$depth > self::$maxDepth) { + self::$depth = 0; + throw new JsonDecodingException(JSON_ERROR_DEPTH); + } + ++self::$depth; + + if (! is_object($schema)) { + --self::$depth; + return; + } + + if (null === $sourceUri && ! empty($schema->id)) { + $sourceUri = $schema->id; + } + + if (null === $this->rootSchema) { + $this->rootSchema = $schema; + } + + // Resolve $ref first + $this->resolveRef($schema, $sourceUri); + + // These properties are just schemas + // eg. items can be a schema or an array of schemas + foreach (array('additionalItems', 'additionalProperties', 'extends', 'items') as $propertyName) { + $this->resolveProperty($schema, $propertyName, $sourceUri); + } + + // These are all potentially arrays that contain schema objects + // eg. type can be a value or an array of values/schemas + // eg. items can be a schema or an array of schemas + foreach (array('disallow', 'extends', 'items', 'type', 'allOf', 'anyOf', 'oneOf') as $propertyName) { + $this->resolveArrayOfSchemas($schema, $propertyName, $sourceUri); + } + + // These are all objects containing properties whose values are schemas + foreach (array('dependencies', 'patternProperties', 'properties') as $propertyName) { + $this->resolveObjectOfSchemas($schema, $propertyName, $sourceUri); + } + + --self::$depth; + } + + /** + * Given an object and a property name, that property should be an + * array whose values can be schemas. + * + * @param object $schema JSON Schema to flesh out + * @param string $propertyName Property to work on + * @param string $sourceUri URI where this schema was located + */ + public function resolveArrayOfSchemas($schema, $propertyName, $sourceUri) + { + if (! isset($schema->$propertyName) || ! is_array($schema->$propertyName)) { + return; + } + + foreach ($schema->$propertyName as $possiblySchema) { + $this->resolve($possiblySchema, $sourceUri); + } + } + + /** + * Given an object and a property name, that property should be an + * object whose properties are schema objects. + * + * @param object $schema JSON Schema to flesh out + * @param string $propertyName Property to work on + * @param string $sourceUri URI where this schema was located + */ + public function resolveObjectOfSchemas($schema, $propertyName, $sourceUri) + { + if (! isset($schema->$propertyName) || ! is_object($schema->$propertyName)) { + return; + } + + foreach (get_object_vars($schema->$propertyName) as $possiblySchema) { + $this->resolve($possiblySchema, $sourceUri); + } + } + + /** + * Given an object and a property name, that property should be a + * schema object. + * + * @param object $schema JSON Schema to flesh out + * @param string $propertyName Property to work on + * @param string $sourceUri URI where this schema was located + */ + public function resolveProperty($schema, $propertyName, $sourceUri) + { + if (! isset($schema->$propertyName)) { + return; + } + + $this->resolve($schema->$propertyName, $sourceUri); + } + + /** + * Look for the $ref property in the object. If found, remove the + * reference and augment this object with the contents of another + * schema. + * + * @param object $schema JSON Schema to flesh out + * @param string $sourceUri URI where this schema was located + */ + public function resolveRef($schema, $sourceUri) + { + $ref = '$ref'; + + if (empty($schema->$ref)) { + return; + } + + $splitRef = explode('#', $schema->$ref, 2); + + $refDoc = $splitRef[0]; + $refPath = null; + if (count($splitRef) === 2) { + $refPath = explode('/', $splitRef[1]); + array_shift($refPath); + } + + if (empty($refDoc) && empty($refPath)) { + // TODO: Not yet implemented - root pointer ref, causes recursion issues + return; + } + + if (!empty($refDoc)) { + $refSchema = $this->fetchRef($refDoc, $sourceUri); + } else { + $refSchema = $this->rootSchema; + } + + if (null !== $refPath) { + $refSchema = $this->resolveRefSegment($refSchema, $refPath); + } + + unset($schema->$ref); + + // Augment the current $schema object with properties fetched + foreach (get_object_vars($refSchema) as $prop => $value) { + $schema->$prop = $value; + } + } + + /** + * Set URI Retriever for use with the Ref Resolver + * + * @param UriRetriever $retriever + * @return $this for chaining + */ + public function setUriRetriever(UriRetriever $retriever) + { + $this->uriRetriever = $retriever; + + return $this; + } + + protected function resolveRefSegment($data, $pathParts) + { + foreach ($pathParts as $path) { + $path = strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%')); + + if (is_array($data)) { + $data = $data[$path]; + } else { + $data = $data->{$path}; + } + } + + return $data; + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php new file mode 100644 index 0000000..f924ad8 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php @@ -0,0 +1,29 @@ +<?php +/** + * JsonSchema + * @filesource + */ +namespace JsonSchema\Uri\Retrievers; + +/** + * AbstractRetriever implements the default shared behavior + * that all decendant Retrievers should inherit + * @author Steven Garcia <webwhammy@gmail.com> + */ +abstract class AbstractRetriever implements UriRetrieverInterface +{ + /** + * Media content type + * @var string + */ + protected $contentType; + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::getContentType() + */ + public function getContentType() + { + return $this->contentType; + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php new file mode 100644 index 0000000..cd8414f --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php @@ -0,0 +1,79 @@ +<?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\Uri\Retrievers; + +use JsonSchema\Validator; + +/** + * Tries to retrieve JSON schemas from a URI using cURL library + * + * @author Sander Coolen <sander@jibber.nl> + */ +class Curl extends AbstractRetriever +{ + protected $messageBody; + + public function __construct() + { + if (!function_exists('curl_init')) { + throw new \RuntimeException("cURL not installed"); + } + } + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() + */ + public function retrieve($uri) + { + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $uri); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: ' . Validator::SCHEMA_MEDIA_TYPE)); + + $response = curl_exec($ch); + if (false === $response) { + throw new \JsonSchema\Exception\ResourceNotFoundException('JSON schema not found'); + } + + $this->fetchMessageBody($response); + $this->fetchContentType($response); + + curl_close($ch); + + return $this->messageBody; + } + + /** + * @param string $response cURL HTTP response + */ + private function fetchMessageBody($response) + { + preg_match("/(?:\r\n){2}(.*)$/ms", $response, $match); + $this->messageBody = $match[1]; + } + + /** + * @param string $response cURL HTTP response + * @return boolean Whether the Content-Type header was found or not + */ + protected function fetchContentType($response) + { + if (0 < preg_match("/Content-Type:(\V*)/ims", $response, $match)) { + $this->contentType = trim($match[1]); + + return true; + } + + return false; + } +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php new file mode 100644 index 0000000..bc43de6 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php @@ -0,0 +1,87 @@ +<?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\Uri\Retrievers; + +use JsonSchema\Exception\ResourceNotFoundException; +use JsonSchema\Validator; + +/** + * Tries to retrieve JSON schemas from a URI using file_get_contents() + * + * @author Sander Coolen <sander@jibber.nl> + */ +class FileGetContents extends AbstractRetriever +{ + protected $messageBody; + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() + */ + public function retrieve($uri) + { + $context = stream_context_create(array( + 'http' => array( + 'method' => 'GET', + 'header' => "Accept: " . Validator::SCHEMA_MEDIA_TYPE + ))); + + set_error_handler(function() use ($uri) { + throw new ResourceNotFoundException('JSON schema not found at ' . $uri); + }); + $response = file_get_contents($uri); + restore_error_handler(); + + if (false === $response) { + throw new ResourceNotFoundException('JSON schema not found at ' . $uri); + } + if ($response == '' + && substr($uri, 0, 7) == 'file://' && substr($uri, -1) == '/' + ) { + throw new ResourceNotFoundException('JSON schema not found at ' . $uri); + } + + $this->messageBody = $response; + if (! empty($http_response_header)) { + $this->fetchContentType($http_response_header); + } else { + // Could be a "file://" url or something else - fake up the response + $this->contentType = null; + } + + return $this->messageBody; + } + + /** + * @param array $headers HTTP Response Headers + * @return boolean Whether the Content-Type header was found or not + */ + private function fetchContentType(array $headers) + { + foreach ($headers as $header) { + if ($this->contentType = self::getContentTypeMatchInHeader($header)) { + return true; + } + } + + return false; + } + + /** + * @param string $header + * @return string|null + */ + protected static function getContentTypeMatchInHeader($header) + { + if (0 < preg_match("/Content-Type:(\V*)/ims", $header, $match)) { + return trim($match[1]); + } + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php new file mode 100644 index 0000000..7652c42 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php @@ -0,0 +1,54 @@ +<?php + +namespace JsonSchema\Uri\Retrievers; + +use JsonSchema\Validator; + +/** + * 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 extends AbstractRetriever +{ + /** + * Contains schemas as URI => JSON + * @var array + */ + private $schemas; + + /** + * Constructor + * + * @param array $schemas + * @param string $contentType + */ + public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE) + { + $this->schemas = $schemas; + $this->contentType = $contentType; + } + + /** + * {@inheritDoc} + * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() + */ + public function retrieve($uri) + { + if (!array_key_exists($uri, $this->schemas)) { + throw new \JsonSchema\Exception\ResourceNotFoundException(sprintf( + 'The JSON schema "%s" was not found.', + $uri + )); + } + + return $this->schemas[$uri]; + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php new file mode 100644 index 0000000..c324998 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php @@ -0,0 +1,32 @@ +<?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\Uri\Retrievers; + +/** + * Interface for URI retrievers + * + * @author Sander Coolen <sander@jibber.nl> + */ +interface UriRetrieverInterface +{ + /** + * Retrieve a schema from the specified URI + * @param string $uri URI that resolves to a JSON schema + * @throws \JsonSchema\Exception\ResourceNotFoundException + * @return mixed string|null + */ + public function retrieve($uri); + + /** + * Get media content type + * @return string + */ + public function getContentType(); +}
\ No newline at end of file diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php new file mode 100644 index 0000000..9784114 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php @@ -0,0 +1,157 @@ +<?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\Uri; + +use JsonSchema\Exception\UriResolverException; + +/** + * Resolves JSON Schema URIs + * + * @author Sander Coolen <sander@jibber.nl> + */ +class UriResolver +{ + /** + * Parses a URI into five main components + * + * @param string $uri + * @return array + */ + public function parse($uri) + { + preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); + + $components = array(); + if (5 < count($match)) { + $components = array( + 'scheme' => $match[2], + 'authority' => $match[4], + 'path' => $match[5] + ); + } + if (7 < count($match)) { + $components['query'] = $match[7]; + } + if (9 < count($match)) { + $components['fragment'] = $match[9]; + } + + return $components; + } + + /** + * Builds a URI based on n array with the main components + * + * @param array $components + * @return string + */ + public function generate(array $components) + { + $uri = $components['scheme'] . '://' + . $components['authority'] + . $components['path']; + + if (array_key_exists('query', $components)) { + $uri .= $components['query']; + } + if (array_key_exists('fragment', $components)) { + $uri .= '#' . $components['fragment']; + } + + return $uri; + } + + /** + * Resolves a URI + * + * @param string $uri Absolute or relative + * @param string $baseUri Optional base URI + * @return string Absolute URI + */ + public function resolve($uri, $baseUri = null) + { + if ($uri == '') { + return $baseUri; + } + + $components = $this->parse($uri); + $path = $components['path']; + + if (! empty($components['scheme'])) { + return $uri; + } + $baseComponents = $this->parse($baseUri); + $basePath = $baseComponents['path']; + + $baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath); + if (isset($components['fragment'])) { + $baseComponents['fragment'] = $components['fragment']; + } + + return $this->generate($baseComponents); + } + + /** + * Tries to glue a relative path onto an absolute one + * + * @param string $relativePath + * @param string $basePath + * @return string Merged path + * @throws UriResolverException + */ + public static function combineRelativePathWithBasePath($relativePath, $basePath) + { + $relativePath = self::normalizePath($relativePath); + if ($relativePath == '') { + return $basePath; + } + if ($relativePath{0} == '/') { + return $relativePath; + } + + $basePathSegments = explode('/', $basePath); + + preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match); + $numLevelUp = strlen($match[0]) /3 + 1; + if ($numLevelUp >= count($basePathSegments)) { + throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath)); + } + + $basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp); + $path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath); + + return implode('/', $basePathSegments) . '/' . $path; + } + + /** + * Normalizes a URI path component by removing dot-slash and double slashes + * + * @param string $path + * @return string + */ + private static function normalizePath($path) + { + $path = preg_replace('|((?<!\.)\./)*|', '', $path); + $path = preg_replace('|//|', '/', $path); + + return $path; + } + + /** + * @param string $uri + * @return boolean + */ + public function isValid($uri) + { + $components = $this->parse($uri); + + return !empty($components); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php new file mode 100644 index 0000000..c723cd9 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php @@ -0,0 +1,289 @@ +<?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\Uri; + +use JsonSchema\Uri\Retrievers\FileGetContents; +use JsonSchema\Uri\Retrievers\UriRetrieverInterface; +use JsonSchema\Validator; +use JsonSchema\Exception\InvalidSchemaMediaTypeException; +use JsonSchema\Exception\JsonDecodingException; +use JsonSchema\Exception\ResourceNotFoundException; + +/** + * Retrieves JSON Schema URIs + * + * @author Tyler Akins <fidian@rumkin.com> + */ +class UriRetriever +{ + /** + * @var null|UriRetrieverInterface + */ + protected $uriRetriever = null; + + /** + * @var array|object[] + * @see loadSchema + */ + private $schemaCache = array(); + + /** + * Guarantee the correct media type was encountered + * + * @param UriRetrieverInterface $uriRetriever + * @param string $uri + * @return bool|void + */ + public function confirmMediaType($uriRetriever, $uri) + { + $contentType = $uriRetriever->getContentType(); + + if (is_null($contentType)) { + // Well, we didn't get an invalid one + return; + } + + if (Validator::SCHEMA_MEDIA_TYPE === $contentType) { + return; + } + + if (substr($uri, 0, 23) == 'http://json-schema.org/') { + //HACK; they deliver broken content types + return true; + } + + throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE)); + } + + /** + * Get a URI Retriever + * + * If none is specified, sets a default FileGetContents retriever and + * returns that object. + * + * @return UriRetrieverInterface + */ + public function getUriRetriever() + { + if (is_null($this->uriRetriever)) { + $this->setUriRetriever(new FileGetContents); + } + + return $this->uriRetriever; + } + + /** + * Resolve a schema based on pointer + * + * URIs can have a fragment at the end in the format of + * #/path/to/object and we are to look up the 'path' property of + * the first object then the 'to' and 'object' properties. + * + * @param object $jsonSchema JSON Schema contents + * @param string $uri JSON Schema URI + * @return object JSON Schema after walking down the fragment pieces + * + * @throws ResourceNotFoundException + */ + public function resolvePointer($jsonSchema, $uri) + { + $resolver = new UriResolver(); + $parsed = $resolver->parse($uri); + if (empty($parsed['fragment'])) { + return $jsonSchema; + } + + $path = explode('/', $parsed['fragment']); + while ($path) { + $pathElement = array_shift($path); + if (! empty($pathElement)) { + $pathElement = str_replace('~1', '/', $pathElement); + $pathElement = str_replace('~0', '~', $pathElement); + if (! empty($jsonSchema->$pathElement)) { + $jsonSchema = $jsonSchema->$pathElement; + } else { + throw new ResourceNotFoundException( + 'Fragment "' . $parsed['fragment'] . '" not found' + . ' in ' . $uri + ); + } + + if (! is_object($jsonSchema)) { + throw new ResourceNotFoundException( + 'Fragment part "' . $pathElement . '" is no object ' + . ' in ' . $uri + ); + } + } + } + + return $jsonSchema; + } + + /** + * Retrieve a URI + * + * @param string $uri JSON Schema URI + * @param string|null $baseUri + * @return object JSON Schema contents + */ + public function retrieve($uri, $baseUri = null) + { + $resolver = new UriResolver(); + $resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri); + + //fetch URL without #fragment + $arParts = $resolver->parse($resolvedUri); + if (isset($arParts['fragment'])) { + unset($arParts['fragment']); + $fetchUri = $resolver->generate($arParts); + } + + $jsonSchema = $this->loadSchema($fetchUri); + + // Use the JSON pointer if specified + $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri); + + if ($jsonSchema instanceof \stdClass) { + $jsonSchema->id = $resolvedUri; + } + + return $jsonSchema; + } + + /** + * Fetch a schema from the given URI, json-decode it and return it. + * Caches schema objects. + * + * @param string $fetchUri Absolute URI + * + * @return object JSON schema object + */ + protected function loadSchema($fetchUri) + { + if (isset($this->schemaCache[$fetchUri])) { + return $this->schemaCache[$fetchUri]; + } + + $uriRetriever = $this->getUriRetriever(); + $contents = $this->uriRetriever->retrieve($fetchUri); + $this->confirmMediaType($uriRetriever, $fetchUri); + $jsonSchema = json_decode($contents); + + if (JSON_ERROR_NONE < $error = json_last_error()) { + throw new JsonDecodingException($error); + } + + $this->schemaCache[$fetchUri] = $jsonSchema; + + return $jsonSchema; + } + + /** + * Set the URI Retriever + * + * @param UriRetrieverInterface $uriRetriever + * @return $this for chaining + */ + public function setUriRetriever(UriRetrieverInterface $uriRetriever) + { + $this->uriRetriever = $uriRetriever; + + return $this; + } + + /** + * Parses a URI into five main components + * + * @param string $uri + * @return array + */ + public function parse($uri) + { + preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); + + $components = array(); + if (5 < count($match)) { + $components = array( + 'scheme' => $match[2], + 'authority' => $match[4], + 'path' => $match[5] + ); + } + + if (7 < count($match)) { + $components['query'] = $match[7]; + } + + if (9 < count($match)) { + $components['fragment'] = $match[9]; + } + + return $components; + } + + /** + * Builds a URI based on n array with the main components + * + * @param array $components + * @return string + */ + public function generate(array $components) + { + $uri = $components['scheme'] . '://' + . $components['authority'] + . $components['path']; + + if (array_key_exists('query', $components)) { + $uri .= $components['query']; + } + + if (array_key_exists('fragment', $components)) { + $uri .= $components['fragment']; + } + + return $uri; + } + + /** + * Resolves a URI + * + * @param string $uri Absolute or relative + * @param string $baseUri Optional base URI + * @return string + */ + public function resolve($uri, $baseUri = null) + { + $components = $this->parse($uri); + $path = $components['path']; + + if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) { + return $uri; + } + + $baseComponents = $this->parse($baseUri); + $basePath = $baseComponents['path']; + + $baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath); + + return $this->generate($baseComponents); + } + + /** + * @param string $uri + * @return boolean + */ + public function isValid($uri) + { + $components = $this->parse($uri); + + return !empty($components); + } +} diff --git a/server/vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php new file mode 100644 index 0000000..14dbb60 --- /dev/null +++ b/server/vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php @@ -0,0 +1,40 @@ +<?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; + +use JsonSchema\Constraints\SchemaConstraint; +use JsonSchema\Constraints\Constraint; + +/** + * A JsonSchema Constraint + * + * @author Robert Schönthal <seroscho@googlemail.com> + * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> + * @see README.md + */ +class Validator extends Constraint +{ + const SCHEMA_MEDIA_TYPE = 'application/schema+json'; + + /** + * Validates the given data against the schema and returns an object containing the results + * Both the php object and the schema are supposed to be a result of a json_decode call. + * The validation works as defined by the schema proposal in http://json-schema.org + * + * {@inheritDoc} + */ + public function check($value, $schema = null, $path = null, $i = null) + { + $validator = $this->getFactory()->createInstanceFor('schema'); + $validator->check($value, $schema); + + $this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR)); + } +} |
