Completed
Push — master ( 7bebed...2fd43b )
by Lars
01:41
created

ValidatorRulesManager::is_serialized()   C

Complexity

Conditions 24
Paths 199

Size

Total Lines 68
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 46.8193

Importance

Changes 0
Metric Value
dl 0
loc 68
c 0
b 0
f 0
ccs 29
cts 44
cp 0.6591
rs 5.1966
cc 24
eloc 46
nc 199
nop 2
crap 46.8193

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
namespace voku\HtmlFormValidator;
4
5
use Respect\Validation\Rules\AbstractRule;
6
use voku\helper\UTF8;
7
8
class ValidatorRulesManager
9
{
10
11
  /**
12
   * @var string[]|AbstractRule[]
13
   */
14
  private $rules = [];
15
16
  /**
17
   * @param string              $name
18
   * @param string|AbstractRule $validatorClassName
19
   */
20 3
  public function addCustomRule(string $name, $validatorClassName)
21
  {
22 3
    $this->rules[$name] = $validatorClassName;
23 3
  }
24
25
  /**
26
   * @param string $rule
27
   *
28
   * @return array <p>keys: 'class', 'classArgs', 'object'</p>
29
   */
30 18
  public function getClassViaAlias(string $rule): array
31
  {
32 18
    if (!$rule) {
33
      return [
34
          'class'     => null,
35
          'classArgs' => null,
36
          'object'    => null,
37
      ];
38
    }
39
40 18
    if (isset($this->rules[$rule])) {
41 2
      $classWithNamespace = $this->rules[$rule];
42
    } else {
43 18
      $classWithNamespace = $rule;
44
    }
45
46 18
    if ($classWithNamespace instanceof AbstractRule) {
47
48
      return [
49 1
          'class'     => null,
50
          'classArgs' => null,
51 1
          'object'    => $classWithNamespace,
52
      ];
53
    }
54
55 18
    if (\strpos($classWithNamespace, "\\") !== false) {
56
      $class =
57 4
          \substr(
58 4
              \strrchr(
59 4
                  $classWithNamespace,
60 4
                  "\\"
61
              ),
62 4
              1
63
64
          );
65
    } else {
66 18
      $class = $classWithNamespace;
67
    }
68
69 18
    $class = \lcfirst(\trim($class));
70
71 18
    $classArgsMatches = [];
72 18
    \preg_match('/\((?<args>.*?)\)$/', $class, $classArgsMatches);
73 18
    $class = \preg_replace('/\((.*?)\)$/', '', $class);
74
75 18
    $classArgs = [];
76 18
    if (isset($classArgsMatches['args'])) {
77 9
      $classArgsTmp = $classArgsMatches['args'];
78
79 9
      if ($this->is_serialized($classArgsTmp, $classArgsTmpUnserialized)) {
80
81 3
        $classArgs = [$classArgsTmpUnserialized];
82
83
      } else {
84
85 7
        $classArgsTmpArray = explode(',', $classArgsTmp);
86 7
        foreach ($classArgsTmpArray as $classArgsTmp) {
87 7
          $classArg = trim($classArgsTmp);
88
89 7
          if ($classArg === 'true' || $classArg === 'false') {
90
            $classArg = (bool)$classArg;
91 7
          } else if ($classArgs === 'null') {
92
            $classArg = null;
93
          }
94
95 7
          $classArgs[] = $classArg;
96
        }
97
98
      }
99
    }
100
101
    return [
102 18
        'class'     => $class,
103 18
        'classArgs' => (\count($classArgs) !== 0 ? $classArgs : null),
104
        'object'    => null,
105
    ];
106
  }
107
108
109
  /**
110
   * Tests if an input is valid PHP serialized string.
111
   *
112
   * Checks if a string is serialized using quick string manipulation
113
   * to throw out obviously incorrect strings. Unserialize is then run
114
   * on the string to perform the final verification.
115
   *
116
   * Valid serialized forms are the following:
117
   * <ul>
118
   * <li>boolean: <code>b:1;</code></li>
119
   * <li>integer: <code>i:1;</code></li>
120
   * <li>double: <code>d:0.2;</code></li>
121
   * <li>string: <code>s:4:"test";</code></li>
122
   * <li>array: <code>a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}</code></li>
123
   * <li>object: <code>O:8:"stdClass":0:{}</code></li>
124
   * <li>null: <code>N;</code></li>
125
   * </ul>
126
   *
127
   * @author     Chris Smith <[email protected]>
128
   * @copyright  Copyright (c) 2009 Chris Smith (http://www.cs278.org/)
129
   * @license    http://sam.zoy.org/wtfpl/ WTFPL
130
   *
131
   * @param    string $value  Value to test for serialized form
132
   * @param    mixed  $result Result of unserialize() of the $value
133
   *
134
   * @return    boolean      True if $value is serialized data, otherwise false
135
   */
136 9
  private function is_serialized($value, &$result = null): bool
137
  {
138
    // Bit of a give away this one
139 9
    if (!\is_string($value)) {
140
      return false;
141
    }
142
143
    // Serialized false, return true. unserialize() returns false on an
144
    // invalid string or it could return false if the string is serialized
145
    // false, eliminate that possibility.
146 9
    if ($value === 'b:0;') {
147
      $result = false;
148
149
      return true;
150
    }
151
152 9
    $length = UTF8::strlen($value);
153 9
    $end = '';
154 9
    switch ($value[0]) {
155 9
      case 's':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
156
        if ($value[$length - 2] !== '"') {
157
          return false;
158
        }
159 9
      case 'b':
160 9
      case 'i':
161 9
      case 'd':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
162
        // This looks odd but it is quicker than isset()ing
163
        $end .= ';';
164 9
      case 'a':
165 7
      case 'O':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
166 3
        $end .= '}';
167 3
        if ($value[1] !== ':') {
168
          return false;
169
        }
170 3
        switch ($value[2]) {
171 3
          case 0:
172 3
          case 1:
173 3
          case 2:
174 3
          case 3:
175 1
          case 4:
176 1
          case 5:
177
          case 6:
178
          case 7:
179
          case 8:
180
          case 9:
181 3
            break;
182
          default:
183
            return false;
184
        }
185 7
      case 'N':
186 3
        $end .= ';';
187 3
        if ($value[$length - 1] !== $end[0]) {
188
          return false;
189
        }
190 3
        break;
191
      default:
192 7
        return false;
193
    }
194
195
    /** @noinspection PhpUsageOfSilenceOperatorInspection */
196 3
    if (($result = @unserialize($value, [])) === false) {
197
      $result = null;
198
199
      return false;
200
    }
201
202 3
    return true;
203
  }
204
205
}
206