Completed
Push — master ( 1bff1a...f9631c )
by Shcherbak
02:38
created

Query   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 291
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

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 81
cts 81
cp 1
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 typeIs() 0 10 1
A typeNot() 0 10 1
A valueIs() 0 9 1
A valueNot() 0 10 1
A valueLike() 0 21 4
A indexIs() 0 10 1
A indexNot() 0 9 1
A indexGt() 0 10 1
A indexLt() 0 9 1
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 357
    public static function create() {
58 357
      return new static();
59
    }
60
61
62
    /**
63
     * @param int|array $type Array<Int>|Int
64
     * @return $this
65
     */
66 216
    public function typeIs($type) {
67
68 216
      $types = $this->prepareIntValues($type);
69
70
      $this->checkFunctions[] = function (Token $token) use ($types) {
71 216
        return in_array($token->getType(), $types, true);
72
      };
73
74 210
      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 3
      $types = $this->prepareIntValues($type);
85
86
      $this->checkFunctions[] = function (Token $token) use ($types) {
87 3
        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 306
    public function valueIs($value) {
99 306
      $values = $this->prepareValues($value);
100
101
      $this->checkFunctions[] = function (Token $token) use ($values) {
102 306
        return in_array($token->getValue(), $values, true);
103
      };
104
105 306
      return $this;
106
    }
107
108
109
    /**
110
     * @param array|string $value Array<String>|String
111
     * @return $this
112
     */
113 9
    public function valueNot($value) {
114
115 9
      $values = $this->prepareValues($value);
116
117
      $this->checkFunctions[] = function (Token $token) use ($values) {
118 3
        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 99
    public function valueLike($regex) {
130 99
      $regexConditions = $this->prepareValues($regex);
131
132
      $this->checkFunctions[] = function (Token $token) use ($regexConditions) {
133 96
        if (empty($regexConditions)) {
134 3
          return false;
135
        }
136
137 96
        $value = $token->getValue();
138
139 96
        foreach ($regexConditions as $regex) {
140 96
          if (!preg_match($regex, $value)) {
141 44
            return false;
142
          }
143 64
        }
144
145 96
        return true;
146
      };
147
148 99
      return $this;
149
    }
150
151
152
    /**
153
     * @param int|int[] $index
154
     * @return $this
155
     */
156 9
    public function indexIs($index) {
157
158 9
      $indexNumbers = $this->prepareIntValues($index);
159
160
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
161 9
        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 3
      $indexNumbers = $this->prepareIntValues($index);
174
175
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
176 3
        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 3
    public function indexGt($index) {
188 3
      $indexNumbers = $this->prepareIntValues($index);
189
190
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
191 3
        return ($token->getIndex() > max($indexNumbers));
192
      };
193
194
195 3
      return $this;
196
    }
197
198
199
    /**
200
     * @param int|int[] $index
201
     * @return $this
202
     */
203 3
    public function indexLt($index) {
204 3
      $indexNumbers = $this->prepareIntValues($index);
205
206 3
      $this->checkFunctions[] = function (Token $token) use ($indexNumbers) {
207 3
        return ($token->getIndex() < min($indexNumbers));
208
      };
209
210 3
      return $this;
211
    }
212
213
214
    /**
215
     * @inheritdoc
216
     */
217 366
    public function isValid(\Funivan\PhpTokenizer\Token $token) {
218
219 366
      foreach ($this->checkFunctions as $check) {
220
221 363
        $result = $check($token);
222 363
        if (!is_bool($result)) {
223 3
          throw new Exception('Check function should return boolean value. Given:' . gettype($result));
224
        }
225
226 360
        if ($result === false) {
227 348
          return false;
228
        }
229
230 224
      }
231
232 330
      return true;
233
    }
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 318
    protected function prepareValues($value) {
242
243 318
      if ($value === null) {
244 33
        return [];
245
      }
246
247 309
      if (is_object($value)) {
248 3
        throw new InvalidArgumentException('Invalid conditions. Must be string or array of string');
249
      }
250
251 306
      $value = array_values((array) $value);
252
253 306
      foreach ($value as $k => $val) {
254 306
        if (!is_string($val) and !is_numeric($val)) {
255 3
          throw new InvalidArgumentException('Invalid conditions. Must be string');
256
        }
257
258 303
        $value[$k] = (string) $val;
259 202
      }
260 303
      return $value;
261
    }
262
263
264
    /**
265
     * @param array|int $value Array<Int>|Int
266
     * @return array
267
     * @throws \Exception
268
     */
269 234
    protected function prepareIntValues($value) {
270
271 234
      if ($value === null) {
272 3
        return [];
273
      }
274
275 231
      if (is_object($value)) {
276 3
        throw new InvalidArgumentException('Invalid condition value. Must be int. Object given');
277
      }
278
279 228
      $value = array_values((array) $value);
280
281
282 228
      foreach ($value as $intValue) {
283 228
        if (!is_int($intValue)) {
284 78
          throw new InvalidArgumentException('Invalid conditions. Must be integer. Given:' . gettype($intValue));
285
        }
286 150
      }
287
288 225
      return $value;
289
    }
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
    }
302
303
  }