Completed
Push — develop ( 93c875...c90588 )
by Freddie
05:45
created

SchemaAttributeValidation::validate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of FlexPHP.
4
 *
5
 * (c) Freddie Gar <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace FlexPHP\Schema\Validations;
11
12
use FlexPHP\Schema\Constants\Keyword;
13
use FlexPHP\Schema\Exception\InvalidSchemaAttributeException;
14
use FlexPHP\Schema\Validators\PropertyConstraintsValidator;
15
use FlexPHP\Schema\Validators\PropertyDataTypeValidator;
16
use FlexPHP\Schema\Validators\PropertyNameValidator;
17
use FlexPHP\Schema\Validators\PropertyTypeValidator;
18
use Symfony\Component\Validator\ConstraintViolationList;
19
20
class SchemaAttributeValidation implements ValidationInterface
21
{
22
    /**
23
     * @var array
24
     */
25
    protected $properties;
26
27
    /**
28
     * @var array
29
     */
30
    protected $requiredProperties = [
31
        Keyword::NAME,
32
        Keyword::DATATYPE,
33
    ];
34
35
    /**
36
     * @var array
37
     */
38
    private $allowedProperties = [
39
        Keyword::NAME,
40
        Keyword::DATATYPE,
41
        Keyword::TYPE,
42
        Keyword::CONSTRAINTS,
43
    ];
44
45
    /**
46
     * @var array<string>
47
     */
48
    private $validators = [
49
        Keyword::NAME => PropertyNameValidator::class,
50
        Keyword::DATATYPE => PropertyDataTypeValidator::class,
51
        Keyword::TYPE => PropertyTypeValidator::class,
52
        Keyword::CONSTRAINTS => PropertyConstraintsValidator::class,
53
    ];
54
55 103
    public function __construct(array $properties)
56
    {
57 103
        $this->properties = $properties;
58 103
    }
59
60 103
    public function validate(): void
61
    {
62 103
        $this->validateAllowedProperties();
63
64 102
        $this->validateRequiredProperties();
65
66 100
        $this->validateRulesProperties();
67 60
    }
68
69 100
    private function validateRulesProperties(): void
70
    {
71 100
        foreach ($this->properties as $property => $value) {
72 100
            if (\in_array($property, \array_keys($this->validators))) {
73 100
                $violations = $this->validateProperty($property, $value);
74
75 100
                if (0 !== \count($violations)) {
76 100
                    throw new InvalidSchemaAttributeException(\sprintf("%1\$s:\n%2\$s", $property, $violations));
77
                }
78
            }
79
        }
80 60
    }
81
82 103
    private function validateAllowedProperties(): void
83
    {
84 103
        $notAllowedProperties = [];
85
86 103
        foreach ($this->properties as $name => $value) {
87 103
            if (!\in_array($name, $this->allowedProperties)) {
88 103
                $notAllowedProperties[] = $name;
89
            }
90
        }
91
92 103
        if (!empty($notAllowedProperties)) {
93 1
            throw new InvalidSchemaAttributeException('Properties unknow: ' . \implode(', ', $notAllowedProperties));
94
        }
95 102
    }
96
97 102
    private function validateRequiredProperties(): void
98
    {
99 102
        $requiredPropertiesNotPresent = [];
100
101 102
        foreach ($this->requiredProperties as $property) {
102 102
            if (!\in_array($property, \array_keys($this->properties))) {
103 102
                $requiredPropertiesNotPresent[] = $property;
104
            }
105
        }
106
107 102
        if (!empty($requiredPropertiesNotPresent)) {
108 3
            throw new InvalidSchemaAttributeException(
109 3
                'Required properties are missing: ' . \implode(', ', $requiredPropertiesNotPresent)
110
            );
111
        }
112 100
    }
113
114
    /**
115
     * @param mixed $value
116
     */
117 100
    private function validateProperty(string $property, $value): ConstraintViolationList
118
    {
119 100
        $validator = new $this->validators[$property];
120
121 100
        return $validator->validate($value);
122
    }
123
}
124