Skip to content

Commit 36bbcb3

Browse files
committed
feat: Copy draft07 from draft06 to get started
1 parent 2d90217 commit 36bbcb3

34 files changed

+1813
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Entity\ErrorBagProxy;
10+
use JsonSchema\Entity\JsonPointer;
11+
12+
class AdditionalItemsConstraint implements ConstraintInterface
13+
{
14+
use ErrorBagProxy;
15+
16+
/** @var Factory */
17+
private $factory;
18+
19+
public function __construct(?Factory $factory = null)
20+
{
21+
$this->factory = $factory ?: new Factory();
22+
$this->initialiseErrorBag($this->factory);
23+
}
24+
25+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
26+
{
27+
if (!property_exists($schema, 'additionalItems')) {
28+
return;
29+
}
30+
31+
if ($schema->additionalItems === true) {
32+
return;
33+
}
34+
if ($schema->additionalItems === false && !property_exists($schema, 'items')) {
35+
return;
36+
}
37+
38+
if (!is_array($value)) {
39+
return;
40+
}
41+
if (!property_exists($schema, 'items')) {
42+
return;
43+
}
44+
if (property_exists($schema, 'items') && is_object($schema->items)) {
45+
return;
46+
}
47+
48+
$additionalItems = array_diff_key($value, property_exists($schema, 'items') ? $schema->items : []);
49+
50+
foreach ($additionalItems as $propertyName => $propertyValue) {
51+
$schemaConstraint = $this->factory->createInstanceFor('schema');
52+
$schemaConstraint->check($propertyValue, $schema->additionalItems, $path, $i);
53+
54+
if ($schemaConstraint->isValid()) {
55+
continue;
56+
}
57+
58+
$this->addError(ConstraintError::ADDITIONAL_ITEMS(), $path, ['item' => $i, 'property' => $propertyName, 'additionalItems' => $schema->additionalItems]);
59+
}
60+
}
61+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Entity\ErrorBagProxy;
10+
use JsonSchema\Entity\JsonPointer;
11+
12+
class AdditionalPropertiesConstraint implements ConstraintInterface
13+
{
14+
use ErrorBagProxy;
15+
16+
/** @var Factory */
17+
private $factory;
18+
19+
public function __construct(?Factory $factory = null)
20+
{
21+
$this->factory = $factory ?: new Factory();
22+
$this->initialiseErrorBag($this->factory);
23+
}
24+
25+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
26+
{
27+
if (!property_exists($schema, 'additionalProperties')) {
28+
return;
29+
}
30+
31+
if ($schema->additionalProperties === true) {
32+
return;
33+
}
34+
35+
if (!is_object($value)) {
36+
return;
37+
}
38+
39+
$additionalProperties = get_object_vars($value);
40+
41+
if (isset($schema->properties)) {
42+
$additionalProperties = array_diff_key($additionalProperties, (array) $schema->properties);
43+
}
44+
45+
if (isset($schema->patternProperties)) {
46+
$patterns = array_keys(get_object_vars($schema->patternProperties));
47+
48+
foreach ($additionalProperties as $key => $_) {
49+
foreach ($patterns as $pattern) {
50+
if (preg_match($this->createPregMatchPattern($pattern), (string) $key)) {
51+
unset($additionalProperties[$key]);
52+
break;
53+
}
54+
}
55+
}
56+
}
57+
58+
if (is_object($schema->additionalProperties)) {
59+
foreach ($additionalProperties as $key => $additionalPropertiesValue) {
60+
$schemaConstraint = $this->factory->createInstanceFor('schema');
61+
$schemaConstraint->check($additionalPropertiesValue, $schema->additionalProperties, $path, $i); // @todo increment path
62+
if ($schemaConstraint->isValid()) {
63+
unset($additionalProperties[$key]);
64+
}
65+
}
66+
}
67+
68+
foreach ($additionalProperties as $key => $additionalPropertiesValue) {
69+
$this->addError(ConstraintError::ADDITIONAL_PROPERTIES(), $path, ['found' => $additionalPropertiesValue]);
70+
}
71+
}
72+
73+
private function createPregMatchPattern(string $pattern): string
74+
{
75+
$replacements = [
76+
// '\D' => '[^0-9]',
77+
// '\d' => '[0-9]',
78+
'\p{digit}' => '\p{Nd}',
79+
// '\w' => '[A-Za-z0-9_]',
80+
// '\W' => '[^A-Za-z0-9_]',
81+
// '\s' => '[\s\x{200B}]' // Explicitly include zero width white space,
82+
'\p{Letter}' => '\p{L}', // Map ECMA long property name to PHP (PCRE) Unicode property abbreviations
83+
];
84+
85+
$pattern = str_replace(
86+
array_keys($replacements),
87+
array_values($replacements),
88+
$pattern
89+
);
90+
91+
return '/' . str_replace('/', '\/', $pattern) . '/u';
92+
}
93+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Entity\ErrorBagProxy;
10+
use JsonSchema\Entity\JsonPointer;
11+
12+
class AllOfConstraint implements ConstraintInterface
13+
{
14+
use ErrorBagProxy;
15+
16+
/** @var Factory */
17+
private $factory;
18+
19+
public function __construct(?Factory $factory = null)
20+
{
21+
$this->factory = $factory ?: new Factory();
22+
$this->initialiseErrorBag($this->factory);
23+
}
24+
25+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
26+
{
27+
if (!property_exists($schema, 'allOf')) {
28+
return;
29+
}
30+
31+
foreach ($schema->allOf as $allOfSchema) {
32+
$schemaConstraint = $this->factory->createInstanceFor('schema');
33+
$schemaConstraint->check($value, $allOfSchema, $path, $i);
34+
35+
if ($schemaConstraint->isValid()) {
36+
continue;
37+
}
38+
$this->addError(ConstraintError::ALL_OF(), $path);
39+
$this->addErrors($schemaConstraint->getErrors());
40+
}
41+
}
42+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Entity\ErrorBagProxy;
10+
use JsonSchema\Entity\JsonPointer;
11+
use JsonSchema\Exception\ValidationException;
12+
13+
class AnyOfConstraint implements ConstraintInterface
14+
{
15+
use ErrorBagProxy;
16+
17+
/** @var Factory */
18+
private $factory;
19+
20+
public function __construct(?Factory $factory = null)
21+
{
22+
$this->factory = $factory ?: new Factory();
23+
$this->initialiseErrorBag($this->factory);
24+
}
25+
26+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
27+
{
28+
if (!property_exists($schema, 'anyOf')) {
29+
return;
30+
}
31+
32+
foreach ($schema->anyOf as $anyOfSchema) {
33+
$schemaConstraint = $this->factory->createInstanceFor('schema');
34+
35+
try {
36+
$schemaConstraint->check($value, $anyOfSchema, $path, $i);
37+
38+
if ($schemaConstraint->isValid()) {
39+
$this->errorBag()->reset();
40+
41+
return;
42+
}
43+
44+
$this->addErrors($schemaConstraint->getErrors());
45+
} catch (ValidationException $e) {
46+
}
47+
}
48+
49+
$this->addError(ConstraintError::ANY_OF(), $path);
50+
}
51+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
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+
use JsonSchema\Tool\DeepComparer;
13+
14+
class ConstConstraint implements ConstraintInterface
15+
{
16+
use ErrorBagProxy;
17+
18+
public function __construct(?Factory $factory = null)
19+
{
20+
$this->initialiseErrorBag($factory ?: new Factory());
21+
}
22+
23+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
24+
{
25+
if (!property_exists($schema, 'const')) {
26+
return;
27+
}
28+
29+
if (DeepComparer::isEqual($value, $schema->const)) {
30+
return;
31+
}
32+
33+
$this->addError(ConstraintError::CONSTANT(), $path, ['const' => $schema->const]);
34+
}
35+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Entity\ErrorBagProxy;
10+
use JsonSchema\Entity\JsonPointer;
11+
12+
class ContainsConstraint implements ConstraintInterface
13+
{
14+
use ErrorBagProxy;
15+
16+
/** @var Factory */
17+
private $factory;
18+
19+
public function __construct(?Factory $factory = null)
20+
{
21+
$this->factory = $factory ?: new Factory();
22+
$this->initialiseErrorBag($this->factory);
23+
}
24+
25+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
26+
{
27+
if (!property_exists($schema, 'contains')) {
28+
return;
29+
}
30+
31+
$properties = [];
32+
if (!is_array($value)) {
33+
return;
34+
}
35+
36+
foreach ($value as $propertyName => $propertyValue) {
37+
$schemaConstraint = $this->factory->createInstanceFor('schema');
38+
39+
$schemaConstraint->check($propertyValue, $schema->contains, $path, $i);
40+
if ($schemaConstraint->isValid()) {
41+
return;
42+
}
43+
}
44+
45+
$this->addError(ConstraintError::CONTAINS(), $path, ['contains' => $schema->contains]);
46+
}
47+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JsonSchema\Constraints\Drafts\Draft07;
6+
7+
use JsonSchema\ConstraintError;
8+
use JsonSchema\Constraints\ConstraintInterface;
9+
use JsonSchema\Entity\ErrorBagProxy;
10+
use JsonSchema\Entity\JsonPointer;
11+
12+
class DependenciesConstraint implements ConstraintInterface
13+
{
14+
use ErrorBagProxy;
15+
16+
/** @var Factory */
17+
private $factory;
18+
19+
public function __construct(?Factory $factory = null)
20+
{
21+
$this->factory = $factory ?: new Factory();
22+
$this->initialiseErrorBag($this->factory);
23+
}
24+
25+
public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = null): void
26+
{
27+
if (!property_exists($schema, 'dependencies')) {
28+
return;
29+
}
30+
31+
if (!is_object($value)) {
32+
return;
33+
}
34+
35+
foreach ($schema->dependencies as $dependant => $dependencies) {
36+
if (!property_exists($value, $dependant)) {
37+
continue;
38+
}
39+
if ($dependencies === true) {
40+
continue;
41+
}
42+
if ($dependencies === false) {
43+
$this->addError(ConstraintError::FALSE(), $path, ['dependant' => $dependant]);
44+
continue;
45+
}
46+
47+
if (is_array($dependencies)) {
48+
foreach ($dependencies as $dependency) {
49+
if (property_exists($value, $dependant) && !property_exists($value, $dependency)) {
50+
$this->addError(ConstraintError::DEPENDENCIES(), $path, ['dependant' => $dependant, 'dependency' => $dependency]);
51+
}
52+
}
53+
}
54+
55+
if (is_object($dependencies)) {
56+
$schemaConstraint = $this->factory->createInstanceFor('schema');
57+
$schemaConstraint->check($value, $dependencies, $path, $i);
58+
if (!$schemaConstraint->isValid()) {
59+
$this->addErrors($schemaConstraint->getErrors());
60+
}
61+
}
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)