Passed
Push — develop ( 49a79e...3c29f3 )
by Mathieu
01:43
created

Validator::__call()   B

Complexity

Conditions 8
Paths 25

Size

Total Lines 43
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 9.8033

Importance

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