Passed
Push — dev ( 40f0b5...3a2e98 )
by Fike
02:50
created

Validator::validateParameters()   C

Complexity

Conditions 7
Paths 11

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
c 0
b 0
f 0
rs 6.7272
cc 7
eloc 14
nc 11
nop 3
1
<?php
2
3
namespace AmaTeam\ElasticSearch\Mapping;
4
5
use AmaTeam\ElasticSearch\API\Mapping\Validation\Context;
6
use AmaTeam\ElasticSearch\API\Mapping\Validation\ContextInterface;
7
use AmaTeam\ElasticSearch\Mapping\Type\Parameter\Infrastructure\Registry as Parameters;
8
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ApplicableParameter;
9
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ValidParameterName;
10
use AmaTeam\ElasticSearch\Mapping\Validation\Constraint\ValidTypeName;
11
use AmaTeam\ElasticSearch\API\Mapping\ValidatorInterface;
12
use AmaTeam\ElasticSearch\API\MappingInterface;
13
use Symfony\Component\Validator\Constraints\NotNull;
14
use Symfony\Component\Validator\ConstraintViolationListInterface;
15
use Symfony\Component\Validator\Validation;
16
use Symfony\Component\Validator\Validator\ContextualValidatorInterface;
17
18
class Validator implements ValidatorInterface
19
{
20
    public function validate(
21
        MappingInterface $mapping,
22
        ContextInterface $context = null
23
    ): ConstraintViolationListInterface {
24
        $context = $context ? Context::from($context) : new Context();
25
        $validator = Validation::createValidator()->startContext();
26
        $this->validateInternal($mapping, $validator, $context);
27
        return $validator->getViolations();
28
    }
29
30
    private function validateInternal(
31
        MappingInterface $mapping,
32
        ContextualValidatorInterface $validator,
33
        Context $context
34
    ): void {
35
        $this->validateType($mapping, $validator, $context);
36
        $this->validateParameters($mapping, $validator, $context);
37
        $this->validateProperties($mapping, $validator, $context);
38
    }
39
40
    private function validateType(
41
        MappingInterface $mapping,
42
        ContextualValidatorInterface $validator,
43
        Context $context
44
    ): void {
45
        $segments = array_merge($context->getPath(), ['type']);
46
        $path = implode('.', $segments);
47
        $validator->atPath($path);
48
        $validator->validate($mapping->getType(), [new ValidTypeName()]);
49
    }
50
51
    private function validateParameters(
52
        MappingInterface $mapping,
53
        ContextualValidatorInterface $validator,
54
        Context $context
55
    ): void {
56
        foreach ($mapping->getParameters() as $name => $value) {
57
            $segments = array_merge($context->getPath(), [$name]);
58
            $validator->atPath(implode('.', $segments));
59
            $parameter = Parameters::getInstance()->find($name);
60
            if ($parameter || !$context->shouldPreserveUnknownParameters()) {
61
                $validator->validate($name, new ValidParameterName());
62
            }
63
            if (!$parameter) {
64
                continue;
65
            }
66
            if ($mapping->getType()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mapping->getType() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
67
                $validator->validate($name, new ApplicableParameter(['type' => $mapping->getType()]));
68
            }
69
            $constraints = $parameter->getConstraints();
70
            if (!$parameter->nullValueAllowed()) {
71
                $constraints[] = new NotNull();
72
            }
73
            $validator->validate($value, $constraints);
74
        }
75
    }
76
77
    private function validateProperties(
78
        MappingInterface $mapping,
79
        ContextualValidatorInterface $validator,
80
        Context $context
81
    ): void {
82
        foreach ($mapping->getProperties() as $name => $property) {
83
            $innerContext = $context->withAppendedPath('properties', $name);
84
            $this->validateInternal($property, $validator, $innerContext);
85
        }
86
    }
87
}
88