From 405c9f1a568797e4c899520debb23aa868a8c8c0 Mon Sep 17 00:00:00 2001 From: Max Loeb Date: Mon, 10 Oct 2016 10:05:25 -0700 Subject: [PATCH 1/2] update readme --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9d96b203..b21eff3a 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,13 @@ $request = (object)[ 'refundAmount'=>"17" ]; -$validator = new \JsonSchema\Validator(\JsonSchema\Constraints\Constraint::CHECK_MODE_TYPE_CAST | \JsonSchema\Constraints\Constraint::CHECK_MODE_COERCE); +$factory = new \JsonSchema\Constraints\Factory( + null, + null, + \JsonSchema\Constraints\Constraint::CHECK_MODE_TYPE_CAST | + \JsonSchema\Constraints\Constraint::CHECK_MODE_COERCE + ); +$validator = new \JsonSchema\Validator($factory); $validator->check($request, (object) [ "type"=>"object", "properties"=>[ @@ -108,13 +114,15 @@ $jsonSchemaObject = json_decode($jsonSchema); // The SchemaStorage can resolve references, loading additional schemas from file as needed, etc. $schemaStorage = new SchemaStorage(); +$factory = new \JsonSchema\Constraints\Factory($schemaStorage); + // This does two things: // 1) Mutates $jsonSchemaObject to normalize the references (to file://mySchema#/definitions/integerData, etc) // 2) Tells $schemaStorage that references to file://mySchema... should be resolved by looking in $jsonSchemaObject $schemaStorage->addSchema('file://mySchema', $jsonSchemaObject); // Provide $schemaStorage to the Validator so that references can be resolved during validation -$jsonValidator = new Validator(Validator::CHECK_MODE_NORMAL, $schemaStorage); +$jsonValidator = new Validator($factory); // JSON must be decoded before it can be validated $jsonToValidateObject = json_decode('{"data":123}'); From 0895ed6af78e4813bfae6dd6919cf0025d939e99 Mon Sep 17 00:00:00 2001 From: Max Loeb Date: Mon, 10 Oct 2016 20:20:56 -0700 Subject: [PATCH 2/2] move checkmode to constraint instance --- README.md | 12 +++----- .../Constraints/CollectionConstraint.php | 2 +- src/JsonSchema/Constraints/Constraint.php | 26 ++++++++++------- src/JsonSchema/Constraints/EnumConstraint.php | 2 +- src/JsonSchema/Constraints/Factory.php | 29 +++++-------------- .../Constraints/ObjectConstraint.php | 8 ++--- src/JsonSchema/Constraints/TypeConstraint.php | 2 +- src/JsonSchema/Validator.php | 2 +- tests/Constraints/BaseTestCase.php | 8 ++--- tests/Constraints/CoerciveTest.php | 8 ++--- tests/Constraints/FactoryTest.php | 6 ++-- 11 files changed, 46 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index b21eff3a..8552b721 100644 --- a/README.md +++ b/README.md @@ -51,13 +51,9 @@ $request = (object)[ 'refundAmount'=>"17" ]; -$factory = new \JsonSchema\Constraints\Factory( - null, - null, - \JsonSchema\Constraints\Constraint::CHECK_MODE_TYPE_CAST | - \JsonSchema\Constraints\Constraint::CHECK_MODE_COERCE - ); -$validator = new \JsonSchema\Validator($factory); +$validator = new \JsonSchema\Validator( + \JsonSchema\Constraints\Constraint::CHECK_MODE_TYPE_CAST | + \JsonSchema\Constraints\Constraint::CHECK_MODE_COERCE); $validator->check($request, (object) [ "type"=>"object", "properties"=>[ @@ -122,7 +118,7 @@ $factory = new \JsonSchema\Constraints\Factory($schemaStorage); $schemaStorage->addSchema('file://mySchema', $jsonSchemaObject); // Provide $schemaStorage to the Validator so that references can be resolved during validation -$jsonValidator = new Validator($factory); +$jsonValidator = new Validator(\JsonSchema\Constraints\Constraint::CHECK_MODE_NORMAL, $factory); // JSON must be decoded before it can be validated $jsonToValidateObject = json_decode('{"data":123}'); diff --git a/src/JsonSchema/Constraints/CollectionConstraint.php b/src/JsonSchema/Constraints/CollectionConstraint.php index b65173de..5d77b088 100644 --- a/src/JsonSchema/Constraints/CollectionConstraint.php +++ b/src/JsonSchema/Constraints/CollectionConstraint.php @@ -106,7 +106,7 @@ protected function validateItems($value, $schema = null, JsonPointer $path = nul // 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($this->factory->createInstanceFor('undefined'), $schema->items[$k], $path, $k); + $this->checkUndefined($this->factory->createInstanceFor($this->checkMode,'undefined'), $schema->items[$k], $path, $k); } } } diff --git a/src/JsonSchema/Constraints/Constraint.php b/src/JsonSchema/Constraints/Constraint.php index 95a63971..df01b281 100644 --- a/src/JsonSchema/Constraints/Constraint.php +++ b/src/JsonSchema/Constraints/Constraint.php @@ -29,6 +29,11 @@ abstract class Constraint implements ConstraintInterface const CHECK_MODE_TYPE_CAST = 0x00000002; const CHECK_MODE_COERCE = 0x00000004; + /** + * @var int + */ + protected $checkMode; + /** * @var Factory */ @@ -37,8 +42,9 @@ abstract class Constraint implements ConstraintInterface /** * @param Factory $factory */ - public function __construct(Factory $factory = null) + public function __construct($checkMode = Constraint::CHECK_MODE_NORMAL, Factory $factory = null) { + $this->checkMode = $checkMode; $this->factory = $factory ? : new Factory(); } @@ -127,7 +133,7 @@ protected function incrementPath(JsonPointer $path = null, $i) */ protected function checkArray($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('collection'); + $validator = $this->factory->createInstanceFor($this->checkMode,'collection'); $validator->check($value, $schema, $path, $i); $this->addErrors($validator->getErrors()); @@ -144,7 +150,7 @@ protected function checkArray($value, $schema = null, JsonPointer $path = null, */ protected function checkObject($value, $schema = null, JsonPointer $path = null, $i = null, $patternProperties = null) { - $validator = $this->factory->createInstanceFor('object'); + $validator = $this->factory->createInstanceFor($this->checkMode,'object'); $validator->check($value, $schema, $path, $i, $patternProperties); $this->addErrors($validator->getErrors()); @@ -160,7 +166,7 @@ protected function checkObject($value, $schema = null, JsonPointer $path = null, */ protected function checkType($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('type'); + $validator = $this->factory->createInstanceFor($this->checkMode, 'type'); $validator->check($value, $schema, $path, $i); $this->addErrors($validator->getErrors()); @@ -176,7 +182,7 @@ protected function checkType($value, $schema = null, JsonPointer $path = null, $ */ protected function checkUndefined($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('undefined'); + $validator = $this->factory->createInstanceFor($this->checkMode,'undefined'); $validator->check($value, $this->factory->getSchemaStorage()->resolveRefSchema($schema), $path, $i); @@ -193,7 +199,7 @@ protected function checkUndefined($value, $schema = null, JsonPointer $path = nu */ protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('string'); + $validator = $this->factory->createInstanceFor($this->checkMode, 'string'); $validator->check($value, $schema, $path, $i); $this->addErrors($validator->getErrors()); @@ -209,7 +215,7 @@ protected function checkString($value, $schema = null, JsonPointer $path = null, */ protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('number'); + $validator = $this->factory->createInstanceFor($this->checkMode, 'number'); $validator->check($value, $schema, $path, $i); $this->addErrors($validator->getErrors()); @@ -225,7 +231,7 @@ protected function checkNumber($value, $schema = null, JsonPointer $path = null, */ protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('enum'); + $validator = $this->factory->createInstanceFor($this->checkMode, 'enum'); $validator->check($value, $schema, $path, $i); $this->addErrors($validator->getErrors()); @@ -241,7 +247,7 @@ protected function checkEnum($value, $schema = null, JsonPointer $path = null, $ */ protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('format'); + $validator = $this->factory->createInstanceFor($this->checkMode, 'format'); $validator->check($value, $schema, $path, $i); $this->addErrors($validator->getErrors()); @@ -254,7 +260,7 @@ protected function checkFormat($value, $schema = null, JsonPointer $path = null, */ protected function getTypeCheck() { - return $this->factory->getTypeCheck(); + return $this->factory->getTypeCheck($this->checkMode); } /** diff --git a/src/JsonSchema/Constraints/EnumConstraint.php b/src/JsonSchema/Constraints/EnumConstraint.php index 376d3ee9..23adb653 100644 --- a/src/JsonSchema/Constraints/EnumConstraint.php +++ b/src/JsonSchema/Constraints/EnumConstraint.php @@ -31,7 +31,7 @@ public function check($element, $schema = null, JsonPointer $path = null, $i = n foreach ($schema->enum as $enum) { $enumType = gettype($enum); - if (($this->factory->getCheckMode() & self::CHECK_MODE_TYPE_CAST) && $type == "array" && $enumType == "object") { + if (($this->checkMode & self::CHECK_MODE_TYPE_CAST) && $type == "array" && $enumType == "object") { if ((object)$element == $enum) { return; } diff --git a/src/JsonSchema/Constraints/Factory.php b/src/JsonSchema/Constraints/Factory.php index 5eadb17e..e9b37150 100644 --- a/src/JsonSchema/Constraints/Factory.php +++ b/src/JsonSchema/Constraints/Factory.php @@ -29,11 +29,6 @@ class Factory */ protected $uriRetriever; - /** - * @var int - */ - private $checkMode; - /** * @var TypeCheck\TypeCheckInterface[] */ @@ -69,12 +64,10 @@ class Factory */ public function __construct( SchemaStorage $schemaStorage = null, - UriRetrieverInterface $uriRetriever = null, - $checkMode = Constraint::CHECK_MODE_NORMAL + UriRetrieverInterface $uriRetriever = null ) { $this->uriRetriever = $uriRetriever ?: new UriRetriever; $this->schemaStorage = $schemaStorage ?: new SchemaStorage($this->uriRetriever); - $this->checkMode = $checkMode; } /** @@ -90,15 +83,15 @@ public function getSchemaStorage() return $this->schemaStorage; } - public function getTypeCheck() + public function getTypeCheck($checkMode) { - if (!isset($this->typeCheck[$this->checkMode])) { - $this->typeCheck[$this->checkMode] = ($this->checkMode & Constraint::CHECK_MODE_TYPE_CAST) + if (!isset($this->typeCheck[$checkMode])) { + $this->typeCheck[$checkMode] = ($checkMode & Constraint::CHECK_MODE_TYPE_CAST) ? new TypeCheck\LooseTypeCheck : new TypeCheck\StrictTypeCheck; } - return $this->typeCheck[$this->checkMode]; + return $this->typeCheck[$checkMode]; } /** @@ -127,24 +120,16 @@ public function setConstraintClass($name, $class) * @return ConstraintInterface|ObjectConstraint * @throws InvalidArgumentException if is not possible create the constraint instance. */ - public function createInstanceFor($constraintName) + public function createInstanceFor($checkMode, $constraintName) { if (!isset($this->constraintMap[$constraintName])) { throw new InvalidArgumentException('Unknown constraint ' . $constraintName); } if (!isset($this->instanceCache[$constraintName])) { - $this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($this); + $this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($checkMode, $this); } return clone $this->instanceCache[$constraintName]; } - - /** - * @return int - */ - public function getCheckMode() - { - return $this->checkMode; - } } diff --git a/src/JsonSchema/Constraints/ObjectConstraint.php b/src/JsonSchema/Constraints/ObjectConstraint.php index b0008f8e..3303bf8c 100644 --- a/src/JsonSchema/Constraints/ObjectConstraint.php +++ b/src/JsonSchema/Constraints/ObjectConstraint.php @@ -106,7 +106,7 @@ public function validateElement($element, $matches, $objectDefinition = null, Js $this->addError($path, "The presence of the property " . $i . " requires that " . $require . " also be present", 'requires'); } - $property = $this->getProperty($element, $i, $this->factory->createInstanceFor('undefined')); + $property = $this->getProperty($element, $i, $this->factory->createInstanceFor($this->checkMode, 'undefined')); if (is_object($property)) { $this->validateMinMaxConstraint(!($property instanceof UndefinedConstraint) ? $property : $element, $definition, $path); } @@ -122,17 +122,17 @@ public function validateElement($element, $matches, $objectDefinition = null, Js */ public function validateDefinition($element, $objectDefinition = null, JsonPointer $path = null) { - $undefinedConstraint = $this->factory->createInstanceFor('undefined'); + $undefinedConstraint = $this->factory->createInstanceFor($this->checkMode,'undefined'); foreach ($objectDefinition as $i => $value) { $property = $this->getProperty($element, $i, $undefinedConstraint); $definition = $this->getProperty($objectDefinition, $i); - if($this->factory->getCheckMode() & Constraint::CHECK_MODE_TYPE_CAST){ + if($this->checkMode & Constraint::CHECK_MODE_TYPE_CAST){ if(!($property instanceof Constraint)) { $property = $this->coerce($property, $definition); - if($this->factory->getCheckMode() & Constraint::CHECK_MODE_COERCE) { + if($this->checkMode & Constraint::CHECK_MODE_COERCE) { if (is_object($element)) { $element->{$i} = $property; } else { diff --git a/src/JsonSchema/Constraints/TypeConstraint.php b/src/JsonSchema/Constraints/TypeConstraint.php index 1b2125e0..d215ca0d 100644 --- a/src/JsonSchema/Constraints/TypeConstraint.php +++ b/src/JsonSchema/Constraints/TypeConstraint.php @@ -82,7 +82,7 @@ protected function validateTypesArray($value, array $type, &$validTypesWording, // with a new type constraint if (is_object($tp)) { if (!$isValid) { - $validator = $this->factory->createInstanceFor('type'); + $validator = $this->factory->createInstanceFor($this->checkMode,'type'); $subSchema = new \stdClass(); $subSchema->type = $tp; $validator->check($value, $subSchema, $path, null); diff --git a/src/JsonSchema/Validator.php b/src/JsonSchema/Validator.php index 39dca096..4ad7d524 100644 --- a/src/JsonSchema/Validator.php +++ b/src/JsonSchema/Validator.php @@ -32,7 +32,7 @@ class Validator extends Constraint */ public function check($value, $schema = null, JsonPointer $path = null, $i = null) { - $validator = $this->factory->createInstanceFor('schema'); + $validator = $this->factory->createInstanceFor($this->checkMode, 'schema'); $validator->check($value, $schema); $this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR)); diff --git a/tests/Constraints/BaseTestCase.php b/tests/Constraints/BaseTestCase.php index 5c6dcf18..143526d1 100644 --- a/tests/Constraints/BaseTestCase.php +++ b/tests/Constraints/BaseTestCase.php @@ -37,7 +37,7 @@ public function testInvalidCases($input, $schema, $checkMode = Constraint::CHECK $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $validator->check(json_decode($input), $schema); if (array() !== $errors) { @@ -59,7 +59,7 @@ public function testInvalidCasesUsingAssoc($input, $schema, $checkMode = Constra $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $validator->check(json_decode($input, true), $schema); if (array() !== $errors) { @@ -76,7 +76,7 @@ public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_M $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $validator->check(json_decode($input), $schema); $this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true)); @@ -96,7 +96,7 @@ public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constrain $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); $value = json_decode($input, true); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $validator->check($value, $schema); $this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true)); diff --git a/tests/Constraints/CoerciveTest.php b/tests/Constraints/CoerciveTest.php index bfec165b..f7c784ed 100644 --- a/tests/Constraints/CoerciveTest.php +++ b/tests/Constraints/CoerciveTest.php @@ -27,7 +27,7 @@ public function testValidCoerceCasesUsingAssoc($input, $schema) $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $value = json_decode($input, true); @@ -45,7 +45,7 @@ public function testValidCoerceCases($input, $schema, $errors = array()) $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $value = json_decode($input); $this->assertTrue(gettype($value->number) == "string"); @@ -71,7 +71,7 @@ public function testInvalidCoerceCases($input, $schema, $errors = array()) $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $validator->check(json_decode($input), $schema); if (array() !== $errors) { @@ -90,7 +90,7 @@ public function testInvalidCoerceCasesUsingAssoc($input, $schema, $errors = arra $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); - $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); + $validator = new Validator($checkMode, new Factory($schemaStorage, null)); $validator->check(json_decode($input, true), $schema); if (array() !== $errors) { diff --git a/tests/Constraints/FactoryTest.php b/tests/Constraints/FactoryTest.php index 956db6de..ff8718ea 100644 --- a/tests/Constraints/FactoryTest.php +++ b/tests/Constraints/FactoryTest.php @@ -50,7 +50,7 @@ protected function setUp() */ public function testCreateInstanceForConstraintName($constraintName, $expectedClass) { - $constraint = $this->factory->createInstanceFor($constraintName); + $constraint = $this->factory->createInstanceFor(Constraint::CHECK_MODE_NORMAL, $constraintName); $this->assertInstanceOf($expectedClass, $constraint); $this->assertInstanceOf('JsonSchema\Constraints\ConstraintInterface', $constraint); @@ -82,7 +82,7 @@ public function constraintNameProvider() public function testExceptionWhenCreateInstanceForInvalidConstraintName($constraintName) { $this->setExpectedException('JsonSchema\Exception\InvalidArgumentException'); - $this->factory->createInstanceFor($constraintName); + $this->factory->createInstanceFor(Constraint::CHECK_MODE_NORMAL, $constraintName); } public function invalidConstraintNameProvider() { @@ -110,7 +110,7 @@ public function testSetConstraintClassImplementsCondition() public function testSetConstraintClassInstance() { $this->factory->setConstraintClass('string', 'JsonSchema\Tests\Constraints\MyStringConstraint'); - $constraint = $this->factory->createInstanceFor('string'); + $constraint = $this->factory->createInstanceFor(Constraint::CHECK_MODE_NORMAL, 'string'); $this->assertInstanceOf('JsonSchema\Tests\Constraints\MyStringConstraint', $constraint); $this->assertInstanceOf('JsonSchema\Constraints\ConstraintInterface', $constraint); }