Check::valid()   C
last analyzed

Complexity

Conditions 13
Paths 39

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
nc 39
nop 2
dl 0
loc 54
rs 6.6166
c 0
b 0
f 0

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
2
3
/**
4
 * Check
5
 *
6
 * Validate a data map against defined methods.
7
 *
8
 * @package core
9
 * @author [email protected]
10
 * @copyright Caffeina srl - 2015 - http://caffeina.com
11
 */
12
13
class Check {
14
  use Module, Events;
15
16
  protected static $methods = [],
17
                   $errors  = [];
18
  public static    $data    = [];
19
20
  public static function valid($rules, $data){
21
    static::$errors = [];
22
    static::triggerOnce('init');
23
    self::$data = ($data = (array)$data);
24
25
    foreach ((array)$rules as $field_name => $rule) {
26
27
      $current = isset($data[$field_name]) ? $data[$field_name] : null;
28
29
      if (is_callable($rule)){
30
        static::$errors[$field_name] = call_user_func($rule,$current);
31
        continue;
32
      } elseif (is_string($rule)) {
33
        $current_rules = array_flip(preg_split('/\s*\|\s*/', $rule));
34
      } else {
35
        $current_rules = (array)$rule;
36
      }
37
38
      static::$errors[$field_name] = true;
39
40
      foreach($current_rules as $method => $message) {
41
42
        $meth_name = strtok($method, ':');
43
        $opts      = strtok(':') ?: '';
44
        $opts      = $opts ? json_decode("[$opts]") : [];
45
        $meth_opts = $opts ? array_merge([$current], $opts) : [$current];
46
47
        if ( static::$errors[$field_name] !== true ) continue 2;
48
49
        if (empty(static::$methods[$meth_name])) {
50
          static::$errors[$field_name] = true;
51
        } else {
52
          if (call_user_func_array(static::$methods[$meth_name]->validate,$meth_opts)){
53
            static::$errors[$field_name] = true;
54
          } else {
55
            $arg = [];
56
            foreach ($meth_opts as $key => $value) {
57
              $arg["arg_$key"] = $value;
58
            }
59
            static::$errors[$field_name] = Text::render(static::$methods[$meth_name]->message,$arg);
60
          }
61
        }
62
      }
63
    }
64
65
    self::$data = [];
66
67
    // Clean non-errors
68
    static::$errors = array_filter(static::$errors,function($v){
69
      return $v !== true;
70
    });
71
72
    return empty(static::$errors);
73
  }
74
75
   public static function method($name, $definition = null){
76
    if (is_array($name)) {
77
      foreach ($name as $method_name => $method_definition){
78
        if (is_callable($method_definition)) $method_definition = ['validate' => $method_definition];
79
        if (empty($method_definition['validate']) || !is_callable($method_definition['validate'])) continue;
80
        $method_definition['message']  = Filter::with("core.check.error.$method_name",@$method_definition['message']?:'Field not valid.');
81
        static::$methods[$method_name] = (object)$method_definition;
82
      }
83
    } else {
84
      if (is_callable($definition)) $definition = ['validate' => $definition];
85
      if (empty($definition['validate']) || !is_callable($definition['validate'])) return;
86
      $methods['message']     = Filter::with("core.check.error.$name",@$methods['message']?:'Field not valid.');
0 ignored issues
show
Coding Style Comprehensibility introduced by
$methods was never initialized. Although not strictly required by PHP, it is generally a good practice to add $methods = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
Bug introduced by
The variable $methods seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
87
      static::$methods[$name] = (object)$definition;
88
    }
89
  }
90
91
  public static function errors() {
92
    return static::$errors;
93
  }
94
95
}
96
97
Check::on('init',function(){
98
99
  Check::method([
100
101
    'required' => [
102
      'validate' => function($value) {
103
          return (is_numeric($value) && $value==0) || !empty($value);
104
       },
105
       'message' => "This value cannot be empty.",
106
    ],
107
108
    'alphanumeric' => [
109
      'validate' => function($value) {
110
         return (bool)preg_match('/^[0-9a-zA-Z]+$/',$value);
111
      },
112
      'message' => "Value must be alphanumeric.",
113
    ],
114
115
    'numeric' => [
116
      'validate' => function($value) {
117
         return (bool)preg_match('/^\d+$/',$value);
118
      },
119
      'message' => "Value must be numeric.",
120
    ],
121
122
    'email' => [
123
      'validate' => function($value) {
124
         return (bool)filter_var($value, FILTER_VALIDATE_EMAIL);
125
      },
126
      'message' => "This is not a valid email.",
127
    ],
128
129
    'url' => [
130
      'validate' => function($value) {
131
         return (bool)filter_var($value, FILTER_VALIDATE_URL);
132
      },
133
      'message' => "This is not a valid URL.",
134
    ],
135
136
    'max' => [
137
      'validate' => function($value,$max) {
138
       return $value<=$max ? true : false;
139
    },
140
      'message' => "Value must be less than {{arg_1}}.",
141
    ],
142
143
    'min' => [
144
      'validate' => function($value,$min) {
145
         return $value >= $min;
146
      },
147
      'message' => "Value must be greater than {{arg_1}}.",
148
    ],
149
150
    'range' => [
151
      'validate' => function($value,$min,$max) {
152
         return ( $value >= $min ) && ( $value <= $max );
153
      },
154
      'message' => "This value must be in [{{arg_1}},{{arg_2}}] range.",
155
    ],
156
157
    'words' => [
158
      'validate' => function($value,$max) {
159
         return str_word_count($value) <= $max;
160
      },
161
      'message' => "Too many words, max count is {{arg_1}}.",
162
    ],
163
164
    'length' => [
165
      'validate' => function($value,$length) {
166
         return strlen($value) == $length;
167
      },
168
      'message' => "This value must be {{arg_1}} characters.",
169
    ],
170
171
    'min_length' => [
172
      'validate' => function($value,$min) {
173
         return strlen($value) >= $min;
174
      },
175
      'message' => "Too few characters, min count is {{arg_1}}.",
176
    ],
177
178
    'max_length' => [
179
      'validate' => function($value,$max) {
180
         return strlen($value) <= $max;
181
      },
182
      'message' => "Too many characters, max count is {{arg_1}}.",
183
    ],
184
185
    'true' => [
186
      'validate' => function($value) {
187
         return (bool)$value;
188
      },
189
      'message' => "This value must be true.",
190
    ],
191
192
    'false' => [
193
      'validate' => function($value) {
194
         return !$value;
195
      },
196
      'message' => "This value must be false.",
197
    ],
198
199
    'same_as' => [
200
      'validate' => function($value,$fieldname) {
201
       $x = isset(Check::$data[$fieldname]) ? Check::$data[$fieldname] : '';
202
         return $value == $x;
203
      },
204
      'message' => "Field must be equal to {{arg_1}}.",
205
    ],
206
207
    'in_array' => [
208
      'validate' => function($value,$array_values) {
209
         return  in_array($value, $array_values);
210
      },
211
      'message' => "This value is forbidden.",
212
    ],
213
214
  ]);
215
216
});
217
218