diff --git a/src/JsonSchema/Constraints/TypeConstraint.php b/src/JsonSchema/Constraints/TypeConstraint.php index ff4eba71..fe843f70 100644 --- a/src/JsonSchema/Constraints/TypeConstraint.php +++ b/src/JsonSchema/Constraints/TypeConstraint.php @@ -81,11 +81,11 @@ public function check(&$value = null, $schema = null, JsonPointer $path = null, * of $isValid to true, if at least one $type mateches the type of $value or the value * passed as $isValid is already true. * - * @param mixed $value Value to validate - * @param array $type TypeConstraints to check against - * @param array $validTypesWording An array of wordings of the valid types of the array $type - * @param bool $isValid The current validation value - * @param $path + * @param mixed $value Value to validate + * @param array $type TypeConstraints to check against + * @param array $validTypesWording An array of wordings of the valid types of the array $type + * @param bool $isValid The current validation value + * @param JsonPointer|null $path */ protected function validateTypesArray(&$value, array $type, &$validTypesWording, &$isValid, $path, $coerce = false) { @@ -98,21 +98,17 @@ protected function validateTypesArray(&$value, array $type, &$validTypesWording, // $tp can be an object, if it's a schema instead of a simple type, validate it // with a new type constraint if (is_object($tp)) { - if (!$isValid) { - $validator = $this->factory->createInstanceFor('type'); - $subSchema = new \stdClass(); - $subSchema->type = $tp; - $validator->check($value, $subSchema, $path, null); - $error = $validator->getErrors(); - $isValid = !(bool) $error; - $validTypesWording[] = self::$wording['object']; - } + $validator = $this->factory->createInstanceFor('type'); + $subSchema = new \stdClass(); + $subSchema->type = $tp; + $validator->check($value, $subSchema, $path, null); + $error = $validator->getErrors(); + $isValid = !(bool) $error; + $validTypesWording[] = self::$wording['object']; } else { $this->validateTypeNameWording($tp); $validTypesWording[] = self::$wording[$tp]; - if (!$isValid) { - $isValid = $this->validateType($value, $tp, $coerce); - } + $isValid = $this->validateType($value, $tp, $coerce); } } } @@ -122,9 +118,9 @@ protected function validateTypesArray(&$value, array $type, &$validTypesWording, * difference, that, if $listEnd isn't false, the last element delimiter is $listEnd instead of * $delimiter. * - * @param array $elements The elements to implode - * @param string $delimiter The delimiter to use - * @param bool $listEnd The last delimiter to use (defaults to $delimiter) + * @param array $elements The elements to implode + * @param string $delimiter The delimiter to use + * @param bool|string $listEnd The last delimiter to use (defaults to $delimiter) * * @return string */ @@ -239,7 +235,7 @@ protected function validateType(&$value, $type, $coerce = false) /** * Converts a value to boolean. For example, "true" becomes true. * - * @param $value The value to convert to boolean + * @param mixed $value The value to convert to boolean * * @return bool|mixed */ diff --git a/src/JsonSchema/Constraints/UndefinedConstraint.php b/src/JsonSchema/Constraints/UndefinedConstraint.php index bdb95f4a..d4200209 100644 --- a/src/JsonSchema/Constraints/UndefinedConstraint.php +++ b/src/JsonSchema/Constraints/UndefinedConstraint.php @@ -140,7 +140,7 @@ protected function validateCommonProperties(&$value, $schema, JsonPointer $path, if (!$this->getTypeCheck()->propertyExists($value, $required)) { $this->addError( ConstraintError::REQUIRED(), - $this->incrementPath($path ?: new JsonPointer(''), $required), array( + $this->incrementPath($path, $required), array( 'property' => $required ) ); diff --git a/src/JsonSchema/SchemaStorage.php b/src/JsonSchema/SchemaStorage.php index 81b3508c..1ec301e3 100644 --- a/src/JsonSchema/SchemaStorage.php +++ b/src/JsonSchema/SchemaStorage.php @@ -60,11 +60,25 @@ public function addSchema($id, $schema = null) // workaround for bug in draft-03 & draft-04 meta-schemas (id & $ref defined with incorrect format) // see https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/177#issuecomment-293051367 if (is_object($schema) && property_exists($schema, 'id')) { - if ($schema->id == 'http://json-schema.org/draft-04/schema#') { - $schema->properties->id->format = 'uri-reference'; - } elseif ($schema->id == 'http://json-schema.org/draft-03/schema#') { - $schema->properties->id->format = 'uri-reference'; - $schema->properties->{'$ref'}->format = 'uri-reference'; + $draft03 = false; + if ( + $schema->id === 'http://json-schema.org/draft-04/schema#' || + ($schema->id === 'http://json-schema.org/draft-03/schema#' && $draft03 = true) + ) { + if (!property_exists($schema, 'properties')) { + $schema->properties = new \stdClass; + } + if (!property_exists($schema->properties, 'id')) { + $schema->properties->id = new \stdClass; + } + $schema->properties->id->format = 'uri-reference'; + + if ($draft03) { + if (!property_exists($schema->properties, '$ref')) { + $schema->properties->{'$ref'} = new \stdClass; + } + $schema->properties->{'$ref'}->format = 'uri-reference'; + } } } diff --git a/tests/SchemaStorageTest.php b/tests/SchemaStorageTest.php index ebbc9477..9ca7e2c2 100644 --- a/tests/SchemaStorageTest.php +++ b/tests/SchemaStorageTest.php @@ -323,4 +323,14 @@ public function testNoDoubleResolve() $schemas['test/schema']->{'$ref'} ); } + + public function testAddSchemaMissingProperties() + { + $schema_03 = array('id' => 'http://json-schema.org/draft-03/schema#'); + $schema_04 = array('id' => 'http://json-schema.org/draft-04/schema#'); + + $s = new SchemaStorage(); + $s->addSchema($schema_03['id'], $schema_03); + $s->addSchema($schema_04['id'], $schema_04); + } }