Completed
Push — master ( 5844c1...ab7dfd )
by Shcherbak
02:28
created

Query   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 291
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 98.86%

Importance

Changes 14
Bugs 5 Features 3
Metric Value
wmc 29
c 14
b 5
f 3
lcom 1
cbo 3
dl 0
loc 291
ccs 87
cts 88
cp 0.9886
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 3 1
A isValid() 0 17 4
A custom() 0 4 1
A typeNot() 0 10 1
A valueNot() 0 10 1
A indexIs() 0 10 1
A indexNot() 0 9 1
A indexGt() 0 10 1
A indexLt() 0 9 1
A typeIs() 0 10 1
A valueIs() 0 9 1
A valueLike() 0 21 4
B prepareValues() 0 21 6
B prepareIntValues() 0 21 5
1
<?php
2
3
4
  namespace Funivan\PhpTokenizer\Query;
5
6
  use Funivan\PhpTokenizer\Exception\Exception;
7
  use Funivan\PhpTokenizer\Exception\InvalidArgumentException;
8
  use Funivan\PhpTokenizer\Token;
9
10
  /**
11
   * @author Ivan Shcherbak <[email protected]>
12
   */
13
  class Query implements QueryInterface {
14
15
16
    /**
17
     * Array of check functions
18
     * As first argument accept token
19
     * Return boolean
20
     *
21
     * @var callable[]
22
     */
23
    protected $checkFunctions = [];
24
25
    /**
26
     * Storage of type conditions
27
     *
28
     * @var array
29
     */
30
    protected $type = [];
31
32
    /**
33
     * Storage of conditions conditions
34
     *
35
     * @var array
36
     */
37
    protected $value = [];
38
39
    /**
40
     * Storage of line conditions
41
     *
42
     * @var array
43
     */
44
    protected $line = [];
45
46
    /**
47
     * Storage of index conditions
48
     *
49
     * @var array
50
     */
51
    protected $index = [];
52
53
54
    /**
55
     * @return static
56
     */
57 222
    public static function create() {
58 222
      return new static();
59
    }
60
61
62
    /**
63
     * @param int|array $type Array<Int>|Int
64
     * @return $this
65
     */
66 150
    public function typeIs($type) {
67
68 146
      $types = $this->prepareIntValues($type);
69
70
      $this->checkFunctions[] = function (Token $token) use ($types) {
71 144
        return in_array($token->getType(), $types, true);
72 2
      };
73
74 146
      return $this;
75
    }
76
77
78
    /**
79
     * @param array|int $type Array<Int>|Int
80
     * @return $this
81
     */
82 3
    public function typeNot($type) {
83
84 2
      $types = $this->prepareIntValues($type);
85
86
      $this->checkFunctions[] = function (Token $token) use ($types) {
87 2
        return !in_array($token->getType(), $types, true);
88
      };
89
90 3
      return $this;
91
    }
92
93
94
    /**
95
     * @param array|string $value Array<String>|String
96
     * @return $this
97
     */
98 197
    public function valueIs($value) {
99 188
      $values = $this->prepareValues($value);
100
101
      $this->checkFunctions[] = function (Token $token) use ($values) {
102 188
        return in_array($token->getValue(), $values, true);
103
      };
104
105 197
      return $this;
106
    }
107
108
109
    /**
110
     * @param array|string $value Array<String>|String
111
     * @return $this
112
     */
113 8
    public function valueNot($value) {
114
115 8
      $values = $this->prepareValues($value);
116
117
      $this->checkFunctions[] = function (Token $token) use ($values) {
118 2
        return !in_array($token->getValue(), $values, true);
119
      };
120
121 3
      return $this;
122
    }
123
124
125
    /**
126
     * @param array|string $regex Array<String>|String
127
     * @return $this
128
     */
129 82
    public function valueLike($regex) {
130 66
      $regexConditions = $this->prepareValues($regex);
131
132
      $this->checkFunctions[] = function (Token $token) use ($regexConditions) {
133 71
        if (empty($regexConditions)) {
134 2
          return false;
135
        }
136
137 64
        $value = $token->getValue();
138
139 64
        foreach ($regexConditions as $regex) {
140 64
          if (!preg_match($regex, $value)) {
141 12
            return false;
142
          }
143 64
        }
144
145 72
        return true;
146 8
      };
147
148 82
      return $this;
149
    }
150
151
152
    /**
153
     * @param int|int[] $index
154
     * @return $this
155
     */
156 9
    public function indexIs($index) {
157
158 6
      $indexNumbers = $this->prepareIntValues($index);
159
160
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
161 6
        return in_array($token->getIndex(), $indexNumbers, true);
162
      };
163
164 9
      return $this;
165
    }
