Passed
Push — develop ( b21b17...91ba7c )
by Mathieu
02:21
created

Validator::createChecks()   C

Complexity

Conditions 11
Paths 1

Size

Total Lines 127
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 14.6926

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 74
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 127
ccs 33
cts 48
cp 0.6875
crap 14.6926
rs 6.4206

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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