Completed
Push — develop ( 0660be...71868c )
by Freddie
04:14
created

AttributeValidation::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 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 18
c 1
b 0
f 0
nc 48
nop 0
dl 0
loc 33
ccs 19
cts 19
cp 1
crap 10
rs 7.6666

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