Completed
Push — develop ( 2e1df2...27dbda )
by Mathieu
03:22
created

Validator::callValidate()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 4
nop 0
dl 0
loc 21
ccs 0
cts 13
cp 0
crap 42
rs 9.2222
c 0
b 0
f 0
1
<?php
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 = array();
15
    private $checks = array();
16
    private $datas;
17
    private $value;
18
    private $index;
19
    private $stop = false;
20
21
    public function __construct($input)
22
    {
23
        $this->datas = $input;
24
        $this->value = $input;
25
        $this->createChecks();
26
    }
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
        $this->checks['true'] = function ($value) {
63
            return $value === true;
64
        };
65
66
        $this->checks['false'] = function ($value) {
67
            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
    }
157
158
    public function validate($index = null)
159
    {
160
        if ($index === null) {
161
            $this->value = $this->datas;
162
            $this->index = null;
163
        } else {
164
            if (is_object($this->datas) && isset($this->datas->$index)) {
165
                $this->value = $this->datas->$index;
166
                $this->index = $index;
167
            } elseif (array_key_exists($index, $this->datas)) {
168
                $this->value = $this->datas[$index];
169
                $this->index = $index;
170
            } else {
171
                throw new \InvalidArgumentException('Index / Property "' . $index . '" does not exists');
172
            }
173
        }
174
175
        return $this;
176
    }
177
178
    public function callValidate()
179
    {
180
        
181
        $args = func_get_args();
182
        if (count($args) < 1) {
183
            throw new \InvalidArgumentException('bad number of arguments');
184
        } else {
185
            $method = array_shift($args);
186
            // Object method
187
            if (is_array($method) || is_string($method)) {
188
                $this->index = null;
189
                $this->value = call_user_func_array($method, $args);
190
            } elseif (is_object($method) && ($method instanceof \Closure)) {
191
                $this->index = null;
192
                $this->value = call_user_func_array($method, $args);
193
            } else {
194
                throw new \InvalidArgumentException('Bad method');
195
            }
196
        }
197
198
        return $this;
199
    }
200
201
    public function __call($method, $parameters)
202
    {
203
        if (!$this->stop) {
204
            // Stop on error, ignore others tests if fails
205
            if (substr($method, 0, 4) == 'stop') {
206
                $stopOnError = true;
207
                $method = lcFirst(substr($method, 4));
208
            } else {
209
                $stopOnError = false;
210
            }
211
212
            // Negation check
213
            if (substr(strtolower($method), 0, 3) == 'not') {
214
                $negation   = true;
215
                $method     = lcFirst(substr($method, 3));
216
            } else {
217
                $negation = false;
218
            }
219
220
            if (!isset($this->checks[$method])) {
221
                throw new \BadMethodCallException('Unknown check ' . $method);
222
            } else {
223
                $validator = $this->checks[$method];
224
            }
225
226
            $errorMessage = array_pop($parameters);
227
228
            array_unshift($parameters, $this->value);
229
230
            $validation = (bool) (call_user_func_array($validator, $parameters) ^ $negation);
231
            if (!$validation) {
232
                if ($stopOnError) {
233
                    $this->stop = true;
234
                }
235
                if ($this->index === null) {
236
                    $this->errors[] = $errorMessage;
237
                } else {
238
                    $this->errors[$this->index][] = $errorMessage;
239
                }
240
            }
241
        }
242
243
        return $this;
244
    }
245
246
    public function getErrors($index = null)
247
    {
248
249
        if ($index === null) {
250
            return $this->errors;
251
        } else {
252
            return isset($this->errors[$index]) ? $this->errors[$index] : array();
253
        }
254
    }
255
256
    public function pass()
257
    {
258
        return count($this->errors) == 0;
259
    }
260
261
    public function fails()
262
    {
263
        return !$this->pass();
264
    }
265
}
266