Completed
Push — develop ( 71868c...88717d )
by Freddie
03:24
created

SchemaAttributeValidation::validate()   B

Complexity

Conditions 10
Paths 48

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 10

Importance

Changes 0
Metric Value
cc 10
eloc 18
nc 48
nop 0
dl 0
loc 33
ccs 19
cts 19
cp 1
crap 10
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 Exception;
13
use FlexPHP\Schema\Constants\Keyword;
14
use FlexPHP\Schema\Exception\InvalidSchemaAttributeException;
15
use FlexPHP\Schema\Validators\PropertyConstraintsValidator;
16
use FlexPHP\Schema\Validators\PropertyDataTypeValidator;
17
use FlexPHP\Schema\Validators\PropertyNameValidator;
18
use FlexPHP\Schema\Validators\PropertyTypeValidator;
19
use Symfony\Component\Validator\ConstraintViolationList;
20
21
class SchemaAttributeValidation implements ValidationInterface
22
{
23
    /**
24
     * @var array
25
     */
26
    protected $properties;
27
28
    /**
29
     * @var array
30
     */
31
    protected $requiredProperties = [
32
        Keyword::NAME,
33
        Keyword::DATATYPE,
34
    ];
35
36
    /**
37
     * @var array
38
     */
39
    private $allowedProperties = [
40
        Keyword::NAME,
41
        Keyword::DATATYPE,
42
        Keyword::TYPE,
43
        Keyword::CONSTRAINTS,
44
    ];
45
46
    /**
47
     * @var array
48
     */
49
    private $validators = [
50
        Keyword::NAME        => PropertyNameValidator::class,
51
        Keyword::DATATYPE    => PropertyDataTypeValidator::class,
52
        Keyword::TYPE        => PropertyTypeValidator::class,
53
        Keyword::CONSTRAINTS => PropertyConstraintsValidator::class,
54
    ];
55
56 104
    public function __construct(array $properties)
57
    {
58 104
        $this->properties = $properties;
59 104
    }
60
61 104
    public function validate(): void
62
    {
63 104
        $notAllowedProperties         = [];
64 104
        $requiredPropertiesNotPresent = [];
65
66 104
        foreach ($this->properties as $name => $value) {
67 104
            if (!\in_array($name, $this->allowedProperties)) {
68 104
                $notAllowedProperties[] = $name;
69
            }
70
        }
71
72 104
        if (!empty($notAllowedProperties)) {
73 1
            throw new InvalidSchemaAttributeException('Properties unknow: ' . \implode(', ', $notAllowedProperties));
74
        }
75
76 103
        foreach ($this->requiredProperties as $property) {
77 103
            if (!\in_array($property, \array_keys($this->properties))) {
78 103
                $requiredPropertiesNotPresent[] = $property;
79
            }
80
        }
81
82 103
        if (!empty($requiredPropertiesNotPresent)) {
83 2
            throw new InvalidSchemaAttributeException(
84 2
                'Required properties are missing: ' . \implode(', ', $requiredPropertiesNotPresent)
85
            );
86
        }
87
88 102
        foreach ($this->properties as $property => $value) {
89 102
            if (\in_array($property, \array_keys($this->validators))) {
90 102
                $violations = $this->validateProperty($property, $value);
91
92 102
                if (0 !== \count($violations)) {
93 102
                    throw new InvalidSchemaAttributeException(\sprintf("%1\$s:\n%2\$s", $property, $violations));
94
                }
95
            }
96
        }
97 64
    }
98
99
    /**
100
     * @param string $property
101
     * @param mixed $value
102
     * @return ConstraintViolationList
103
     */
104 102
    private function validateProperty(string $property, $value): ConstraintViolationList
105
    {
106
        try {
107 102
            $validator  = new $this->validators[$property];
108 102
            $violations = $validator->validate($value);
109 1
        } catch (Exception $e) {
110 1
            throw new InvalidSchemaAttributeException(\sprintf('%1$s: %2$s', $property, $e->getMessage()));
111
        }
112
113 102
        return $violations;
114
    }
115
}
116