ex

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Committer:
TMBOY
Date:
Tue Jul 18 16:27:22 2017 +0800
Revision:
44:c1d8923072ba
?

Who changed what in which revision?

UserRevisionLine numberNew 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 }