4 * This file is part of the JsonSchema package.
6 * For the full copyright and license information, please view the LICENSE
7 * file that was distributed with this source code.
10 namespace JsonSchema\Constraints;
12 use JsonSchema\Entity\JsonPointer;
13 use JsonSchema\Exception\InvalidArgumentException;
14 use JsonSchema\Exception\InvalidSchemaException;
15 use JsonSchema\Exception\RuntimeException;
16 use JsonSchema\SchemaStorage;
17 use JsonSchema\Validator;
20 * The SchemaConstraint Constraints, validates an element against a given schema
22 * @author Robert Schönthal <seroscho@googlemail.com>
23 * @author Bruno Prieto Reis <bruno.p.reis@gmail.com>
25 class SchemaConstraint extends Constraint
27 const DEFAULT_SCHEMA_SPEC = 'http://json-schema.org/draft-04/schema#';
32 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
34 if ($schema !== null) {
36 $validationSchema = $schema;
37 } elseif ($this->getTypeCheck()->propertyExists($element, $this->inlineSchemaProperty)) {
39 $validationSchema = $this->getTypeCheck()->propertyGet($element, $this->inlineSchemaProperty);
41 throw new InvalidArgumentException('no schema found to verify against');
44 // cast array schemas to object
45 if (is_array($validationSchema)) {
46 $validationSchema = BaseConstraint::arrayToObjectRecursive($validationSchema);
49 // validate schema against whatever is defined in $validationSchema->$schema. If no
50 // schema is defined, assume self::DEFAULT_SCHEMA_SPEC (currently draft-04).
51 if ($this->factory->getConfig(self::CHECK_MODE_VALIDATE_SCHEMA)) {
52 if (!$this->getTypeCheck()->isObject($validationSchema)) {
53 throw new RuntimeException('Cannot validate the schema of a non-object');
55 if ($this->getTypeCheck()->propertyExists($validationSchema, '$schema')) {
56 $schemaSpec = $this->getTypeCheck()->propertyGet($validationSchema, '$schema');
58 $schemaSpec = self::DEFAULT_SCHEMA_SPEC;
61 // get the spec schema
62 $schemaStorage = $this->factory->getSchemaStorage();
63 if (!$this->getTypeCheck()->isObject($schemaSpec)) {
64 $schemaSpec = $schemaStorage->getSchema($schemaSpec);
67 // save error count, config & subtract CHECK_MODE_VALIDATE_SCHEMA
68 $initialErrorCount = $this->numErrors();
69 $initialConfig = $this->factory->getConfig();
70 $initialContext = $this->factory->getErrorContext();
71 $this->factory->removeConfig(self::CHECK_MODE_VALIDATE_SCHEMA | self::CHECK_MODE_APPLY_DEFAULTS);
72 $this->factory->addConfig(self::CHECK_MODE_TYPE_CAST);
73 $this->factory->setErrorContext(Validator::ERROR_SCHEMA_VALIDATION);
77 $this->check($validationSchema, $schemaSpec);
78 } catch (\Exception $e) {
79 if ($this->factory->getConfig(self::CHECK_MODE_EXCEPTIONS)) {
80 throw new InvalidSchemaException('Schema did not pass validation', 0, $e);
83 if ($this->numErrors() > $initialErrorCount) {
84 $this->addError($path, 'Schema is not valid', 'schema');
87 // restore the initial config
88 $this->factory->setConfig($initialConfig);
89 $this->factory->setErrorContext($initialContext);
92 // validate element against $validationSchema
93 $this->checkUndefined($element, $validationSchema, $path, $i);