Completed
Push — master ( 5f9fd0...8569d0 )
by Sebastian
05:20
created

NumberInterval::validate()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6.0585

Importance

Changes 0
Metric Value
cc 6
nc 7
nop 4
dl 0
loc 29
ccs 15
cts 17
cp 0.8824
crap 6.0585
rs 8.8337
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Linna Filter
5
 *
6
 * @author Sebastian Rapetti <[email protected]>
7
 * @copyright (c) 2018, Sebastian Rapetti
8
 * @license http://opensource.org/licenses/MIT MIT License
9
 */
10
declare(strict_types = 1);
11
12
namespace Linna\Filter\Rules;
13
14
use UnexpectedValueException;
15
16
/**
17
 * Check if a number is included or not on interval using ><, <>, >=<, <=> operators.
18
 */
19
class NumberInterval extends AbstractNumber implements RuleSanitizeInterface
20
{
21
    /**
22
     * @var array Arguments expected.
23
     */
24
    private $arguments = ['string', 'number', 'number'];
0 ignored issues
show
introduced by
The private property $arguments is not used, and could be removed.
Loading history...
25
26
    /**
27
     * Validate.
28
     *
29
     * @param int|float $received
30
     * @param string    $operator
31
     * @param int|float $min
32
     * @param int|float $max
33
     *
34
     * @return bool
35
     */
36 27
    public function validate($received, string $operator, $min, $max): bool
37
    {
38 27
        if (!is_numeric($received)) {
0 ignored issues
show
introduced by
The condition is_numeric($received) is always true.
Loading history...
39 1
            return true;
40
        }
41
42 26
        if (!is_numeric($min)) {
0 ignored issues
show
introduced by
The condition is_numeric($min) is always true.
Loading history...
43
            return true;
44
        }
45
46 26
        if (!is_numeric($max)) {
0 ignored issues
show
introduced by
The condition is_numeric($max) is always true.
Loading history...
47
            return true;
48
        }
49
50 26
        settype($received, 'float');
51 26
        settype($min, 'float');
52 26
        settype($max, 'float');
53
54 26
        if ((fmod($received, 1.0) === 0.0)) {
55 26
            settype($received, 'integer');
56 26
            settype($min, 'integer');
57 26
            settype($max, 'integer');
58
        }
59
60 26
        if ($this->switchOperator($operator, $received, $min, $max)) {
61 11
            return false;
62
        }
63
64 14
        return true;
65
    }
66
67
    /**
68
     * Perform correct operation from passed operator.
69
     *
70
     * @param string    $operator
71
     * @param int|float $numberReceived
72
     * @param int|float $min
73
     * @param int|float $max
74
     *
75
     * @return bool
76
     *
77
     * @throws UnexpectedValueException if unknown operator is provided.
78
     */
79 26
    private function switchOperator(string $operator, &$numberReceived, &$min, &$max): bool
80
    {
81
        switch ($operator) {
82 26
            case '><': //inside interval exclusive
83 10
                return $numberReceived > $min && $numberReceived < $max;
84 16
            case '>=<': //inside interval inclusive
85 5
                return $numberReceived >= $min && $numberReceived <= $max;
86 11
            case '<>': //outside interval exclusive
87 5
                return $numberReceived < $min || $numberReceived > $max;
88 6
            case '<=>': //outside interval inclusive
89 5
                return $numberReceived <= $min || $numberReceived >= $max;;
90
            default:
91 1
                throw new UnexpectedValueException("Unknown comparson operator ({$operator}). Permitted ><, <>, >=<, <=>");
92
        }
93
    }
94
}
95