Validator   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 265
Duplicated Lines 0 %

Test Coverage

Coverage 56.52%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 144
c 6
b 0
f 0
dl 0
loc 265
ccs 65
cts 115
cp 0.5652
rs 9.76
wmc 33

8 Methods

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