Completed
Pull Request — master (#8)
by
unknown
02:38
created

Assert::inArray()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4

Importance

Changes 3
Bugs 0 Features 2
Metric Value
c 3
b 0
f 2
dl 0
loc 14
ccs 4
cts 4
cp 1
rs 9.2
cc 4
eloc 8
nc 4
nop 1
crap 4
1
<?php
2
/**
3
 * @link      https://github.com/ko-ko-ko/php-assert
4
 * @copyright Copyright (c) 2015 Roman Levishchenko <[email protected]>
5
 * @license   https://raw.github.com/ko-ko-ko/php-assert/master/LICENSE
6
 */
7
8
namespace KoKoKo\assert;
9
10
use KoKoKo\assert\exceptions\ArgumentException;
11
use KoKoKo\assert\exceptions\ArrayKeyNotExistsException;
12
use KoKoKo\assert\exceptions\InvalidArrayCountException;
13
use KoKoKo\assert\exceptions\InvalidArrayException;
14
use KoKoKo\assert\exceptions\InvalidBoolException;
15
use KoKoKo\assert\exceptions\InvalidDigitException;
16
use KoKoKo\assert\exceptions\InvalidEmptyException;
17
use KoKoKo\assert\exceptions\InvalidFloatException;
18
use KoKoKo\assert\exceptions\InvalidIntException;
19
use KoKoKo\assert\exceptions\InvalidIntOrFloatException;
20
use KoKoKo\assert\exceptions\InvalidIntOrFloatOrStringException;
21
use KoKoKo\assert\exceptions\InvalidIntOrStringException;
22
use KoKoKo\assert\exceptions\InvalidNotArrayException;
23
use KoKoKo\assert\exceptions\InvalidNotEmptyException;
24
use KoKoKo\assert\exceptions\InvalidNotNullException;
25
use KoKoKo\assert\exceptions\InvalidNotObjectException;
26
use KoKoKo\assert\exceptions\InvalidNotSameValueException;
27
use KoKoKo\assert\exceptions\InvalidNullException;
28
use KoKoKo\assert\exceptions\InvalidNumericException;
29
use KoKoKo\assert\exceptions\InvalidRegExpPatternException;
30
use KoKoKo\assert\exceptions\InvalidResourceException;
31
use KoKoKo\assert\exceptions\InvalidSameValueException;
32
use KoKoKo\assert\exceptions\InvalidStringException;
33
use KoKoKo\assert\exceptions\InvalidStringLengthException;
34
use KoKoKo\assert\exceptions\LengthNotBetweenException;
35
use KoKoKo\assert\exceptions\LengthNotGreaterException;
36
use KoKoKo\assert\exceptions\LengthNotLessException;
37
use KoKoKo\assert\exceptions\NumberNotBetweenException;
38
use KoKoKo\assert\exceptions\NumberNotBetweenStrictlyException;
39
use KoKoKo\assert\exceptions\NumberNotGreaterException;
40
use KoKoKo\assert\exceptions\NumberNotGreaterStrictlyException;
41
use KoKoKo\assert\exceptions\NumberNotLessException;
42
use KoKoKo\assert\exceptions\NumberNotLessStrictlyException;
43
use KoKoKo\assert\exceptions\NumberNotNegativeException;
44
use KoKoKo\assert\exceptions\NumberNotPositiveException;
45
use KoKoKo\assert\exceptions\StringNotMatchGlobException;
46
use KoKoKo\assert\exceptions\StringNotMatchRegExpException;
47
use KoKoKo\assert\exceptions\ValueNotInArrayException;
48
49
class Assert
50
{
51
    /** @var Assert */
52
    protected static $validator;
53
54
    /** @var string */
55
    protected static $exceptionClass;
56
57
    /** @var string */
58
    protected $name;
59
60
    /** @var int|float|bool|string|resource|array|null */
61
    protected $value;
62
63
    /**
64
     * Creates validator instance for variable, first fail check will throw an exception
65
     *
66
     * @param int|float|string|resource|array|null $value
67
     * @param string                               $name
68 133
     * @param null|string                          $exceptionClass
69
     * @return static
70 133
     * @throws InvalidNotObjectException
71 1
     * @throws InvalidStringException
72
     */
73
    public static function assert($value, $name = 'value', $exceptionClass = null)
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
74 132
    {
75 1
        if (is_object($value)) {
76
            throw new InvalidNotObjectException($name);
77
        }
78 131
79 1
        if (!is_string($name)) {
80 1
            throw new InvalidStringException('name', $name);
81
        }
82 131
83 131
        if ($exceptionClass!== null && !is_string($exceptionClass)) {
84
            throw new InvalidStringException('exceptionClass', $exceptionClass);
85 131
        }
86
87
        if (empty(self::$validator)) {
88
            self::$validator = new static;
89
        }
90
91
        self::$validator->name  = $name;
92
        self::$validator->value = $value;
93 5
        self::$validator->setExceptionClass($exceptionClass);
0 ignored issues
show
Deprecated Code introduced by
The method KoKoKo\assert\Assert::setExceptionClass() has been deprecated with message: Method will be removed

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
94
95 5
        return self::$validator;
96
    }
97
98
    /**
99
     * Return current validation value
100
     *
101
     * @return int|float|bool|string|resource|array
102
     */
103
    public function get()
104 4
    {
105
        return $this->value;
106 4
    }
107 1
108
    /**
109
     * @param \Closure $callback (Assert $value)
110 3
     * @return $this
111 1
     * @throws InvalidArrayException
112
     * @throws InvalidIntException
113
     */
114 2
    public function forList(\Closure $callback)
115
    {
116 2
        if (!is_array($this->value)) {
117 2
            throw new InvalidArrayException($this->name, $this->value);
118 2
        }
119
120 2
        if (empty($this->value)) {
121 1
            return $this;
122
        }
123 1
124
        $valueAssert = clone self::$validator;
125
126
        foreach ($this->value as $key => $value) {
127
            $valueAssert->value = $value;
128
            $valueAssert->name  = sprintf("%s[%s]", $this->name, $key);
129
130
            $callback($valueAssert);
131 5
        }
132
133 5
        return $this;
134 1
    }
135
136
    /**
137 4
     * @param \Closure $callback (Assert $key, Assert $value)
138 1
     * @return $this
139
     * @throws InvalidArrayException
140
     */
141 3
    public function forMap(\Closure $callback)
142 3
    {
143
        if (!is_array($this->value)) {
144 3
            throw new InvalidArrayException($this->name, $this->value);
145 3
        }
146 3
147
        if (empty($this->value)) {
148 3
            return $this;
149 3
        }
150
151 3
        $keyAssert   = clone self::$validator;
152 1
        $valueAssert = clone self::$validator;
153
154 1
        foreach ($this->value as $key => $value) {
155
            $keyAssert->value   = $key;
156
            $valueAssert->value = $value;
157
158
            $keyAssert->name   = sprintf("%s: key '%s'", $this->name, $key);
159
            $valueAssert->name = sprintf("%s['%s']", $this->name, $key);
160
161
            $callback($keyAssert, $valueAssert);
162
        }
163
164
        return $this;
165 5
    }
166
167 5
    /**
168 1
     * @param int $length
169 4
     * @return $this
170 1
     * @throws InvalidIntException
171
     * @throws InvalidStringLengthException
172
     * @throws NumberNotPositiveException
173 3
     * @throws InvalidStringException
174 1
     * @throws \Exception|\Throwable
175 2
     */
176 1
    public function length($length)
177
    {
178
        if (!is_int($length)) {
179 1
            throw new InvalidIntException('length', $length);
180
        } elseif ($length < 0) {
181
            throw new NumberNotPositiveException('length', $length);
182
        }
183
184
        if (!is_string($this->value)) {
185
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
186
        } elseif (strlen($this->value) !== $length) {
187
            throw $this->buildException(new InvalidStringLengthException($this->name, $this->value, $length));
188
        }
189
190
        return $this;
191
    }
192
193
    /**
194
     * Soft check if value has length $from <= $length <= to. Runs only after string validation
195 7
     *
196
     * @param int $from
197 7
     * @param int $to
198 1
     * @return $this
199 6
     * @throws InvalidIntException
200 1
     * @throws LengthNotBetweenException
201 5
     * @throws NumberNotPositiveException
202 1
     * @throws NumberNotGreaterException
203 4
     * @throws NumberNotLessException
204 1
     * @throws InvalidStringException
205
     * @throws \Exception|\Throwable
206
     */
207 3
    public function lengthBetween($from, $to)
208 1
    {
209
        if (!is_int($from)) {
210
            throw new InvalidIntException('from', $from);
211 2
        } elseif (!is_int($to)) {
212
            throw new InvalidIntException('to', $to);
213 2
        } elseif ($from > $to) {
214 1
            throw new NumberNotLessException('from', $from, $to);
215
        } elseif ($from < 0) {
216
            throw new NumberNotGreaterException('from', $from, 0);
217 1
        }
218
219
        if (!is_string($this->value)) {
220
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
221
        }
222
223
        $length = strlen($this->value);
224
225
        if ($length < $from || $length > $to) {
226
            throw $this->buildException(new LengthNotBetweenException($this->name, $this->value, $from, $to));
227
        }
228
229
        return $this;
230 5
    }
231
232 5
    /**
233 1
     * Soft check if value has length less than $length. Runs only after string validation
234 4
     *
235 1
     * @param int $length
236
     * @return $this
237
     * @throws InvalidIntException
238 3
     * @throws LengthNotLessException
239 1
     * @throws NumberNotPositiveException
240 2
     * @throws InvalidStringException
241 1
     * @throws \Exception|\Throwable
242
     */
243
    public function lengthLess($length)
244 1
    {
245
        if (!is_int($length)) {
246
            throw new InvalidIntException('length', $length);
247
        } elseif ($length < 0) {
248
            throw new NumberNotPositiveException('length', $length);
249
        }
250
251
        if (!is_string($this->value)) {
252
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
253
        } elseif (strlen($this->value) > $length) {
254
            throw $this->buildException(new LengthNotLessException($this->name, $this->value, $length));
255
        }
256
257 5
        return $this;
258
    }
259 5
260 1
    /**
261 4
     * Soft check if value has length less than $length. Runs only after notEmpty and string validations
262 1
     *
263
     * @param int $length
264
     * @return $this
265 3
     * @throws InvalidIntException
266 1
     * @throws LengthNotGreaterException
267 2
     * @throws NumberNotPositiveException
268 1
     * @throws InvalidStringException
269
     * @throws \Exception|\Throwable
270
     */
271 1
    public function lengthGreater($length)
272
    {
273
        if (!is_int($length)) {
274
            throw new InvalidIntException('length', $length);
275
        } elseif ($length < 0) {
276
            throw new NumberNotPositiveException('length', $length);
277
        }
278
279
        if (!is_string($this->value)) {
280
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
281
        } elseif (strlen($this->value) < $length) {
282
            throw $this->buildException(new LengthNotGreaterException($this->name, $this->value, $length));
283 4
        }
284
285 4
        return $this;
286 1
    }
287 3
288 1
    /**
289
     * Check if value is in array (in_array strict)
290
     *
291 2
     * @param array $range
292 1
     * @return $this
293
     * @throws InvalidArrayException
294
     * @throws InvalidNotEmptyException
295 1
     * @throws ValueNotInArrayException
296
     * @throws \Exception|\Throwable
297
     */
298
    public function inArray($range)
299
    {
300
        if (!is_array($range)) {
301
            throw new InvalidArrayException('range', $range);
302
        } elseif (empty($range)) {
303
            throw new InvalidNotEmptyException('range');
304 2
        }
305
306 2
        if (!in_array($this->value, $range, true)) {
307 1
            throw $this->buildException(new ValueNotInArrayException($this->name, $this->value, $range));
308
        }
309
310 1
        return $this;
311
    }
312
313
    /**
314
     * Check if value is array
315
     *
316
     * @return $this
317
     * @throws InvalidArrayException
318
     * @throws \Exception|\Throwable
319
     */
320
    public function isArray()
321
    {
322 4
        if (!is_array($this->value)) {
323
            throw $this->buildException(new InvalidArrayException($this->name, $this->value));
324 4
        }
325 1
326
        return $this;
327
    }
328 3
329 1
    /**
330
     * Check if array key exists
331
     *
332 2
     * @param string|int $key
333 1
     * @return $this
334
     * @throws ArrayKeyNotExistsException
335
     * @throws InvalidArrayException
336 1
     * @throws InvalidIntOrStringException
337
     * @throws \Exception|\Throwable
338
     */
339
    public function hasKey($key)
340
    {
341
        if (!is_string($key) && !is_int($key)) {
342
            throw new InvalidIntOrStringException('key', $key);
343
        }
344
345
        if (!is_array($this->value)) {
346
            throw $this->buildException(new InvalidArrayException($this->name, $this->value));
347
        }
348
349 5
        if (!array_key_exists($key, $this->value)) {
350
            throw $this->buildException(new ArrayKeyNotExistsException($this->name, $key));
351 5
        }
352 1
353 4
        return $this;
354 1
    }
355
356
    /**
357 3
     * Check if array elements count is same as $count
358 1
     *
359
     * @param int $count
360
     * @return $this
361 2
     * @throws InvalidArrayCountException
362 1
     * @throws InvalidArrayException
363
     * @throws InvalidIntException
364
     * @throws NumberNotGreaterException
365 1
     * @throws \Exception|\Throwable
366
     */
367
    public function count($count)
368
    {
369
        if (!is_int($count)) {
370
            throw new InvalidIntException('count', $count);
371
        } elseif ($count < 0) {
372
            throw new NumberNotGreaterException('count', $count, 0);
373
        }
374
375
        if (!is_array($this->value)) {
376
            throw $this->buildException(new InvalidArrayException($this->name, $this->value));
377
        }
378 6
379
        if (count($this->value) !== $count) {
380 6
            throw $this->buildException(new InvalidArrayCountException($this->name, $this->value, $count));
381 1
        }
382 5
383 1
        return $this;
384 4
    }
385 1
386
    /**
387
     * Soft check that $from <= value <= $to
388 3
     *
389 1
     * @param float|int $from
390 2
     * @param float|int $to
391 1
     * @return $this
392
     * @throws NumberNotBetweenException
393
     * @throws InvalidIntOrFloatException
394 1
     * @throws NumberNotLessStrictlyException
395
     * @throws \Exception|\Throwable
396
     */
397
    public function between($from, $to)
398
    {
399
        if (!is_int($from) && !is_float($from)) {
400
            throw new InvalidIntOrFloatException('from', $from);
401
        } elseif (!is_int($to) && !is_float($to)) {
402
            throw new InvalidIntOrFloatException('to', $to);
403
        } elseif ($from > $to) {
404
            throw new NumberNotLessStrictlyException('from', $from, $to);
405
        }
406
407 6
        if (!is_int($this->value) && !is_float($this->value)) {
408
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
409 6
        } elseif ($this->value < $from || $this->value > $to) {
410 1
            throw $this->buildException(new NumberNotBetweenException($this->name, $this->value, $from, $to));
411 5
        }
412 1
413 4
        return $this;
414 1
    }
415
416
    /**
417 3
     * Strict check that $from < value < $to
418 1
     *
419 2
     * @param float|int $from
420 1
     * @param float|int $to
421
     * @return $this
422
     * @throws InvalidIntOrFloatException
423 1
     * @throws NumberNotBetweenStrictlyException
424
     * @throws NumberNotLessStrictlyException
425
     * @throws \Exception|\Throwable
426
     */
427
    public function betweenStrict($from, $to)
428
    {
429
        if (!is_int($from) && !is_float($from)) {
430
            throw new InvalidIntOrFloatException('from', $from);
431
        } elseif (!is_int($to) && !is_float($to)) {
432 2
            throw new InvalidIntOrFloatException('to', $to);
433
        } elseif ($from > $to) {
434 2
            throw new NumberNotLessStrictlyException('from', $from, $to);
435 1
        }
436
437
        if (!is_int($this->value) && !is_float($this->value)) {
438 1
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
439
        } elseif ($this->value <= $from || $this->value >= $to) {
440
            throw $this->buildException(new NumberNotBetweenStrictlyException($this->name, $this->value, $from, $to));
441
        }
442
443
        return $this;
444
    }
445
446
    /**
447
     * Check if value is boolean (is_bool)
448 3
     *
449
     * @return $this
450 3
     * @throws InvalidBoolException
451 1
     * @throws \Exception|\Throwable
452 2
     */
453 1
    public function bool()
454
    {
455
        if (!is_bool($this->value)) {
456 1
            throw $this->buildException(new InvalidBoolException($this->name, $this->value));
457
        }
458
459
        return $this;
460
    }
461
462
    /**
463
     * Check if value is digit (ctype_digit)
464
     *
465 2
     * @return $this
466
     * @throws InvalidDigitException
467 2
     * @throws InvalidStringException
468 1
     * @throws \Exception|\Throwable
469
     */
470
    public function digit()
471 1
    {
472
        if (!is_string($this->value)) {
473
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
474
        } elseif (!ctype_digit($this->value)) {
475
            throw $this->buildException(new InvalidDigitException($this->name, $this->value));
476
        }
477
478
        return $this;
479
    }
480 2
481
    /**
482 2
     * Check if value is empty (empty)
483 1
     *
484
     * @return $this
485
     * @throws InvalidEmptyException
486 1
     * @throws \Exception|\Throwable
487
     */
488
    public function isEmpty()
489
    {
490
        if (!empty($this->value)) {
491
            throw $this->buildException(new InvalidEmptyException($this->name));
492
        }
493
494
        return $this;
495 2
    }
496
497 2
    /**
498 1
     * Check if value is not empty (empty)
499
     *
500
     * @return $this
501 1
     * @throws InvalidNotEmptyException
502
     * @throws \Exception|\Throwable
503
     */
504
    public function notEmpty()
505
    {
506
        if (empty($this->value)) {
507
            throw $this->buildException(new InvalidNotEmptyException($this->name));
508
        }
509
510 7
        return $this;
511
    }
512 7
513 4
    /**
514
     * Check if value is float (is_float)
515
     *
516 3
     * @return $this
517
     * @throws InvalidFloatException
518
     * @throws \Exception|\Throwable
519
     */
520
    public function float()
521
    {
522
        if (!is_float($this->value)) {
523
            throw $this->buildException(new InvalidFloatException($this->name, $this->value));
524
        }
525
526
        return $this;
527 4
    }
528
529 4
    /**
530 1
     * Check if value is integer (is_int)
531
     *
532
     * @return $this
533 3
     * @throws InvalidIntException
534 1
     * @throws \Exception|\Throwable
535 2
     */
536 1
    public function int()
537
    {
538
        if (!is_int($this->value)) {
539 1
            throw $this->buildException(new InvalidIntException($this->name, $this->value));
540
        }
541
542
        return $this;
543
    }
544
545
    /**
546
     * Soft check that value <= $max
547
     *
548
     * @param float|int $number
549
     * @return $this
550 4
     * @throws InvalidIntOrFloatException
551
     * @throws NumberNotLessException
552 4
     * @throws \Exception|\Throwable
553 1
     */
554
    public function less($number)
555
    {
556 3
        if (!is_int($number) && !is_float($number)) {
557 1
            throw new InvalidIntOrFloatException('number', $number);
558 2
        }
559 1
560
        if (!is_int($this->value) && !is_float($this->value)) {
561
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
562 1
        } elseif ($this->value > $number) {
563
            throw $this->buildException(new NumberNotLessException($this->name, $this->value, $number));
564
        }
565
566
        return $this;
567
    }
568
569
    /**
570
     * Soft check that value >= $min
571
     *
572
     * @param float|int $number
573 4
     * @return $this
574
     * @throws NumberNotGreaterException
575 4
     * @throws InvalidIntOrFloatException
576 1
     * @throws \Exception|\Throwable
577
     */
578
    public function greater($number)
579 3
    {
580 1
        if (!is_int($number) && !is_float($number)) {
581 2
            throw new InvalidIntOrFloatException('number', $number);
582 1
        }
583
584
        if (!is_int($this->value) && !is_float($this->value)) {
585 1
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
586
        } elseif ($this->value < $number) {
587
            throw $this->buildException(new NumberNotGreaterException($this->name, $this->value, $number));
588
        }
589
590
        return $this;
591
    }
592
593
    /**
594
     * Strict check that value < $max
595
     *
596 4
     * @param float|int $number
597
     * @return $this
598 4
     * @throws InvalidIntOrFloatException
599 1
     * @throws NumberNotLessStrictlyException
600
     * @throws \Exception|\Throwable
601
     */
602 3
    public function lessStrict($number)
603 1
    {
604 2
        if (!is_int($number) && !is_float($number)) {
605 1
            throw new InvalidIntOrFloatException('number', $number);
606
        }
607
608 1
        if (!is_int($this->value) && !is_float($this->value)) {
609
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
610
        } elseif ($this->value >= $number) {
611
            throw $this->buildException(new NumberNotLessStrictlyException($this->name, $this->value, $number));
612
        }
613
614
        return $this;
615
    }
616
617
    /**
618
     * Strict check that value > $min
619
     *
620
     * @param float|int $number
621 6
     * @return $this
622
     * @throws InvalidIntOrFloatException
623 6
     * @throws NumberNotGreaterStrictlyException
624 1
     * @throws \Exception|\Throwable
625 5
     */
626 1
    public function greaterStrict($number)
627
    {
628
        if (!is_int($number) && !is_float($number)) {
629 4
            throw new InvalidIntOrFloatException('number', $number);
630 1
        }
631
632
        if (!is_int($this->value) && !is_float($this->value)) {
633
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
634 3
        } elseif ($this->value <= $number) {
635
            throw $this->buildException(new NumberNotGreaterStrictlyException($this->name, $this->value, $number));
636 3
        }
637 1
638
        return $this;
639
    }
640 2
641 1
    /**
642
     * Check if value match regexp pattern
643
     *
644 1
     * @param string $pattern
645
     * @return $this
646
     * @throws InvalidNotEmptyException
647
     * @throws InvalidRegexpPatternException
648
     * @throws InvalidStringException
649
     * @throws StringNotMatchRegExpException
650
     * @throws \Exception|\Throwable
651
     */
652
    public function match($pattern)
653
    {
654
        if (!is_string($pattern)) {
655
            throw new InvalidStringException('pattern', $pattern);
656 5
        } elseif (empty($pattern)) {
657
            throw new InvalidNotEmptyException('pattern');
658 5
        }
659 1
660 4
        if (!is_string($this->value)) {
661 1
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
662
        }
663
664 3
        // God please sorry for this @
665 1
        $checkResult = @preg_match($pattern, $this->value);
666 2
667 1
        if ((preg_last_error() !== PREG_NO_ERROR) || ($checkResult === false)) {
668
            throw $this->buildException(new InvalidRegExpPatternException('pattern', $pattern));
669
        }
670 1
671
        if ($checkResult === 0) {
672
            throw $this->buildException(new StringNotMatchRegExpException($this->name, $this->value, $pattern));
673
        }
674
675
        return $this;
676
    }
677
678
    /**
679
     * Check if value match glob pattern
680 3
     *
681
     * @param string $pattern
682 3
     * @return $this
683 1
     * @throws InvalidNotEmptyException
684 2
     * @throws InvalidStringException
685 1
     * @throws StringNotMatchGlobException
686
     * @throws \Exception|\Throwable
687
     */
688 1
    public function glob($pattern)
689
    {
690
        if (!is_string($pattern)) {
691
            throw new InvalidStringException('pattern', $pattern);
692
        } elseif (empty($pattern)) {
693
            throw new InvalidNotEmptyException('pattern');
694
        }
695
696
        if (!is_string($this->value)) {
697
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
698 3
        } elseif (!fnmatch($pattern, $this->value)) {
699
            throw $this->buildException(new StringNotMatchGlobException($this->name, $this->value, $pattern));
700 3
        }
701 1
702 2
        return $this;
703 1
    }
704
705
    /**
706 1
     * Check if value < 0
707
     *
708
     * @return $this
709
     * @throws InvalidIntOrFloatException
710
     * @throws NumberNotNegativeException
711
     * @throws \Exception|\Throwable
712
     */
713
    public function negative()
714
    {
715
        if (!is_int($this->value) && !is_float($this->value)) {
716
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
717 3
        } elseif ($this->value >= 0) {
718
            throw $this->buildException(new NumberNotNegativeException($this->name, $this->value));
719 3
        }
720 1
721
        return $this;
722
    }
723 2
724 1
    /**
725
     * Check if value > 0
726
     *
727 1
     * @return $this
728
     * @throws InvalidIntOrFloatException
729
     * @throws NumberNotPositiveException
730
     * @throws \Exception|\Throwable
731
     */
732
    public function positive()
733
    {
734
        if (!is_int($this->value) && !is_float($this->value)) {
735
            throw $this->buildException(new InvalidIntOrFloatException($this->name, $this->value));
736
        } elseif ($this->value <= 0) {
737
            throw $this->buildException(new NumberNotPositiveException($this->name, $this->value));
738 3
        }
739
740 3
        return $this;
741 1
    }
742
743
    /**
744 2
     * Check if value is same as $anotherValue
745 1
     *
746
     * @param int|float|bool|string|resource|array|null $anotherValue
747
     * @return $this
748 1
     * @throws InvalidNotObjectException
749
     * @throws InvalidSameValueException
750
     * @throws \Exception|\Throwable
751
     */
752
    public function isSame($anotherValue)
753
    {
754
        if (is_object($anotherValue)) {
755
            throw new InvalidNotObjectException('anotherValue');
756
        }
757 2
758
        if ($this->value !== $anotherValue) {
759 2
            throw $this->buildException(new InvalidSameValueException($this->name, $this->value, $anotherValue));
760 1
        }
761
762
        return $this;
763 1
    }
764
765
    /**
766
     * Check if value is not same as $anotherValue
767
     *
768
     * @param int|float|bool|string|resource|array|null $anotherValue
769
     * @return $this
770
     * @throws InvalidNotObjectException
771
     * @throws InvalidNotSameValueException
772 2
     * @throws \Exception|\Throwable
773
     */
774 2
    public function notSame($anotherValue)
775 1
    {
776
        if (is_object($anotherValue)) {
777
            throw new InvalidNotObjectException('anotherValue');
778 1
        }
779
780
        if ($this->value === $anotherValue) {
781
            throw $this->buildException(new InvalidNotSameValueException($this->name, $this->value));
782
        }
783
784
        return $this;
785
    }
786
787
    /**
788 3
     * Check if value is null
789
     *
790 3
     * @return $this
791 1
     * @throws InvalidNullException
792 2
     * @throws \Exception|\Throwable
793 1
     */
794
    public function isNull()
795
    {
796 1
        if (!is_null($this->value)) {
797
            throw $this->buildException(new InvalidNullException($this->name, $this->value));
798
        }
799
800
        return $this;
801
    }
802
803
    /**
804
     * Check if value is not null
805 2
     *
806
     * @return $this
807 2
     * @throws InvalidNotNullException
808 1
     * @throws \Exception|\Throwable
809
     */
810
    public function notNull()
811 1
    {
812
        if (is_null($this->value)) {
813
            throw $this->buildException(new InvalidNotNullException($this->name));
814
        }
815
816
        return $this;
817
    }
818
819
    /**
820 3
     * Check if value is numeric (is_numeric)
821
     *
822 3
     * @return $this
823 1
     * @throws InvalidIntOrFloatOrStringException
824
     * @throws InvalidNumericException
825
     * @throws \Exception|\Throwable
826 2
     */
827
    public function numeric()
828
    {
829
        if (!is_int($this->value) && !is_float($this->value) && !is_string($this->value)) {
830
            throw $this->buildException(new InvalidIntOrFloatOrStringException($this->name, $this->value));
831
        } elseif (!is_numeric($this->value)) {
832
            throw $this->buildException(new InvalidNumericException($this->name, $this->value));
833
        }
834 1
835
        return $this;
836 1
    }
837
838 1
    /**
839
     * Check if value is resource (is_resource)
840
     *
841
     * @return $this
842
     * @throws InvalidResourceException
843
     * @throws \Exception|\Throwable
844
     */
845
    public function resource()
846
    {
847
        if (!is_resource($this->value)) {
848 3
            throw $this->buildException(new InvalidResourceException($this->name, $this->value));
849
        }
850 3
851 1
        return $this;
852 2
    }
853 1
854
    /**
855
     * Check if value is string (is_string)
856 1
     *
857
     * @return $this
858 1
     * @throws InvalidStringException
859
     * @throws \Exception|\Throwable
860
     */
861
    public function string()
862
    {
863
        if (!is_string($this->value)) {
864
            throw $this->buildException(new InvalidStringException($this->name, $this->value));
865
        }
866
867
        return $this;
868 3
    }
869
870 3
    /**
871 1
     * Cast value to bool
872 2
     *
873 1
     * @return $this
874
     */
875
    public function toBool()
876 1
    {
877
        $this->value = (bool) $this->value;
878 1
879
        return $this;
880
    }
881
882
    /**
883
     * Cast value to float. If it's not numeric - there will be fail cast
884
     *
885
     * @return $this
886
     * @throws InvalidNotArrayException
887 2
     * @throws InvalidNumericException
888
     */
889 2
    public function toFloat()
890 1
    {
891
        if (is_array($this->value)) {
892
            throw new InvalidNotArrayException($this->name);
893 1
        } elseif (!empty($this->value) && !is_numeric($this->value)) {
894
            throw new InvalidNumericException($this->name, $this->value);
895 1
        }
896
897
        $this->value = (float) $this->value;
898
899
        return $this;
900
    }
901
902
    /**
903
     * Cast value to int. If it's not numeric - there will be fail cast
904
     *
905
     * @return $this
906
     * @throws InvalidNotArrayException
907
     * @throws InvalidNumericException
908
     */
909
    public function toInt()
910
    {
911
        if (is_array($this->value)) {
912
            throw new InvalidNotArrayException($this->name);
913
        } elseif (!empty($this->value) && !is_numeric($this->value)) {
914
            throw new InvalidNumericException($this->name, $this->value);
915
        }
916
917
        $this->value = (int) $this->value;
918
919
        return $this;
920
    }
921
922
    /**
923
     * Cast value to string. If it's array - there will be fail cast
924
     *
925
     * @return $this
926
     * @throws InvalidNotArrayException
927
     */
928
    public function toString()
929
    {
930
        if (is_array($this->value)) {
931
            throw new InvalidNotArrayException($this->name);
932
        }
933
934
        $this->value = (string) $this->value;
935
936
        return $this;
937
    }
938
939
    /**
940
     * Process fail validation
941
     *
942
     * @param \InvalidArgumentException $originalException
943
     *
944
     * @return \InvalidArgumentException|\Exception|\Throwable
945
     */
946
    protected function buildException(\InvalidArgumentException $originalException)
947
    {
948
        if (self::$exceptionClass) {
949
            return new self::$exceptionClass(
950
                $originalException->getMessage(),
951
                $originalException->getCode(),
952
                $originalException
953
            );
954
        }
955
        return $originalException;
956
    }
957
958
    /**
959
     * Return class of exception, which will be thrown on fail test
960
     *
961
     * @return string
962
     * @deprecated Method will be removed
963
     */
964
    public function getExceptionClass()
965
    {
966
        return self::$exceptionClass ?: ArgumentException::class;
967
    }
968
969
    /**
970
     * Update default exception class
971
     *
972
     * @param string $exceptionClass
973
     *
974
     * @return $this
975
     * @throws InvalidStringException|ArgumentException
976
     * @deprecated Method will be removed
977
     */
978
    public function setExceptionClass($exceptionClass)
979
    {
980
        if (!is_string($exceptionClass)) {
981
            throw new InvalidStringException('Param $exceptionClass must be string', $exceptionClass);
982
        }
983
        if (!is_a($exceptionClass, '\Exception', true) || !is_a($exceptionClass, '\Throwable', true)) {
984
            throw new ArgumentException('Param $exceptionClass must be subclass of \Exception or \Throwable');
985
        }
986
        self::$exceptionClass = $exceptionClass;
987
        return self::$validator;
988
    }
989
990
    /**
991
     * Soft check that value >= $min
992
     *
993
     * @param float|int $number
994
     * @return $this
995
     * @throws NumberNotGreaterException
996
     * @throws InvalidIntOrFloatException
997
     * @throws \Exception|\Throwable
998
     * @deprecated Method will be removed
999
     */
1000
    public function more($number)
1001
    {
1002
        return $this->greater($number);
1003
    }
1004
1005
    /**
1006
     * Strict check that value > $min
1007
     *
1008
     * @param float|int $number
1009
     * @return $this
1010
     * @throws InvalidIntOrFloatException
1011
     * @throws NumberNotGreaterStrictlyException
1012
     * @throws \Exception|\Throwable
1013
     * @deprecated Method will be removed
1014
     */
1015
    public function moreStrict($number)
1016
    {
1017
        return $this->greaterStrict($number);
1018
    }
1019
1020
    /**
1021
     * Soft check if value has length less than $length. Runs only after notEmpty and string validations
1022
     *
1023
     * @param int $length
1024
     * @return $this
1025
     * @throws InvalidIntException
1026
     * @throws LengthNotGreaterException
1027
     * @throws NumberNotPositiveException
1028
     * @throws InvalidStringException
1029
     * @throws \Exception|\Throwable
1030
     * @deprecated Method will be removed
1031
     */
1032
    public function lengthMore($length)
1033
    {
1034
        return $this->lengthGreater($length);
1035
    }
1036
}
1037