Passed
Push — feature/initial-implementation ( 3b7c72...40c5a6 )
by Fike
01:49
created

Validator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
dl 0
loc 76
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A validateInternal() 0 8 1
A validate() 0 8 1
A validateType() 0 11 2
B validateParameters() 0 27 5
A validateProperties() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AmaTeam\ElasticSearch\Mapping;
6
7
use AmaTeam\ElasticSearch\API\Mapping\MappingInterface;
8
use AmaTeam\ElasticSearch\API\Mapping\Validation\ContextInterface;
9
use AmaTeam\ElasticSearch\API\Mapping\Validation\DefaultContext;
10
use AmaTeam\ElasticSearch\API\Mapping\ValidatorInterface;
11
use AmaTeam\ElasticSearch\Mapping\Type\Infrastructure\Registry as TypeRegistry;
12
use AmaTeam\ElasticSearch\Mapping\Type\Parameter\Infrastructure\Registry as ParameterRegistry;
13
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ApplicableParameter;
14
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ExistingParameter;
15
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ExistingType;
16
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ValidParameterName;
17
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ValidTypeName;
18
use Symfony\Component\Validator\Constraints\NotNull;
19
use Symfony\Component\Validator\ConstraintViolationListInterface;
20
use Symfony\Component\Validator\Validation;
21
use Symfony\Component\Validator\Validator\ContextualValidatorInterface;
22
23
class Validator implements ValidatorInterface
24
{
25
26
    public function validate(
27
        MappingInterface $mapping,
28
        ContextInterface $context = null
29
    ): ConstraintViolationListInterface {
30
        $validator = Validation::createValidator()->startContext();
31
        $context = $context ?? new DefaultContext();
32
        $this->validateInternal($validator, $mapping, $context);
33
        return $validator->getViolations();
34
    }
35
36
    private function validateInternal(
37
        ContextualValidatorInterface $validator,
38
        MappingInterface $mapping,
39
        ContextInterface $context
40
    ): void {
41
        $this->validateType($validator, $mapping, $context);
42
        $this->validateParameters($validator, $mapping, $context);
43
        $this->validateProperties($validator, $mapping, $context);
44
    }
45
46
    private function validateType(
47
        ContextualValidatorInterface $validator,
48
        MappingInterface $mapping,
49
        ContextInterface $context
50
    ): void {
51
        $path = array_merge($context->getPath(), ['type']);
52
        $validator->atPath(implode('.', $path));
53
        $type = TypeRegistry::getInstance()->find($mapping->getType());
54
        $validator->validate($mapping->getType(), new ExistingType());
55
        if ($type) {
56
            $validator->validate($mapping->getType(), new ValidTypeName(['id' => $type->getId()]));
57
        }
58
    }
59
60
    private function validateParameters(
61
        ContextualValidatorInterface $validator,
62
        MappingInterface $mapping,
63
        ContextInterface $context
64
    ): void {
65
        foreach ($mapping->getParameters() as $name => $value) {
66
            $path = array_merge($context->getPath(), [$name]);
67
            $validator->atPath(implode('.', $path));
68
            if (!$context->shouldIgnoreUnknownParameters()) {
69
                $validator->validate($name, new ExistingParameter());
70
            }
71
            $parameter = ParameterRegistry::getInstance()->find($name);
72
            if (!$parameter) {
73
                continue;
74
            }
75
            $validator->validate(
76
                $name,
77
                [
78
                    new ValidParameterName(['id' => $parameter->getId()]),
79
                    new ApplicableParameter(['parameter' => $name, 'type' => $mapping->getType()])
80
                ]
81
            );
82
            $constraints = $parameter->getConstraints();
83
            if (!$parameter->nullValueAllowed()) {
84
                $constraints[] = new NotNull();
85
            }
86
            $validator->validate($value, $constraints);
87
        }
88
    }
89
90
    private function validateProperties(
91
        ContextualValidatorInterface $validator,
92
        MappingInterface $mapping,
93
        ContextInterface $context
94
    ): void {
95
        foreach ($mapping->getProperties() as $name => $property) {
96
            $path = array_merge($context->getPath(), ['properties', $name]);
97
            $innerContext = DefaultContext::from($context)->setPath($path);
98
            $this->validateInternal($validator, $property, $innerContext);
99
        }
100
    }
101
}
102