Passed
Push — develop ( 3c29f3...131cab )
by Mathieu
01:35
created

Validator   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 259
Duplicated Lines 0 %

Test Coverage

Coverage 40.88%

Importance

Changes 0
Metric Value
eloc 142
dl 0
loc 259
ccs 56
cts 137
cp 0.4088
rs 9.52
c 0
b 0
f 0
wmc 36

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getErrors() 0 7 3
A pass() 0 3 1
A callValidate() 0 23 6
A validate() 0 22 5
A fails() 0 3 1
A __construct() 0 5 1
C createChecks() 0 127 11
B __call() 0 43 8
1
<?php declare(strict_types=1);
2
namespace Suricate;
3
4
/**
5
 * Validator
6
 * Inspired from Kieron Wilson PHP Validator
7
 *
8
 * @method Validator true(mixed $toTest)
9
 * @method Validator false(mixed $toTest)
10
 * @author      Mathieu LESNIAK <[email protected]>
11
 * @copyright   Mathieu LESNIAK
12
 * @package     Suricate
13
 */
14
class Validator
15
{
16
    private $errors = [];
17
    private $checks = [];
18
    private $datas;
19
    private $value;
20
    private $index;
21
    private $stop = false;
22
23 12
    public function __construct($input)
24
    {
25 12
        $this->datas = $input;
26 12
        $this->value = $input;
27 12
        $this->createChecks();
28 12
    }
29
30
    private function createChecks()
31
    {
32 1
        $this->checks['equalTo'] = function ($value, $compare) {
33 1
            return $value == $compare;
34
        };
35
36 1
        $this->checks['identicalTo'] = function ($value, $compare) {
37 1
            return $value === $compare;
38
        };
39
40 1
        $this->checks['lessThan'] = function ($value, $compare) {
41 1
            return $value < $compare;
42
        };
43
44 1
        $this->checks['lessThanOrEqual'] = function ($value, $compare) {
45 1
            return $value <= $compare;
46
        };
47
48 1
        $this->checks['greaterThan'] = function ($value, $compare) {
49 1
            return $value > $compare;
50
        };
51
52 1
        $this->checks['greaterThanOrEqual'] = function ($value, $compare) {
53 1
            return $value >= $compare;
54
        };
55
56 1
        $this->checks['blank'] = function ($value) {
57 1
            return $value == '';
58
        };
59
60 1
        $this->checks['null'] = function ($value) {
61 1
            return is_null($value);
62
        };
63
64 1
        $this->checks['true'] = function ($value) {
65 1
            return $value === true;
66
        };
67
68 1
        $this->checks['false'] = function ($value) {
69 1
            return !($value === true);
70
        };
71
72 1
        $this->checks['type'] = function ($value, $type) {
73
            switch ($type) {
74 1
                case 'array':
75 1
                    return is_array($value);
76 1
                case 'bool':
77 1
                    return is_bool($value);
78
                case 'callable':
79
                    return is_callable($value);
80
                case 'float':
81
                    return is_float($value);
82
                case 'int':
83
                    return is_int($value);
84
                case 'numeric':
85
                    return is_numeric($value);
86
                case 'object':
87
                    return is_object($value);
88
                case 'resource':
89
                    return is_resource($value);
90
                case 'scalar':
91
                    return is_scalar($value);
92
                case 'string':
93
                    return is_string($value);
94
                default:
95
                    throw new \InvalidArgumentException('Unknown type to check ' . $type);
96
            }
97
        };
98
99
        $this->checks['email'] = function ($value) {
100
            return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
101
        };
102
103
        $this->checks['url'] = function ($value) {
104
            return filter_var($value, FILTER_VALIDATE_URL) !== false;
105
        };
106
107
        $this->checks['ip'] = function ($value) {
108
            return filter_var($value, FILTER_VALIDATE_IP) !== false;
109
        };
110
111
        $this->checks['regexp'] = function ($value, $regexp) {
112
            return filter_var($value, FILTER_VALIDATE_REGEXP, $regexp) !== false;
113
        };
114
115
        $this->checks['longerThan'] = function ($value, $length) {
116
            return strlen($value) > $length;
117
        };
118
119
        $this->checks['longerThanOrEqual'] = function ($value, $length) {
120
            return strlen($value) >= $length;
121
        };
122
123
        $this->checks['shorterThan'] = function ($value, $length) {
124
            return strlen($value) < $length;
125
        };
126
127
        $this->checks['shortThanOrEqual'] = function ($value, $length) {
128
            return strlen($value) <= $length;
129
        };
130
131
        $this->checks['contains'] = function ($value, $toFind) {
132
            return strpos($value, $toFind) !== false;
133
        };
134
        
135 1
        $this->checks['alnum'] = function ($value) {
136 1
            return ctype_alnum($value);
137
        };
138
139
        $this->checks['alpha'] = function ($value) {
140
            return ctype_alpha($value);
141
        };
142
143
        $this->checks['digit'] = function ($value) {
144
            return ctype_digit($value);
145
        };
146
        
147
        $this->checks['lower'] = function ($value) {
148
            return ctype_lower($value);
149
        };
150
151
        $this->checks['upper'] = function ($value) {
152
            return ctype_upper($value);
153
        };
154
155
        $this->checks['space'] = function ($value) {
156
            return ctype_space($value);
157
        };
158 12
    }
159
160
    public function validate($index = null)
161
    {
162
        if ($index === null) {
163
            $this->value = $this->datas;
164
            $this->index = null;
165
            return $this;
166
        }
167
168
        if (is_object($this->datas) && isset($this->datas->$index)) {
169
            $this->value = $this->datas->$index;
170
            $this->index = $index;
171
172
            return $this;
173
        } 
174
        if (array_key_exists($index, $this->datas)) {
175
            $this->value = $this->datas[$index];
176
            $this->index = $index;
177
178
            return $this;
179
        }
180
        
181
        throw new \InvalidArgumentException('Index / Property "' . $index . '" does not exists');
182
    }
183
184
    public function callValidate()
185
    {
186
        $args = func_get_args();
187
        if (count($args) < 1) {
188
            throw new \InvalidArgumentException('bad number of arguments');
189
        }
190
        
191
        $method = array_shift($args);
192
        // Object method
193
        if (is_array($method) || is_string($method)) {
194
            $this->index = null;
195
            $this->value = call_user_func_array($method, $args);
196
197
            return $this;
198
        }
199
200
        if (is_object($method) && ($method instanceof \Closure)) {
201
            $this->index = null;
202
            $this->value = call_user_func_array($method, $args);
203
204
            return $this;
205
        }
206
        throw new \InvalidArgumentException('Bad method');
207
208
    }
209
210 12
    public function __call($method, $parameters)
211
    {
212 12
        if (!$this->stop) {
213
            // Stop on error, ignore others tests if fails
214 12
            if (substr($method, 0, 4) == 'stop') {
215
                $stopOnError = true;
216
                $method = lcFirst(substr($method, 4));
217
            } else {
218 12
                $stopOnError = false;
219
            }
220
221
            // Negation check
222 12
            if (substr(strtolower($method), 0, 3) == 'not') {
223
                $negation   = true;
224
                $method     = lcFirst(substr($method, 3));
225
            } else {
226 12
                $negation = false;
227
            }
228
229 12
            if (!isset($this->checks[$method])) {
230
                throw new \BadMethodCallException('Unknown check ' . $method);
231
            } else {
232 12
                $validator = $this->checks[$method];
233
            }
234
235 12
            $errorMessage = array_pop($parameters);
236
237 12
            array_unshift($parameters, $this->value);
238
239 12
            $validation = (bool) (call_user_func_array($validator, $parameters) ^ $negation);
240 12
            if (!$validation) {
241 7
                if ($stopOnError) {
242
                    $this->stop = true;
243
                }
244 7
                if ($this->index === null) {
245 7
                    $this->errors[] = $errorMessage;
246
                } else {
247
                    $this->errors[$this->index][] = $errorMessage;
248
                }
249
            }
250
        }
251
252 12
        return $this;
253
    }
254
255 2
    public function getErrors($index = null)
256
    {
257
258 2
        if ($index === null) {
259 2
            return $this->errors;
260
        } else {
261
            return isset($this->errors[$index]) ? $this->errors[$index] : array();
262
        }
263
    }
264
265 12
    public function pass()
266
    {
267 12
        return count($this->errors) == 0;
268
    }
269
270 7
    public function fails()
271
    {
272 7
        return !$this->pass();
273
    }
274
}
275