ex
Fork of mbed-os-example-mbed5-blinky by
dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php@44:c1d8923072ba, 2017-07-18 (annotated)
- Committer:
- TMBOY
- Date:
- Tue Jul 18 16:27:22 2017 +0800
- Revision:
- 44:c1d8923072ba
?
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| TMBOY | 44:c1d8923072ba | 1 | <?php |
| TMBOY | 44:c1d8923072ba | 2 | |
| TMBOY | 44:c1d8923072ba | 3 | /* |
| TMBOY | 44:c1d8923072ba | 4 | * This file is part of the JsonSchema package. |
| TMBOY | 44:c1d8923072ba | 5 | * |
| TMBOY | 44:c1d8923072ba | 6 | * For the full copyright and license information, please view the LICENSE |
| TMBOY | 44:c1d8923072ba | 7 | * file that was distributed with this source code. |
| TMBOY | 44:c1d8923072ba | 8 | */ |
| TMBOY | 44:c1d8923072ba | 9 | |
| TMBOY | 44:c1d8923072ba | 10 | namespace JsonSchema\Constraints; |
| TMBOY | 44:c1d8923072ba | 11 | |
| TMBOY | 44:c1d8923072ba | 12 | use JsonSchema\Uri\UriResolver; |
| TMBOY | 44:c1d8923072ba | 13 | use JsonSchema\Entity\JsonPointer; |
| TMBOY | 44:c1d8923072ba | 14 | |
| TMBOY | 44:c1d8923072ba | 15 | /** |
| TMBOY | 44:c1d8923072ba | 16 | * The UndefinedConstraint Constraints |
| TMBOY | 44:c1d8923072ba | 17 | * |
| TMBOY | 44:c1d8923072ba | 18 | * @author Robert Schönthal <seroscho@googlemail.com> |
| TMBOY | 44:c1d8923072ba | 19 | * @author Bruno Prieto Reis <bruno.p.reis@gmail.com> |
| TMBOY | 44:c1d8923072ba | 20 | */ |
| TMBOY | 44:c1d8923072ba | 21 | class UndefinedConstraint extends Constraint |
| TMBOY | 44:c1d8923072ba | 22 | { |
| TMBOY | 44:c1d8923072ba | 23 | /** |
| TMBOY | 44:c1d8923072ba | 24 | * {@inheritDoc} |
| TMBOY | 44:c1d8923072ba | 25 | */ |
| TMBOY | 44:c1d8923072ba | 26 | public function check($value, $schema = null, JsonPointer $path = null, $i = null) |
| TMBOY | 44:c1d8923072ba | 27 | { |
| TMBOY | 44:c1d8923072ba | 28 | if (is_null($schema) || !is_object($schema)) { |
| TMBOY | 44:c1d8923072ba | 29 | return; |
| TMBOY | 44:c1d8923072ba | 30 | } |
| TMBOY | 44:c1d8923072ba | 31 | |
| TMBOY | 44:c1d8923072ba | 32 | $path = $this->incrementPath($path ?: new JsonPointer(''), $i); |
| TMBOY | 44:c1d8923072ba | 33 | |
| TMBOY | 44:c1d8923072ba | 34 | // check special properties |
| TMBOY | 44:c1d8923072ba | 35 | $this->validateCommonProperties($value, $schema, $path); |
| TMBOY | 44:c1d8923072ba | 36 | |
| TMBOY | 44:c1d8923072ba | 37 | // check allOf, anyOf, and oneOf properties |
| TMBOY | 44:c1d8923072ba | 38 | $this->validateOfProperties($value, $schema, $path); |
| TMBOY | 44:c1d8923072ba | 39 | |
| TMBOY | 44:c1d8923072ba | 40 | // check known types |
| TMBOY | 44:c1d8923072ba | 41 | $this->validateTypes($value, $schema, $path, $i); |
| TMBOY | 44:c1d8923072ba | 42 | } |
| TMBOY | 44:c1d8923072ba | 43 | |
| TMBOY | 44:c1d8923072ba | 44 | /** |
| TMBOY | 44:c1d8923072ba | 45 | * Validates the value against the types |
| TMBOY | 44:c1d8923072ba | 46 | * |
| TMBOY | 44:c1d8923072ba | 47 | * @param mixed $value |
| TMBOY | 44:c1d8923072ba | 48 | * @param mixed $schema |
| TMBOY | 44:c1d8923072ba | 49 | * @param JsonPointer $path |
| TMBOY | 44:c1d8923072ba | 50 | * @param string $i |
| TMBOY | 44:c1d8923072ba | 51 | */ |
| TMBOY | 44:c1d8923072ba | 52 | public function validateTypes($value, $schema = null, JsonPointer $path, $i = null) |
| TMBOY | 44:c1d8923072ba | 53 | { |
| TMBOY | 44:c1d8923072ba | 54 | // check array |
| TMBOY | 44:c1d8923072ba | 55 | if ($this->getTypeCheck()->isArray($value)) { |
| TMBOY | 44:c1d8923072ba | 56 | $this->checkArray($value, $schema, $path, $i); |
| TMBOY | 44:c1d8923072ba | 57 | } |
| TMBOY | 44:c1d8923072ba | 58 | |
| TMBOY | 44:c1d8923072ba | 59 | // check object |
| TMBOY | 44:c1d8923072ba | 60 | if ($this->getTypeCheck()->isObject($value)) { |
| TMBOY | 44:c1d8923072ba | 61 | $this->checkObject( |
| TMBOY | 44:c1d8923072ba | 62 | $value, |
| TMBOY | 44:c1d8923072ba | 63 | isset($schema->properties) ? $this->factory->getSchemaStorage()->resolveRefSchema($schema->properties) : $schema, |
| TMBOY | 44:c1d8923072ba | 64 | $path, |
| TMBOY | 44:c1d8923072ba | 65 | isset($schema->additionalProperties) ? $schema->additionalProperties : null, |
| TMBOY | 44:c1d8923072ba | 66 | isset($schema->patternProperties) ? $schema->patternProperties : null |
| TMBOY | 44:c1d8923072ba | 67 | ); |
| TMBOY | 44:c1d8923072ba | 68 | } |
| TMBOY | 44:c1d8923072ba | 69 | |
| TMBOY | 44:c1d8923072ba | 70 | // check string |
| TMBOY | 44:c1d8923072ba | 71 | if (is_string($value)) { |
| TMBOY | 44:c1d8923072ba | 72 | $this->checkString($value, $schema, $path, $i); |
| TMBOY | 44:c1d8923072ba | 73 | } |
| TMBOY | 44:c1d8923072ba | 74 | |
| TMBOY | 44:c1d8923072ba | 75 | // check numeric |
| TMBOY | 44:c1d8923072ba | 76 | if (is_numeric($value)) { |
| TMBOY | 44:c1d8923072ba | 77 | $this->checkNumber($value, $schema, $path, $i); |
| TMBOY | 44:c1d8923072ba | 78 | } |
| TMBOY | 44:c1d8923072ba | 79 | |
| TMBOY | 44:c1d8923072ba | 80 | // check enum |
| TMBOY | 44:c1d8923072ba | 81 | if (isset($schema->enum)) { |
| TMBOY | 44:c1d8923072ba | 82 | $this->checkEnum($value, $schema, $path, $i); |
| TMBOY | 44:c1d8923072ba | 83 | } |
| TMBOY | 44:c1d8923072ba | 84 | } |
| TMBOY | 44:c1d8923072ba | 85 | |
| TMBOY | 44:c1d8923072ba | 86 | /** |
| TMBOY | 44:c1d8923072ba | 87 | * Validates common properties |
| TMBOY | 44:c1d8923072ba | 88 | * |
| TMBOY | 44:c1d8923072ba | 89 | * @param mixed $value |
| TMBOY | 44:c1d8923072ba | 90 | * @param mixed $schema |
| TMBOY | 44:c1d8923072ba | 91 | * @param JsonPointer $path |
| TMBOY | 44:c1d8923072ba | 92 | * @param string $i |
| TMBOY | 44:c1d8923072ba | 93 | */ |
| TMBOY | 44:c1d8923072ba | 94 | protected function validateCommonProperties($value, $schema = null, JsonPointer $path, $i = "") |
| TMBOY | 44:c1d8923072ba | 95 | { |
| TMBOY | 44:c1d8923072ba | 96 | // if it extends another schema, it must pass that schema as well |
| TMBOY | 44:c1d8923072ba | 97 | if (isset($schema->extends)) { |
| TMBOY | 44:c1d8923072ba | 98 | if (is_string($schema->extends)) { |
| TMBOY | 44:c1d8923072ba | 99 | $schema->extends = $this->validateUri($schema, $schema->extends); |
| TMBOY | 44:c1d8923072ba | 100 | } |
| TMBOY | 44:c1d8923072ba | 101 | if (is_array($schema->extends)) { |
| TMBOY | 44:c1d8923072ba | 102 | foreach ($schema->extends as $extends) { |
| TMBOY | 44:c1d8923072ba | 103 | $this->checkUndefined($value, $extends, $path, $i); |
| TMBOY | 44:c1d8923072ba | 104 | } |
| TMBOY | 44:c1d8923072ba | 105 | } else { |
| TMBOY | 44:c1d8923072ba | 106 | $this->checkUndefined($value, $schema->extends, $path, $i); |
| TMBOY | 44:c1d8923072ba | 107 | } |
| TMBOY | 44:c1d8923072ba | 108 | } |
| TMBOY | 44:c1d8923072ba | 109 | |
| TMBOY | 44:c1d8923072ba | 110 | // Verify required values |
| TMBOY | 44:c1d8923072ba | 111 | if ($this->getTypeCheck()->isObject($value)) { |
| TMBOY | 44:c1d8923072ba | 112 | if (!($value instanceof UndefinedConstraint) && isset($schema->required) && is_array($schema->required)) { |
| TMBOY | 44:c1d8923072ba | 113 | // Draft 4 - Required is an array of strings - e.g. "required": ["foo", ...] |
| TMBOY | 44:c1d8923072ba | 114 | foreach ($schema->required as $required) { |
| TMBOY | 44:c1d8923072ba | 115 | if (!$this->getTypeCheck()->propertyExists($value, $required)) { |
| TMBOY | 44:c1d8923072ba | 116 | $this->addError( |
| TMBOY | 44:c1d8923072ba | 117 | $this->incrementPath($path ?: new JsonPointer(''), $required), |
| TMBOY | 44:c1d8923072ba | 118 | "The property " . $required . " is required", |
| TMBOY | 44:c1d8923072ba | 119 | 'required' |
| TMBOY | 44:c1d8923072ba | 120 | ); |
| TMBOY | 44:c1d8923072ba | 121 | } |
| TMBOY | 44:c1d8923072ba | 122 | } |
| TMBOY | 44:c1d8923072ba | 123 | } elseif (isset($schema->required) && !is_array($schema->required)) { |
| TMBOY | 44:c1d8923072ba | 124 | // Draft 3 - Required attribute - e.g. "foo": {"type": "string", "required": true} |
| TMBOY | 44:c1d8923072ba | 125 | if ($schema->required && $value instanceof UndefinedConstraint) { |
| TMBOY | 44:c1d8923072ba | 126 | $this->addError($path, "Is missing and it is required", 'required'); |
| TMBOY | 44:c1d8923072ba | 127 | } |
| TMBOY | 44:c1d8923072ba | 128 | } |
| TMBOY | 44:c1d8923072ba | 129 | } |
| TMBOY | 44:c1d8923072ba | 130 | |
| TMBOY | 44:c1d8923072ba | 131 | // Verify type |
| TMBOY | 44:c1d8923072ba | 132 | if (!($value instanceof UndefinedConstraint)) { |
| TMBOY | 44:c1d8923072ba | 133 | $this->checkType($value, $schema, $path); |
| TMBOY | 44:c1d8923072ba | 134 | } |
| TMBOY | 44:c1d8923072ba | 135 | |
| TMBOY | 44:c1d8923072ba | 136 | // Verify disallowed items |
| TMBOY | 44:c1d8923072ba | 137 | if (isset($schema->disallow)) { |
| TMBOY | 44:c1d8923072ba | 138 | $initErrors = $this->getErrors(); |
| TMBOY | 44:c1d8923072ba | 139 | |
| TMBOY | 44:c1d8923072ba | 140 | $typeSchema = new \stdClass(); |
| TMBOY | 44:c1d8923072ba | 141 | $typeSchema->type = $schema->disallow; |
| TMBOY | 44:c1d8923072ba | 142 | $this->checkType($value, $typeSchema, $path); |
| TMBOY | 44:c1d8923072ba | 143 | |
| TMBOY | 44:c1d8923072ba | 144 | // if no new errors were raised it must be a disallowed value |
| TMBOY | 44:c1d8923072ba | 145 | if (count($this->getErrors()) == count($initErrors)) { |
| TMBOY | 44:c1d8923072ba | 146 | $this->addError($path, "Disallowed value was matched", 'disallow'); |
| TMBOY | 44:c1d8923072ba | 147 | } else { |
| TMBOY | 44:c1d8923072ba | 148 | $this->errors = $initErrors; |
| TMBOY | 44:c1d8923072ba | 149 | } |
| TMBOY | 44:c1d8923072ba | 150 | } |
| TMBOY | 44:c1d8923072ba | 151 | |
| TMBOY | 44:c1d8923072ba | 152 | if (isset($schema->not)) { |
| TMBOY | 44:c1d8923072ba | 153 | $initErrors = $this->getErrors(); |
| TMBOY | 44:c1d8923072ba | 154 | $this->checkUndefined($value, $schema->not, $path, $i); |
| TMBOY | 44:c1d8923072ba | 155 | |
| TMBOY | 44:c1d8923072ba | 156 | // if no new errors were raised then the instance validated against the "not" schema |
| TMBOY | 44:c1d8923072ba | 157 | if (count($this->getErrors()) == count($initErrors)) { |
| TMBOY | 44:c1d8923072ba | 158 | $this->addError($path, "Matched a schema which it should not", 'not'); |
| TMBOY | 44:c1d8923072ba | 159 | } else { |
| TMBOY | 44:c1d8923072ba | 160 | $this->errors = $initErrors; |
| TMBOY | 44:c1d8923072ba | 161 | } |
| TMBOY | 44:c1d8923072ba | 162 | } |
| TMBOY | 44:c1d8923072ba | 163 | |
| TMBOY | 44:c1d8923072ba | 164 | // Verify that dependencies are met |
| TMBOY | 44:c1d8923072ba | 165 | if (isset($schema->dependencies) && $this->getTypeCheck()->isObject($value)) { |
| TMBOY | 44:c1d8923072ba | 166 | $this->validateDependencies($value, $schema->dependencies, $path); |
| TMBOY | 44:c1d8923072ba | 167 | } |
| TMBOY | 44:c1d8923072ba | 168 | } |
| TMBOY | 44:c1d8923072ba | 169 | |
| TMBOY | 44:c1d8923072ba | 170 | /** |
| TMBOY | 44:c1d8923072ba | 171 | * Validate allOf, anyOf, and oneOf properties |
| TMBOY | 44:c1d8923072ba | 172 | * |
| TMBOY | 44:c1d8923072ba | 173 | * @param mixed $value |
| TMBOY | 44:c1d8923072ba | 174 | * @param mixed $schema |
| TMBOY | 44:c1d8923072ba | 175 | * @param JsonPointer $path |
| TMBOY | 44:c1d8923072ba | 176 | * @param string $i |
| TMBOY | 44:c1d8923072ba | 177 | */ |
| TMBOY | 44:c1d8923072ba | 178 | protected function validateOfProperties($value, $schema, JsonPointer $path, $i = "") |
| TMBOY | 44:c1d8923072ba | 179 | { |
| TMBOY | 44:c1d8923072ba | 180 | // Verify type |
| TMBOY | 44:c1d8923072ba | 181 | if ($value instanceof UndefinedConstraint) { |
| TMBOY | 44:c1d8923072ba | 182 | return; |
| TMBOY | 44:c1d8923072ba | 183 | } |
| TMBOY | 44:c1d8923072ba | 184 | |
| TMBOY | 44:c1d8923072ba | 185 | if (isset($schema->allOf)) { |
| TMBOY | 44:c1d8923072ba | 186 | $isValid = true; |
| TMBOY | 44:c1d8923072ba | 187 | foreach ($schema->allOf as $allOf) { |
| TMBOY | 44:c1d8923072ba | 188 | $initErrors = $this->getErrors(); |
| TMBOY | 44:c1d8923072ba | 189 | $this->checkUndefined($value, $allOf, $path, $i); |
| TMBOY | 44:c1d8923072ba | 190 | $isValid = $isValid && (count($this->getErrors()) == count($initErrors)); |
| TMBOY | 44:c1d8923072ba | 191 | } |
| TMBOY | 44:c1d8923072ba | 192 | if (!$isValid) { |
| TMBOY | 44:c1d8923072ba | 193 | $this->addError($path, "Failed to match all schemas", 'allOf'); |
| TMBOY | 44:c1d8923072ba | 194 | } |
| TMBOY | 44:c1d8923072ba | 195 | } |
| TMBOY | 44:c1d8923072ba | 196 | |
| TMBOY | 44:c1d8923072ba | 197 | if (isset($schema->anyOf)) { |
| TMBOY | 44:c1d8923072ba | 198 | $isValid = false; |
| TMBOY | 44:c1d8923072ba | 199 | $startErrors = $this->getErrors(); |
| TMBOY | 44:c1d8923072ba | 200 | foreach ($schema->anyOf as $anyOf) { |
| TMBOY | 44:c1d8923072ba | 201 | $initErrors = $this->getErrors(); |
| TMBOY | 44:c1d8923072ba | 202 | $this->checkUndefined($value, $anyOf, $path, $i); |
| TMBOY | 44:c1d8923072ba | 203 | if ($isValid = (count($this->getErrors()) == count($initErrors))) { |
| TMBOY | 44:c1d8923072ba | 204 | break; |
| TMBOY | 44:c1d8923072ba | 205 | } |
| TMBOY | 44:c1d8923072ba | 206 | } |
| TMBOY | 44:c1d8923072ba | 207 | if (!$isValid) { |
| TMBOY | 44:c1d8923072ba | 208 | $this->addError($path, "Failed to match at least one schema", 'anyOf'); |
| TMBOY | 44:c1d8923072ba | 209 | } else { |
| TMBOY | 44:c1d8923072ba | 210 | $this->errors = $startErrors; |
| TMBOY | 44:c1d8923072ba | 211 | } |
| TMBOY | 44:c1d8923072ba | 212 | } |
| TMBOY | 44:c1d8923072ba | 213 | |
| TMBOY | 44:c1d8923072ba | 214 | if (isset($schema->oneOf)) { |
| TMBOY | 44:c1d8923072ba | 215 | $allErrors = array(); |
| TMBOY | 44:c1d8923072ba | 216 | $matchedSchemas = 0; |
| TMBOY | 44:c1d8923072ba | 217 | $startErrors = $this->getErrors(); |
| TMBOY | 44:c1d8923072ba | 218 | foreach ($schema->oneOf as $oneOf) { |
| TMBOY | 44:c1d8923072ba | 219 | $this->errors = array(); |
| TMBOY | 44:c1d8923072ba | 220 | $this->checkUndefined($value, $oneOf, $path, $i); |
| TMBOY | 44:c1d8923072ba | 221 | if (count($this->getErrors()) == 0) { |
| TMBOY | 44:c1d8923072ba | 222 | $matchedSchemas++; |
| TMBOY | 44:c1d8923072ba | 223 | } |
| TMBOY | 44:c1d8923072ba | 224 | $allErrors = array_merge($allErrors, array_values($this->getErrors())); |
| TMBOY | 44:c1d8923072ba | 225 | } |
| TMBOY | 44:c1d8923072ba | 226 | if ($matchedSchemas !== 1) { |
| TMBOY | 44:c1d8923072ba | 227 | $this->addErrors(array_merge($allErrors, $startErrors)); |
| TMBOY | 44:c1d8923072ba | 228 | $this->addError($path, "Failed to match exactly one schema", 'oneOf'); |
| TMBOY | 44:c1d8923072ba | 229 | } else { |
| TMBOY | 44:c1d8923072ba | 230 | $this->errors = $startErrors; |
| TMBOY | 44:c1d8923072ba | 231 | } |
| TMBOY | 44:c1d8923072ba | 232 | } |
| TMBOY | 44:c1d8923072ba | 233 | } |
| TMBOY | 44:c1d8923072ba | 234 | |
| TMBOY | 44:c1d8923072ba | 235 | /** |
| TMBOY | 44:c1d8923072ba | 236 | * Validate dependencies |
| TMBOY | 44:c1d8923072ba | 237 | * |
| TMBOY | 44:c1d8923072ba | 238 | * @param mixed $value |
| TMBOY | 44:c1d8923072ba | 239 | * @param mixed $dependencies |
| TMBOY | 44:c1d8923072ba | 240 | * @param JsonPointer $path |
| TMBOY | 44:c1d8923072ba | 241 | * @param string $i |
| TMBOY | 44:c1d8923072ba | 242 | */ |
| TMBOY | 44:c1d8923072ba | 243 | protected function validateDependencies($value, $dependencies, JsonPointer $path, $i = "") |
| TMBOY | 44:c1d8923072ba | 244 | { |
| TMBOY | 44:c1d8923072ba | 245 | foreach ($dependencies as $key => $dependency) { |
| TMBOY | 44:c1d8923072ba | 246 | if ($this->getTypeCheck()->propertyExists($value, $key)) { |
| TMBOY | 44:c1d8923072ba | 247 | if (is_string($dependency)) { |
| TMBOY | 44:c1d8923072ba | 248 | // Draft 3 string is allowed - e.g. "dependencies": {"bar": "foo"} |
| TMBOY | 44:c1d8923072ba | 249 | if (!$this->getTypeCheck()->propertyExists($value, $dependency)) { |
| TMBOY | 44:c1d8923072ba | 250 | $this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies'); |
| TMBOY | 44:c1d8923072ba | 251 | } |
| TMBOY | 44:c1d8923072ba | 252 | } elseif (is_array($dependency)) { |
| TMBOY | 44:c1d8923072ba | 253 | // Draft 4 must be an array - e.g. "dependencies": {"bar": ["foo"]} |
| TMBOY | 44:c1d8923072ba | 254 | foreach ($dependency as $d) { |
| TMBOY | 44:c1d8923072ba | 255 | if (!$this->getTypeCheck()->propertyExists($value, $d)) { |
| TMBOY | 44:c1d8923072ba | 256 | $this->addError($path, "$key depends on $d and $d is missing", 'dependencies'); |
| TMBOY | 44:c1d8923072ba | 257 | } |
| TMBOY | 44:c1d8923072ba | 258 | } |
| TMBOY | 44:c1d8923072ba | 259 | } elseif (is_object($dependency)) { |
| TMBOY | 44:c1d8923072ba | 260 | // Schema - e.g. "dependencies": {"bar": {"properties": {"foo": {...}}}} |
| TMBOY | 44:c1d8923072ba | 261 | $this->checkUndefined($value, $dependency, $path, $i); |
| TMBOY | 44:c1d8923072ba | 262 | } |
| TMBOY | 44:c1d8923072ba | 263 | } |
| TMBOY | 44:c1d8923072ba | 264 | } |
| TMBOY | 44:c1d8923072ba | 265 | } |
| TMBOY | 44:c1d8923072ba | 266 | |
| TMBOY | 44:c1d8923072ba | 267 | protected function validateUri($schema, $schemaUri = null) |
| TMBOY | 44:c1d8923072ba | 268 | { |
| TMBOY | 44:c1d8923072ba | 269 | $resolver = new UriResolver(); |
| TMBOY | 44:c1d8923072ba | 270 | $retriever = $this->factory->getUriRetriever(); |
| TMBOY | 44:c1d8923072ba | 271 | |
| TMBOY | 44:c1d8923072ba | 272 | $jsonSchema = null; |
| TMBOY | 44:c1d8923072ba | 273 | if ($resolver->isValid($schemaUri)) { |
| TMBOY | 44:c1d8923072ba | 274 | $schemaId = property_exists($schema, 'id') ? $schema->id : null; |
| TMBOY | 44:c1d8923072ba | 275 | $jsonSchema = $retriever->retrieve($schemaId, $schemaUri); |
| TMBOY | 44:c1d8923072ba | 276 | } |
| TMBOY | 44:c1d8923072ba | 277 | |
| TMBOY | 44:c1d8923072ba | 278 | return $jsonSchema; |
| TMBOY | 44:c1d8923072ba | 279 | } |
| TMBOY | 44:c1d8923072ba | 280 | } |
