SchemaAttributeValidation::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
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\ConstraintViolationListInterface;
19
20
class SchemaAttributeValidation implements ValidationInterface
21
{
22
    protected array $properties;
23
24
    protected array $requiredProperties = [
25
        Keyword::NAME,
26
        Keyword::DATATYPE,
27
    ];
28
29
    private array $allowedProperties = [
30
        Keyword::NAME,
31
        Keyword::DATATYPE,
32
        Keyword::TYPE,
33
        Keyword::CONSTRAINTS,
34
    ];
35
36
    /**
37
     * @var array<string>
38
     */
39
    private array $validators = [
40
        Keyword::NAME => PropertyNameValidator::class,
41
        Keyword::DATATYPE => PropertyDataTypeValidator::class,
42
        Keyword::TYPE => PropertyTypeValidator::class,
43
        Keyword::CONSTRAINTS => PropertyConstraintsValidator::class,
44
    ];
45
46 515
    public function __construct(array $properties)
47
    {
48 515
        $this->properties = $properties;
49 515
    }
50
51 515
    public function validate(): void
52
    {
53 515
        $this->validateAllowedProperties();
54
55 514
        $this->validateRequiredProperties();
56
57 513
        $this->validateRulesProperties();
58 417
    }
59
60 515
    private function validateAllowedProperties(): void
61
    {
62 515
        $notAllowedProperties = \array_filter(\array_keys($this->properties), function ($name) {
63 515
            return !\in_array($name, $this->allowedProperties);
64 515
        });
65
66 515
        if (!empty($notAllowedProperties)) {
67 1
            throw new InvalidSchemaAttributeException('Properties unknow: ' . \implode(', ', $notAllowedProperties));
68
        }
69 514
    }
70
71 514
    private function validateRequiredProperties(): void
72
    {
73 514
        $requiredProperties = \array_filter($this->requiredProperties, function ($requiredProperty) {
74 514
            return !array_key_exists($requiredProperty, $this->properties);
75 514
        });
76
77 514
        if (!empty($requiredProperties)) {
78 1
            throw new InvalidSchemaAttributeException(
79 1
                'Required properties are missing: ' . \implode(', ', $requiredProperties)
80
            );
81
        }
82 513
    }
83
84 513
    private function validateRulesProperties(): void
85
    {
86 513
        foreach ($this->properties as $property => $value) {
87 513
            if (array_key_exists($property, $this->validators)) {
88 513
                $violations = $this->validateProperty($property, $value);
89
90 513
                if (\count($violations) > 0) {
91 97
                    $valueProperty = \is_array($value) ? \json_encode($value) : $value;
92
93 97
                    throw new InvalidSchemaAttributeException(
94 97
                        \sprintf(
95 97
                            '%1$s: [%2$s] %3$s',
96 97
                            $property,
97 97
                            $valueProperty,
98 97
                            (string)$violations->get(0)->getMessage()
99
                        )
100
                    );
101
                }
102
            }
103
        }
104 417
    }
105
106
    /**
107
     * @param mixed $value
108
     */
109 513
    private function validateProperty(string $property, $value): ConstraintViolationListInterface
110
    {
111 513
        $validator = new $this->validators[$property];
112
113 513
        return $validator->validate($value);
114
    }
115
}
116