Completed
Push — master ( 93f6e0...a7ea34 )
by Aydin
27:25 queued 18:55
created

Validator::__call()   C

Complexity

Conditions 11
Paths 48

Size

Total Lines 50
Code Lines 36

Duplication

Lines 6
Ratio 12 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 6
loc 50
rs 5.4894
cc 11
eloc 36
nc 48
nop 2

How to fix   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
2
/**
3
 * Klein (klein.php) - A fast & flexible router for PHP
4
 *
5
 * @author      Chris O'Hara <[email protected]>
6
 * @author      Trevor Suarez (Rican7) (contributor and v2 refactorer)
7
 * @copyright   (c) Chris O'Hara
8
 * @link        https://github.com/chriso/klein.php
9
 * @license     MIT
10
 */
11
12
namespace Klein;
13
14
use BadMethodCallException;
15
use Klein\Exceptions\ValidationException;
16
17
/**
18
 * Validator 
19
 */
20
class Validator
21
{
22
23
    /**
24
     * Class properties
25
     */
26
27
    /**
28
     * The available validator methods
29
     *
30
     * @type array
31
     */
32
    public static $methods = array();
33
34
    /**
35
     * The string to validate
36
     *
37
     * @type string
38
     */
39
    protected $str;
40
41
    /**
42
     * The custom exception message to throw on validation failure
43
     *
44
     * @type string
45
     */
46
    protected $err;
47
48
    /**
49
     * Flag for whether the default validation methods have been added or not
50
     *
51
     * @type boolean
52
     */
53
    protected static $defaultAdded = false;
54
55
56
    /**
57
     * Methods
58
     */
59
60
    /**
61
     * Sets up the validator chain with the string and optional error message
62
     *
63
     * @param string $str   The string to validate
64
     * @param string $err   The optional custom exception message to throw on validation failure
65
     */
66
    public function __construct($str, $err = null)
67
    {
68
        $this->str = $str;
69
        $this->err = $err;
70
71
        if (!static::$defaultAdded) {
72
            static::addDefault();
73
        }
74
    }
75
76
    /**
77
     * Adds default validators on first use
78
     *
79
     * @return void
80
     */
81
    public static function addDefault()
82
    {
83
        static::$methods['null'] = function ($str) {
84
            return $str === null || $str === '';
85
        };
86
        static::$methods['len'] = function ($str, $min, $max = null) {
87
            $len = strlen($str);
88
            return null === $max ? $len === $min : $len >= $min && $len <= $max;
89
        };
90
        static::$methods['int'] = function ($str) {
91
            return (string)$str === ((string)(int)$str);
92
        };
93
        static::$methods['float'] = function ($str) {
94
            return (string)$str === ((string)(float)$str);
95
        };
96
        static::$methods['email'] = function ($str) {
97
            return filter_var($str, FILTER_VALIDATE_EMAIL) !== false;
98
        };
99
        static::$methods['url'] = function ($str) {
100
            return filter_var($str, FILTER_VALIDATE_URL) !== false;
101
        };
102
        static::$methods['ip'] = function ($str) {
103
            return filter_var($str, FILTER_VALIDATE_IP) !== false;
104
        };
105
        static::$methods['remoteip'] = function ($str) {
106
            return filter_var($str, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false;
107
        };
108
        static::$methods['alnum'] = function ($str) {
109
            return ctype_alnum($str);
110
        };
111
        static::$methods['alpha'] = function ($str) {
112
            return ctype_alpha($str);
113
        };
114
        static::$methods['contains'] = function ($str, $needle) {
115
            return strpos($str, $needle) !== false;
116
        };
117
        static::$methods['regex'] = function ($str, $pattern) {
118
            return preg_match($pattern, $str);
119
        };
120
        static::$methods['chars'] = function ($str, $chars) {
121
            return preg_match("/^[$chars]++$/i", $str);
122
        };
123
124
        static::$defaultAdded = true;
125
    }
126
127
    /**
128
     * Add a custom validator to our list of validation methods
129
     *
130
     * @param string $method        The name of the validator method
131
     * @param callable $callback    The callback to perform on validation
132
     * @return void
133
     */
134
    public static function addValidator($method, $callback)
135
    {
136
        static::$methods[strtolower($method)] = $callback;
137
    }
138
139
    /**
140
     * Magic "__call" method
141
     *
142
     * Allows the ability to arbitrarily call a validator with an optional prefix
143
     * of "is" or "not" by simply calling an instance property like a callback
144
     *
145
     * @param string $method            The callable method to execute
146
     * @param array $args               The argument array to pass to our callback
147
     * @throws BadMethodCallException   If an attempt was made to call a validator modifier that doesn't exist
148
     * @throws ValidationException      If the validation check returns false
149
     * @return Validator|boolean
150
     */
151
    public function __call($method, $args)
152
    {
153
        $reverse = false;
154
        $validator = $method;
155
        $method_substr = substr($method, 0, 2);
156
157
        if ($method_substr === 'is') {       // is<$validator>()
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
158
            $validator = substr($method, 2);
159
        } elseif ($method_substr === 'no') { // not<$validator>()
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
160
            $validator = substr($method, 3);
161
            $reverse = true;
162
        }
163
164
        $validator = strtolower($validator);
165
166
        if (!$validator || !isset(static::$methods[$validator])) {
167
            throw new BadMethodCallException('Unknown method '. $method .'()');
168
        }
169
170
        $validator = static::$methods[$validator];
171
        array_unshift($args, $this->str);
172
173
        switch (count($args)) {
174
            case 1:
175
                $result = $validator($args[0]);
176
                break;
177
            case 2:
178
                $result = $validator($args[0], $args[1]);
179
                break;
180 View Code Duplication
            case 3:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
                $result = $validator($args[0], $args[1], $args[2]);
182
                break;
183 View Code Duplication
            case 4:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
                $result = $validator($args[0], $args[1], $args[2], $args[3]);
185
                break;
186
            default:
187
                $result = call_user_func_array($validator, $args);
188
                break;
189
        }
190
191
        $result = (bool)($result ^ $reverse);
192
193
        if (false === $this->err) {
194
            return $result;
195
        } elseif (false === $result) {
196
            throw new ValidationException($this->err);
197
        }
198
199
        return $this;
200
    }
201
}
202