Completed
Push — master ( 5f0c82...b81315 )
by Philip
02:17
created

Validator::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 0 Features 5
Metric Value
c 8
b 0
f 5
dl 0
loc 24
rs 8.9713
cc 1
eloc 22
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Valdi package.
5
 *
6
 * (c) Philip Lehmann-Böhm <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Valdi;
13
14
use Valdi\Validator\ValidatorInterface;
15
16
/**
17
 * The Validator is used to chain Validators together and validate a set of data
18
 * with it.
19
 */
20
class Validator {
21
22
    /**
23
     * Holds the available validators.
24
     */
25
    protected $availableValidators;
26
27
    /**
28
     * Creates instances of the available validators.
29
     *
30
     * @param array $validators
31
     * the validators to load, key = name, value = classname within the
32
     * namespace "\Valdi\Validator"
33
     */
34
    protected function createValidators(array $validators) {
35
        $this->availableValidators = array();
36
        foreach ($validators as $name => $type) {
37
            $class = '\\Valdi\\Validator\\' . $type;
38
            $this->availableValidators[$name] = new $class();
39
        }
40
    }
41
42
    /**
43
     * Validates a single rule.
44
     *
45
     * @param string $validator
46
     * the validator to use
47
     * @param string[] $parameters
48
     * the validation parameters, depending on the validator
49
     * @param string $value
50
     * the value to validate
51
     *
52
     * @return boolean
53
     * true if the value is valid
54
     */
55
    protected function validateRule($validator, $parameters, $value) {
56
        if (!array_key_exists($validator, $this->availableValidators)) {
57
            throw new ValidatorException('"' . $validator . '" not found as available validator.');
58
        }
59
        return $this->availableValidators[$validator]->validate($value, $parameters);
60
    }
61
62
    /**
63
     * Validates a value via the given rules.
64
     *
65
     * @param array $fieldRules
66
     * the validation rules
67
     * @param string $value
68
     * the value to validate
69
     *
70
     * @return string[]
71
     * the fields where the validation failed
72
     */
73
    protected function validateField($fieldRules, $value) {
74
        $result = array();
75
        foreach ($fieldRules as $rule) {
76
            $name = $rule;
77
            $parameters = array();
78
            if (is_array($rule)) {
79
                $parameters = $rule;
80
                $name = array_shift($parameters);
81
            }
82
            $valid = $this->validateRule($name, $parameters, $value);
83
            if (!$valid) {
84
                $result[] = $name;
85
            }
86
        }
87
        return $result;
88
    }
89
90
    /**
91
     * Constructor.
92
     */
93
    public function __construct() {
94
        $validators = array(
95
            'between' => 'Between',
96
            'boolean' => 'Boolean',
97
            'dateTime' => 'DateTime',
98
            'email' => 'Email',
99
            'floating' => 'Floating',
100
            'inSet' => 'InSet',
101
            'integer' => 'Integer',
102
            'ip' => 'IP',
103
            'ipv4' => 'IPv4',
104
            'ipv6' => 'IPv6',
105
            'lengthBetween' => 'LengthBetween',
106
            'max' => 'Max',
107
            'maxLength' => 'MaxLength',
108
            'min' => 'Min',
109
            'minLength' => 'MinLength',
110
            'regexp' => 'Regexp',
111
            'required' => 'Required',
112
            'url' => 'Url',
113
            'value' => 'Value'
114
        );
115
        $this->createValidators($validators);
116
    }
117
118
    /**
119
     * Adds additional validator. It can override existing validators as well.
120
     *
121
     * @param string $name
122
     * the name of the new validator.
123
     * @param ValidatorInterface $validator
124
     * the validator to add
125
     */
126
    public function addValidator($name, ValidatorInterface $validator) {
127
        $this->availableValidators[$name] = $validator;
128
    }
129
130
    /**
131
     * Performs the actual validation.
132
     *
133
     * @param array $rules
134
     * the validation rules: an array with a field name as key and an array
135
     * of rules to use for this field; each rule is either a string with the
136
     * validator name or an array with the validator name as first element and
137
     * parameters as following elements; example:
138
     * array('a' => array('required'), 'b' => array(array('min', 1)))
139
     * @param array $data
140
     * the data to validate as a map
141
     *
142
     * @return array
143
     * the validation result having the keys "valid" (true or false) and
144
     * the key "errors" containing all failed fields as keys with arrays of the
145
     * failed validator names; example where the field "b" from the above sample
146
     * failed due to the min validator:
147
     * array('valid' => false, errors => array('b' => array('min')))
148
     */
149
    public function validate(array $rules, array $data) {
150
        $errors = array();
151
        foreach ($rules as $field => $fieldRules) {
152
            $value = isset($data[$field]) ? $data[$field] : null;
153
            $fieldErrors = $this->validateField($fieldRules, $value);
154
            if (!empty($fieldErrors)) {
155
                $errors[$field] = $fieldErrors;
156
            }
157
        }
158
        return array(
159
            'valid' => count($errors) === 0,
160
            'errors' => $errors
161
        );
162
    }
163
164
}
165