Query::typeNot()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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