Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update readme and simplify interface #320

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ if ($validator->isValid()) {
```
###Type Coercion
If you're validating data passed to your application via HTTP, you can cast strings and booleans to the expected types defined by your schema:
```
```php
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;
use JsonSchema\Constraints\Factory;
Expand All @@ -56,9 +56,7 @@ $request = (object)[
'refundAmount'=>"17"
];

$factory = new Factory( null, null, Constraint::CHECK_MODE_TYPE_CAST | Constraint::CHECK_MODE_COERCE );

$validator = new Validator($factory);
$validator = new Validator(Constraint::CHECK_MODE_TYPE_CAST | Constraint::CHECK_MODE_COERCE);
$validator->check($request, (object) [
"type"=>"object",
"properties"=>(object)[
Expand All @@ -85,6 +83,7 @@ Note that the ```CHECK_MODE_COERCE``` flag will only take effect when an object
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;
use JsonSchema\Constraints\Factory;
use JsonSchema\Constraints\Constraint;

$jsonSchema = <<<'JSON'
{
Expand Down Expand Up @@ -122,7 +121,7 @@ $schemaStorage = new SchemaStorage();
$schemaStorage->addSchema('file://mySchema', $jsonSchemaObject);

// Provide $schemaStorage to the Validator so that references can be resolved during validation
$jsonValidator = new Validator( new Factory($schemaStorage));
$jsonValidator = new Validator( Constraint::CHECK_MODE_NORMAL, new Factory($schemaStorage));

// JSON must be decoded before it can be validated
$jsonToValidateObject = json_decode('{"data":123}');
Expand All @@ -133,4 +132,4 @@ $jsonValidator->check($jsonToValidateObject, $jsonSchemaObject);

## Running the tests

$ vendor/bin/phpunit
$ vendor/bin/phpunit
2 changes: 1 addition & 1 deletion src/JsonSchema/Constraints/CollectionConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
26 changes: 16 additions & 10 deletions src/JsonSchema/Constraints/Constraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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();
}

Expand Down Expand Up @@ -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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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);

Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/JsonSchema/Constraints/EnumConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
29 changes: 7 additions & 22 deletions src/JsonSchema/Constraints/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ class Factory
*/
protected $uriRetriever;

/**
* @var int
*/
private $checkMode;

/**
* @var TypeCheck\TypeCheckInterface[]
*/
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -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];
}

/**
Expand Down Expand Up @@ -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;
}
}
8 changes: 4 additions & 4 deletions src/JsonSchema/Constraints/ObjectConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/JsonSchema/Constraints/TypeConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/JsonSchema/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
8 changes: 4 additions & 4 deletions tests/Constraints/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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));
Expand All @@ -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));
Expand Down
8 changes: 4 additions & 4 deletions tests/Constraints/CoerciveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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");
Expand Down Expand Up @@ -86,7 +86,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) {
Expand All @@ -105,7 +105,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) {
Expand Down
6 changes: 3 additions & 3 deletions tests/Constraints/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
}
Expand Down