Skip to content

Commit 022342a

Browse files
committed
feat: more support on draft-06 schema
1 parent 6ef38b3 commit 022342a

File tree

8 files changed

+111
-3
lines changed

8 files changed

+111
-3
lines changed

src/JsonSchema/Constraints/Drafts/Draft06/AdditionalPropertiesConstraint.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,25 @@ public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = n
3333
return;
3434
}
3535

36-
$additionalProperties = array_diff_key(get_object_vars($value), (array) $schema->properties);
37-
// @todo additional properties should bechecked against the patternProperties
36+
$additionalProperties = get_object_vars($value);
37+
38+
if (isset($schema->properties)) {
39+
$additionalProperties = array_diff_key($additionalProperties, (array)$schema->properties);
40+
}
41+
42+
if (isset($schema->patternProperties)) {
43+
$patterns = array_keys(get_object_vars($schema->patternProperties));
44+
45+
foreach ($additionalProperties as $key => $_) {
46+
foreach ($patterns as $pattern) {
47+
if (preg_match("/{$pattern}/", $key)) {
48+
unset($additionalProperties[$key]);
49+
break;
50+
}
51+
}
52+
}
53+
}
54+
3855
if ($schema->additionalProperties === false && $additionalProperties !== []) {
3956
$this->addError(ConstraintError::ADDITIONAL_PROPERTIES(), $path, ['additionalProperties' => array_keys($additionalProperties)]);
4057
}

src/JsonSchema/Constraints/Drafts/Draft06/Draft06Constraint.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = n
3434
$this->checkForKeyword('minProperties', $value, $schema, $path, $i);
3535
$this->checkForKeyword('maxProperties', $value, $schema, $path, $i);
3636
$this->checkForKeyword('minimum', $value, $schema, $path, $i);
37+
$this->checkForKeyword('maximum', $value, $schema, $path, $i);
3738
$this->checkForKeyword('minLength', $value, $schema, $path, $i);
3839
$this->checkForKeyword('exclusiveMinimum', $value, $schema, $path, $i);
3940
$this->checkForKeyword('maxItems', $value, $schema, $path, $i);
4041
$this->checkForKeyword('maxLength', $value, $schema, $path, $i);
4142
$this->checkForKeyword('exclusiveMaximum', $value, $schema, $path, $i);
4243
$this->checkForKeyword('enum', $value, $schema, $path, $i);
4344
$this->checkForKeyword('const', $value, $schema, $path, $i);
45+
$this->checkForKeyword('multipleOf', $value, $schema, $path, $i);
4446
}
4547

4648
protected function checkForKeyword(string $keyword, $value, $schema = null, ?JsonPointer $path = null, $i = null): void

src/JsonSchema/Constraints/Drafts/Draft06/ExclusiveMaximumConstraint.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = n
2525
return;
2626
}
2727

28+
if (!is_numeric($value)) {
29+
return;
30+
}
31+
2832
if ($value < $schema->exclusiveMaximum) {
2933
return;
3034
}

src/JsonSchema/Constraints/Drafts/Draft06/ExclusiveMinimumConstraint.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = n
2525
return;
2626
}
2727

28+
if (!is_numeric($value)) {
29+
return;
30+
}
31+
2832
if ($value > $schema->exclusiveMinimum) {
2933
return;
3034
}

src/JsonSchema/Constraints/Drafts/Draft06/Factory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ class Factory extends \JsonSchema\Constraints\Factory
2020
'minProperties' => MinPropertiesConstraint::class,
2121
'maxProperties' => MaxPropertiesConstraint::class,
2222
'minimum' => MinimumConstraint::class,
23+
'maximum' => MaximumConstraint::class,
2324
'exclusiveMinimum' => ExclusiveMinimumConstraint::class,
2425
'minLength' => MinLengthConstraint::class,
2526
'maxLength' => MaxLengthConstraint::class,
2627
'maxItems' => MaxItemsConstraint::class,
2728
'exclusiveMaximum' => ExclusiveMaximumConstraint::class,
29+
'multipleOf' => MultipleOfConstraint::class,
2830
];
2931
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft06;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Constraints\Factory;
10+
use JsonSchema\Entity\ErrorBagProxy;
11+
use JsonSchema\Entity\JsonPointer;
12+
13+
class MaximumConstraint implements ConstraintInterface
14+
{
15+
use ErrorBagProxy;
16+
17+
public function __construct(?Factory $factory = null)
18+
{
19+
$this->initialiseErrorBag($factory ?: new Factory());
20+
}
21+
22+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
23+
{
24+
if (!property_exists($schema, 'maximum')) {
25+
return;
26+
}
27+
28+
if ($value <= $schema->maximum) {
29+
return;
30+
}
31+
32+
$this->addError(ConstraintError::MAXIMUM(), $path, ['maximum' => $schema->maximum, 'found' => $value]);
33+
}
34+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft06;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Constraints\Factory;
10+
use JsonSchema\Entity\ErrorBagProxy;
11+
use JsonSchema\Entity\JsonPointer;
12+
13+
class MultipleOfConstraint implements ConstraintInterface
14+
{
15+
use ErrorBagProxy;
16+
17+
public function __construct(?Factory $factory = null)
18+
{
19+
$this->initialiseErrorBag($factory ?: new Factory());
20+
}
21+
22+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
23+
{
24+
if (!property_exists($schema, 'multipleOf')) {
25+
return;
26+
}
27+
28+
if (!is_numeric($value)) {
29+
return;
30+
}
31+
32+
if (fmod($value, $schema->multipleOf) === 0) {
33+
return;
34+
}
35+
36+
$this->addError(ConstraintError::MULTIPLE_OF(), $path, ['multipleOf' => $schema->multipleOf, 'found' => $value]);
37+
38+
39+
}
40+
}

src/JsonSchema/Constraints/Drafts/Draft06/TypeConstraint.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = n
2626
}
2727

2828
$schemaTypes = (array) $schema->type;
29-
$valueType = gettype($value);
29+
$valueType = strtolower(gettype($value));
30+
if ($valueType === 'double' || $valueType === 'integer') {
31+
$valueType = 'number';
32+
}
33+
// @todo 1.0 is considered an integer but also number
34+
3035

3136
foreach ($schemaTypes as $type) {
3237
if ($valueType === $type) {

0 commit comments

Comments
 (0)