Passed
Push — master ( 926673...c10187 )
by
unknown
47s queued 10s
created

RangeValidator::setRange()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace ValueValidators;
4
5
use Exception;
6
7
/**
8
 * ValueValidator that validates if a numeric value is within a certain range.
9
 *
10
 * @since 0.1
11
 *
12
 * @license GPL-2.0-or-later
13
 * @author Jeroen De Dauw < [email protected] >
14
 */
15
class RangeValidator extends ValueValidatorObject {
16
17
	/**
18
	 * Lower bound of the range (included). Either a number or false, for no lower limit.
19
	 *
20
	 * @since 0.1
21
	 *
22
	 * @var false|int|float
23
	 */
24
	protected $lowerBound = false;
25
26
	/**
27
	 * Upper bound of the range (included). Either a number or false, for no upper limit.
28
	 *
29
	 * @since 0.1
30
	 *
31
	 * @var false|int|float
32
	 */
33
	protected $upperBound = false;
34
35
	/**
36
	 * Sets the lower bound (included).
37
	 *
38
	 * @since 0.1
39
	 *
40
	 * @param $lowerBound false|int|float
41
	 */
42
	public function setLowerBound( $lowerBound ) {
43
		$this->lowerBound = $lowerBound;
44
	}
45
46
	/**
47
	 * Sets the upper bound (included).
48
	 *
49
	 * @since 0.1
50
	 *
51
	 * @param $upperBound false|int|float
52
	 */
53
	public function setUpperBound( $upperBound ) {
54
		$this->upperBound = $upperBound;
55
	}
56
57
	/**
58
	 * Requires the value to be in the specified range.
59
	 *
60
	 * @since 0.1
61
	 *
62
	 * @param $lowerBound false|int|float
63
	 * @param $upperBound false|int|float
64
	 */
65
	public function setRange( $lowerBound, $upperBound ) {
66
		$this->lowerBound = $lowerBound;
67
		$this->upperBound = $upperBound;
68
	}
69
70
	/**
71
	 * Requires the value to be within the range of a point.
72
	 * Bounds are included, ie 6 will be valid for point 4 within range 2.
73
	 *
74
	 * @since 0.1
75
	 *
76
	 * @param int|float $point
77
	 * @param int|float $range
78
	 */
79
	public function setWithinRange( $point, $range ) {
80
		$this->lowerBound = $point - $range;
81
		$this->upperBound = $point + $range;
82
	}
83
84
	/**
85
	 * @see ValueValidatorObject::doValidation
86
	 *
87
	 * @since 0.1
88
	 *
89
	 * @param mixed $value
90
	 */
91
	public function doValidation( $value ) {
92
		if ( !true ) {
93
			// TODO: type check
94
			$this->addErrorMessage( 'Not a numeric value - cannot check the range' );
95
			return;
96
		}
97
98
		$this->validateBounds( $value );
99
	}
100
101
	/**
102
	 * Validates the parameters value and returns the result.
103
	 *
104
	 * @since 0.1
105
	 *
106
	 * @param $value mixed
107
	 * @param float|null|false $upperBound
108
	 * @param float|null|false $lowerBound
109
	 *
110
	 * @return boolean
111
	 */
112
	protected function validateBounds( $value, $upperBound = null, $lowerBound = null ) {
113
		$upperBound = $upperBound ?? $this->upperBound;
114
		$lowerBound = $lowerBound ?? $this->lowerBound;
115
116
		$smallEnough = $upperBound === false || $value <= $upperBound;
117
		$bigEnough = $lowerBound === false || $value >= $lowerBound;
118
119
		if ( !$smallEnough ) {
120
			$this->addErrorMessage( 'Value exceeding upper bound' );
121
		}
122
123
		if ( !$bigEnough ) {
124
			$this->addErrorMessage( 'Value exceeding lower bound' );
125
		}
126
127
		return $smallEnough && $bigEnough;
128
	}
129
130
	/**
131
	 * @see ValueValidator::setOptions
132
	 *
133
	 * @since 0.1
134
	 *
135
	 * @param array $options
136
	 * @throws Exception
137
	 */
138
	public function setOptions( array $options ) {
139
		parent::setOptions( $options );
140
141
		if ( array_key_exists( 'range', $options ) ) {
142
			if ( is_array( $options['range'] ) && count( $options['range'] ) == 2 ) {
143
				$this->setRange( $options['range'][0], $options['range'][1] );
144
			} else {
145
				throw new Exception( 'The range argument must be an array with two elements' );
146
			}
147
		}
148
149
		if ( array_key_exists( 'withinrange', $options ) ) {
150
			if ( is_array( $options['withinrange'] ) && count( $options['withinrange'] ) == 2 ) {
151
				$this->setWithinRange( $options['withinrange'][0], $options['withinrange'][1] );
152
			} else {
153
				throw new Exception( 'The withinrange argument must be an array with two elements' );
154
			}
155
		}
156
157
		if ( array_key_exists( 'lowerbound', $options ) ) {
158
			$this->setLowerBound( $options['lowerbound'] );
159
		}
160
161
		if ( array_key_exists( 'upperbound', $options ) ) {
162
			$this->setUpperBound( $options['upperbound'] );
163
		}
164
	}
165
166
}
167