From f55a09b5e1ea574c3c481f1c34287a04c4b7c4e4 Mon Sep 17 00:00:00 2001 From: Erayd Date: Sun, 5 Feb 2017 14:58:05 +1300 Subject: [PATCH 1/2] Add option to throw an exception on validation errors --- src/JsonSchema/Constraints/BaseConstraint.php | 5 ++ src/JsonSchema/Constraints/Constraint.php | 1 + .../Exception/ValidationException.php | 14 +++++ tests/Constraints/ValidationExceptionTest.php | 52 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 src/JsonSchema/Exception/ValidationException.php create mode 100644 tests/Constraints/ValidationExceptionTest.php diff --git a/src/JsonSchema/Constraints/BaseConstraint.php b/src/JsonSchema/Constraints/BaseConstraint.php index 9d2ade65..6c4cc42f 100644 --- a/src/JsonSchema/Constraints/BaseConstraint.php +++ b/src/JsonSchema/Constraints/BaseConstraint.php @@ -10,6 +10,7 @@ namespace JsonSchema\Constraints; use JsonSchema\Entity\JsonPointer; +use JsonSchema\Exception\ValidationException; /** * A more basic constraint definition - used for the public @@ -47,6 +48,10 @@ public function addError(JsonPointer $path = null, $message, $constraint = '', a 'constraint' => $constraint, ); + if ($this->factory->getConfig(Constraint::CHECK_MODE_EXCEPTIONS)) { + throw new ValidationException(sprintf("Error validating %s: %s", $error['pointer'], $error['message'])); + } + if (is_array($more) && count($more) > 0) { $error += $more; diff --git a/src/JsonSchema/Constraints/Constraint.php b/src/JsonSchema/Constraints/Constraint.php index c5170eea..cc12a22c 100644 --- a/src/JsonSchema/Constraints/Constraint.php +++ b/src/JsonSchema/Constraints/Constraint.php @@ -29,6 +29,7 @@ abstract class Constraint extends BaseConstraint implements ConstraintInterface const CHECK_MODE_TYPE_CAST = 0x00000002; const CHECK_MODE_COERCE_TYPES = 0x00000004; const CHECK_MODE_APPLY_DEFAULTS = 0x00000008; + const CHECK_MODE_EXCEPTIONS = 0x00000010; /** * Bubble down the path diff --git a/src/JsonSchema/Exception/ValidationException.php b/src/JsonSchema/Exception/ValidationException.php new file mode 100644 index 00000000..65d8849e --- /dev/null +++ b/src/JsonSchema/Exception/ValidationException.php @@ -0,0 +1,14 @@ +assertInstanceOf('\JsonSchema\Exception\ValidationException', $exception); + + $checkValue = json_decode('{"propertyOne": "thisIsNotAnObject"}'); + $schema = json_decode('{ + "type": "object", + "additionalProperties": false, + "properties": { + "propertyOne": { + "type": "object" + } + } + }'); + + $validator = new Validator(); + + try { + $validator->validate($checkValue, $schema, Constraint::CHECK_MODE_EXCEPTIONS); + } catch (\Exception $e) { + $exception = $e; + } + + $this->assertEquals( + 'Error validating /propertyOne: String value found, but an object is required', + $exception->getMessage() + ); + + + $this->setExpectedException('JsonSchema\Exception\ValidationException'); + throw $exception; + + } +} From a4cd125db3d2a22419ad074c59ae07d6045725a0 Mon Sep 17 00:00:00 2001 From: Erayd Date: Thu, 16 Feb 2017 09:38:17 +1300 Subject: [PATCH 2/2] Update README * Changes API references to use the new Validator::validate() entry point * Adds section describing available config options --- README.md | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cb390f2f..fee6dfb9 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ $data = json_decode(file_get_contents('data.json')); // Validate $validator = new JsonSchema\Validator; -$validator->check($data, (object)['$ref' => 'file://' . realpath('schema.json')]); +$validator->validate($data, (object)['$ref' => 'file://' . realpath('schema.json')]); if ($validator->isValid()) { echo "The supplied JSON validates against the schema.\n"; @@ -63,22 +63,31 @@ $request = (object)[ 'refundAmount'=>"17" ]; -$validator->coerce($request, (object) [ +$validator->validate( + $request, (object) [ "type"=>"object", - "properties"=>(object)[ - "processRefund"=>(object)[ - "type"=>"boolean" - ], - "refundAmount"=>(object)[ - "type"=>"number" + "properties"=>(object)[ + "processRefund"=>(object)[ + "type"=>"boolean" + ], + "refundAmount"=>(object)[ + "type"=>"number" + ] ] - ] -]); // validates! + ], + Constraint::CHECK_MODE_COERCE_TYPES +); // validates! is_bool($request->processRefund); // true is_int($request->refundAmount); // true ``` +A shorthand method is also available: +```PHP +$validator->coerce($request, $schema); +// equivalent to $validator->validate($data, $schema, Constraint::CHECK_MODE_COERCE_TYPES); +``` + ### With inline references ```php @@ -130,9 +139,23 @@ $jsonValidator = new Validator( new Factory($schemaStorage)); $jsonToValidateObject = json_decode('{"data":123}'); // Do validation (use isValid() and getErrors() to check the result) -$jsonValidator->check($jsonToValidateObject, $jsonSchemaObject); +$jsonValidator->validate($jsonToValidateObject, $jsonSchemaObject); ``` +### Configuration Options +A number of flags are available to alter the behavior of the validator. These can be passed as the +third argument to `Validator::validate()`, or can be provided as the third argument to +`Factory::__construct()` if you wish to persist them across multiple `validate()` calls. + +| Flag | Description | +|------|-------------| +| `Constraint::CHECK_MODE_NORMAL` | Validate in 'normal' mode - this is the default | +| `Constraint::CHECK_MODE_TYPE_CAST` | Enable fuzzy type checking for associative arrays and objects | +| `Constraint::CHECK_MODE_COERCE_TYPES` | Convert data types to match the schema where possible | +| `Constraint::CHECK_MODE_EXCEPTIONS` | Throw an exception immediately if validation fails | + +Please note that using `Constraint::CHECK_MODE_COERCE_TYPES` will modify your original data. + ## Running the tests ```bash