Completed
Push — master ( d27e1e...d6d70b )
by Hannes
01:43
created

ArrayValidator::addValidator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace hanneskod\clean;
6
7
/**
8
 * Validate arrays of input data
9
 */
10
final class ArrayValidator implements ValidatorInterface
11
{
12
    /**
13
     * @var array<string, ValidatorInterface>
14
     */
15
    private array $validators;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_ARRAY, expecting T_FUNCTION or T_CONST
Loading history...
16
    private bool $ignoreUnknown;
17
18
    /**
19
     * @param array<string, ValidatorInterface> $validators
20
     */
21
    public function __construct(array $validators = [], bool $ignoreUnknown = false)
22
    {
23
        $this->validators = $validators;
24
        $this->ignoreUnknown = $ignoreUnknown;
25
    }
26
27
    /**
28
     * Create a new validator flagged if unknown items should be ignored when validating
29
     */
30
    public function ignoreUnknown(bool $ignoreUnknown = true): ArrayValidator
31
    {
32
        return new static($this->validators, $ignoreUnknown);
33
    }
34
35
    public function applyTo($data): ResultInterface
36
    {
37
        if (!is_array($data)) {
38
            return new Invalid(new Exception("expecting array input"));
39
        }
40
41
        /** @var array<string, mixed> */
42
        $clean = [];
43
44
        /** @var array<string, string> */
45
        $errors = [];
46
47
        foreach ($this->validators as $name => $validator) {
48
            $result = $validator->applyTo($data[$name] ?? null);
49
50
            if ($result->isValid()) {
51
                $clean[$name] = $result->getValidData();
52
                continue;
53
            }
54
55
            $errors[$name] = implode("\n", $result->getErrors());
56
        }
57
58
        if (!$this->ignoreUnknown && $diff = array_diff_key($data, $this->validators)) {
59
            foreach (array_keys($diff) as $unknown) {
60
                $errors[(string)$unknown] = "Unknown input item $unknown";
61
            }
62
        }
63
64
        return new ArrayResult($clean, $errors);
65
    }
66
67
    public function validate($data)
68
    {
69
        $result = $this->applyTo($data);
70
71
        if ($result->isValid()) {
72
            return $result->getValidData();
73
        }
74
75
        $msg = '';
76
77
        foreach ($result->getErrors() as $name => $error) {
78
            $msg .= "$name: $error\n";
79
        }
80
81
        throw new Exception(trim($msg));
82
    }
83
}
84