166
167
168
    /**
169
     * @param int|int[] $index
170
     * @return $this
171
     */
172 3
    public function indexNot($index) {
173 2
      $indexNumbers = $this->prepareIntValues($index);
174
175
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
176 2
        return !in_array($token->getIndex(), $indexNumbers, true);
177
      };
178
179 3
      return $this;
180
    }
181
182
183
    /**
184
     * @param int|int[] $index
185
     * @return $this
186
     */
187 2
    public function indexGt($index) {
188 2
      $indexNumbers = $this->prepareIntValues($index);
189
190
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
191 2
        return ($token->getIndex() > max($indexNumbers));
192
      };
193
194
195 2
      return $this;
196
    }
197
198
199
    /**
200
     * @param int|int[] $index
201
     * @return $this
202
     */
203 2
    public function indexLt($index) {
204 2
      $indexNumbers = $this->prepareIntValues($index);
205
206 2
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
207 2
        return ($token->getIndex() < min($indexNumbers));
208
      };
209
210 2
      return $this;
211
    }
212
213
214
    /**
215
     * @inheritdoc
216
     */
217 247
    public function isValid(\Funivan\PhpTokenizer\Token $token) {
218
219 247
      foreach ($this->checkFunctions as $check) {
220
221 226
        $result = $check($token);
222 226
        if (!is_bool($result)) {
223 2
          throw new Exception('Check function should return boolean value. Given:' . gettype($result));
224
        }
225
226 239
        if ($result === false) {
227 229
          return false;
228
        }
229
230 219
      }
231
232 219
      return true;
233 18
    }
234
235
236
    /**
237
     * @param string|int|array $value String|Int|Array<String>|Array<Int>
238
     * @return array Array<String>
239
     * @throws \Exception
240
     */
241 209
    protected function prepareValues($value) {
242
243 209
      if ($value === null) {
244 25
        return [];
245
      }
246
247 190
      if (is_object($value)) {
248 2
        throw new InvalidArgumentException('Invalid conditions. Must be string or array of string');
249
      }
250
251 188
      $value = array_values((array) $value);
252
253 188
      foreach ($value as $k => $val) {
254 188
        if (!is_string($val) and !is_numeric($val)) {
255 2
          throw new InvalidArgumentException('Invalid conditions. Must be string');
256
        }
257
258 194
        $value[$k] = (string) $val;
259 187
      }
260 194
      return $value;
261 1
    }
262
263
264
    /**
265
     * @param array|int $value Array<Int>|Int
266
     * @return array
267
     * @throws \Exception
268
     */
269 168
    protected function prepareIntValues($value) {
270
271 168
      if ($value === null) {
272 3
        return [];
273
      }
274
275 154
      if (is_object($value)) {
276 2
        throw new InvalidArgumentException('Invalid condition value. Must be int. Object given');
277
      }
278
279 152
      $value = array_values((array) $value);
280
281
282 152
      foreach ($value as $intValue) {
283 152
        if (!is_int($intValue)) {
284 2
          throw new InvalidArgumentException('Invalid conditions. Must be integer. Given:' . gettype($intValue));
285
        }
286 151
      }
287
288 159
      return $value;
289 1
    }
290
291
292
    /**
293
     * Under development
294
     *
295
     * @param callable $checkFunction
296
     * @return $this
297
     */
298 6
    public function custom(callable $checkFunction) {
299 6
      $this->checkFunctions[] = $checkFunction;
300 6
      return $this;
301 2
    }
302
303
  }