This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace DataValues; |
||
4 | |||
5 | use InvalidArgumentException; |
||
6 | |||
7 | /** |
||
8 | * Class representing a quantity with associated unit. |
||
9 | * The amount is stored as a @see DecimalValue object. |
||
10 | * |
||
11 | * @see QuantityValue for quantities with a known uncertainty interval. |
||
12 | * For simple numeric amounts use @see NumberValue. |
||
13 | * |
||
14 | * @note UnboundedQuantityValue and QuantityValue both use the value type ID "quantity". |
||
15 | * The fact that we use subclassing to model the bounded vs the unbounded case should be |
||
16 | * considered an implementation detail. |
||
17 | * |
||
18 | * @since 0.8 |
||
19 | * |
||
20 | * @license GPL-2.0-or-later |
||
21 | * @author Daniel Kinzler |
||
22 | */ |
||
23 | class UnboundedQuantityValue extends DataValueObject { |
||
24 | |||
25 | /** |
||
26 | * The quantity's amount |
||
27 | * |
||
28 | * @var DecimalValue |
||
29 | */ |
||
30 | protected $amount; |
||
31 | |||
32 | /** |
||
33 | * The quantity's unit identifier (use "1" for unitless quantities). |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $unit; |
||
38 | |||
39 | /** |
||
40 | * @param DecimalValue $amount |
||
41 | * @param string $unit A unit identifier. Must not be empty, use "1" for unit-less quantities. |
||
42 | * |
||
43 | * @throws IllegalValueException |
||
44 | */ |
||
45 | 32 | public function __construct( DecimalValue $amount, $unit ) { |
|
46 | 32 | if ( !is_string( $unit ) || $unit === '' ) { |
|
47 | 2 | throw new IllegalValueException( '$unit must be a non-empty string. Use "1" for unit-less quantities.' ); |
|
48 | } |
||
49 | |||
50 | 30 | $this->amount = $amount; |
|
51 | 30 | $this->unit = $unit; |
|
52 | 30 | } |
|
53 | |||
54 | /** |
||
55 | * Returns a QuantityValue representing the given amount. |
||
56 | * |
||
57 | * This is a convenience wrapper around the constructor that accepts native values |
||
58 | * instead of DecimalValue objects. |
||
59 | * |
||
60 | * @note if the amount or a bound is given as a string, the string must conform |
||
61 | * to the rules defined by @see DecimalValue. |
||
62 | * |
||
63 | * @param string|int|float|DecimalValue $amount |
||
64 | * @param string $unit A unit identifier. Must not be empty, use "1" for unit-less quantities. |
||
65 | * |
||
66 | * @return self |
||
67 | * @throws InvalidArgumentException |
||
68 | */ |
||
69 | 7 | public static function newFromNumber( $amount, $unit = '1' ) { |
|
70 | 7 | $amount = self::asDecimalValue( 'amount', $amount ); |
|
71 | |||
72 | 7 | return new self( $amount, $unit ); |
|
73 | } |
||
74 | |||
75 | /** |
||
76 | * Converts $number to a DecimalValue if possible and necessary. |
||
77 | * |
||
78 | * @note if the $number is given as a string, it must conform to the rules |
||
79 | * defined by @see DecimalValue. |
||
80 | * |
||
81 | * @param string $name The variable name to use in exception messages |
||
82 | * @param string|int|float|DecimalValue|null $number |
||
83 | * @param DecimalValue|null $default |
||
84 | * |
||
85 | * @throws InvalidArgumentException |
||
86 | * @return DecimalValue |
||
87 | */ |
||
88 | 7 | protected static function asDecimalValue( $name, $number, DecimalValue $default = null ) { |
|
89 | 7 | if ( !is_string( $name ) ) { |
|
90 | throw new InvalidArgumentException( '$name must be a string' ); |
||
91 | } |
||
92 | |||
93 | 7 | if ( $number === null ) { |
|
94 | if ( $default === null ) { |
||
95 | throw new InvalidArgumentException( '$' . $name . ' must not be null' ); |
||
96 | } |
||
97 | |||
98 | $number = $default; |
||
99 | } |
||
100 | |||
101 | 7 | if ( $number instanceof DecimalValue ) { |
|
102 | // nothing to do |
||
103 | 6 | } elseif ( is_int( $number ) || is_float( $number ) || is_string( $number ) ) { |
|
104 | 6 | $number = new DecimalValue( $number ); |
|
105 | } else { |
||
106 | throw new IllegalValueException( '$' . $name . ' must be a string, int, or float' ); |
||
107 | } |
||
108 | |||
109 | 7 | return $number; |
|
110 | } |
||
111 | |||
112 | /** |
||
113 | * @see Serializable::serialize |
||
114 | * |
||
115 | * @return string |
||
116 | */ |
||
117 | 9 | public function serialize() { |
|
118 | 9 | return serialize( [ |
|
119 | 9 | $this->amount, |
|
120 | 9 | $this->unit |
|
121 | ] ); |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * @see Serializable::unserialize |
||
126 | * |
||
127 | * @param string $data |
||
128 | */ |
||
129 | 9 | public function unserialize( $data ) { |
|
130 | 9 | list( $amount, $unit ) = unserialize( $data ); |
|
131 | 9 | $this->__construct( $amount, $unit ); |
|
132 | 9 | } |
|
133 | |||
134 | /** |
||
135 | * @see DataValue::getType |
||
136 | * |
||
137 | * @return string |
||
138 | */ |
||
139 | 15 | public static function getType() { |
|
140 | 15 | return 'quantity'; |
|
141 | } |
||
142 | |||
143 | /** |
||
144 | * @deprecated Kept for compatibility with older DataValues versions. |
||
145 | * Do not use. |
||
146 | * |
||
147 | * @return float |
||
148 | 3 | */ |
|
149 | 3 | public function getSortKey() { |
|
150 | return $this->amount->getValueFloat(); |
||
151 | } |
||
152 | |||
153 | /** |
||
154 | * Returns the quantity object. |
||
155 | * @see DataValue::getValue |
||
156 | * |
||
157 | * @return self |
||
158 | 6 | */ |
|
159 | 6 | public function getValue() { |
|
160 | return $this; |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Returns the amount represented by this quantity. |
||
165 | * |
||
166 | * @return DecimalValue |
||
167 | 20 | */ |
|
168 | 20 | public function getAmount() { |
|
169 | return $this->amount; |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Returns the unit held by this quantity. |
||
174 | * Unit-less quantities should use "1" as their unit. |
||
175 | * |
||
176 | * @return string |
||
177 | 10 | */ |
|
178 | 10 | public function getUnit() { |
|
179 | return $this->unit; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * Returns a transformed value derived from this QuantityValue by applying |
||
184 | * the given transformation to the amount and the upper and lower bounds. |
||
185 | * The resulting amount and bounds are rounded to the significant number of |
||
186 | * digits. Note that for exact quantities (with at least one bound equal to |
||
187 | * the amount), no rounding is applied (since they are considered to have |
||
188 | * infinite precision). |
||
189 | * |
||
190 | * The transformation is provided as a callback, which must implement a |
||
191 | * monotonously increasing, fully differentiable function mapping a DecimalValue |
||
192 | * to a DecimalValue. Typically, it will be a linear transformation applying a |
||
193 | * factor and an offset. |
||
194 | * |
||
195 | * @param string $newUnit The unit of the transformed quantity. |
||
196 | * |
||
197 | * @param callable $transformation A callback that implements the desired transformation. |
||
198 | * The transformation will be called three times, once for the amount, once |
||
199 | * for the lower bound, and once for the upper bound. It must return a DecimalValue. |
||
200 | * The first parameter passed to $transformation is the DecimalValue to transform |
||
201 | * In addition, any extra parameters passed to transform() will be passed through |
||
202 | * to the transformation callback. |
||
203 | * |
||
204 | * @param mixed ... Any extra parameters will be passed to the $transformation function. |
||
205 | * |
||
206 | * @todo Should be factored out into a separate QuantityMath class. |
||
207 | * |
||
208 | * @throws InvalidArgumentException |
||
209 | * @return self |
||
210 | 7 | */ |
|
211 | 7 | public function transform( $newUnit, $transformation ) { |
|
212 | if ( !is_callable( $transformation ) ) { |
||
213 | throw new InvalidArgumentException( '$transformation must be callable.' ); |
||
214 | } |
||
215 | 7 | ||
216 | if ( !is_string( $newUnit ) || $newUnit === '' ) { |
||
217 | throw new InvalidArgumentException( |
||
218 | '$newUnit must be a non-empty string. Use "1" for unit-less quantities.' |
||
219 | ); |
||
220 | } |
||
221 | |||
222 | // Apply transformation by calling the $transform callback. |
||
223 | // The first argument for the callback is the DataValue to transform. In addition, |
||
224 | 7 | // any extra arguments given for transform() are passed through. |
|
225 | 7 | $args = func_get_args(); |
|
226 | array_shift( $args ); |
||
227 | 7 | ||
228 | 7 | $args[0] = $this->amount; |
|
229 | $amount = call_user_func_array( $transformation, $args ); |
||
230 | 7 | ||
231 | return new self( $amount, $newUnit ); |
||
232 | } |
||
233 | 2 | ||
234 | 2 | public function __toString() { |
|
235 | 2 | return $this->amount->getValue() |
|
236 | . ( $this->unit === '1' ? '' : $this->unit ); |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * @see DataValue::getArrayValue |
||
241 | * |
||
242 | * @return array |
||
243 | 15 | */ |
|
244 | public function getArrayValue() { |
||
245 | 15 | return [ |
|
246 | 15 | 'amount' => $this->amount->getArrayValue(), |
|
247 | 'unit' => $this->unit, |
||
248 | ]; |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * Static helper capable of constructing both unbounded and bounded quantity value objects, |
||
253 | * depending on the serialization provided. Required for @see DataValueDeserializer. |
||
254 | * This is expected to round-trip with both @see getArrayValue as well as |
||
255 | * @see QuantityValue::getArrayValue. |
||
256 | * |
||
257 | * @deprecated since 0.8.3. Static DataValue::newFromArray constructors like this are |
||
258 | * underspecified (not in the DataValue interface), and misleadingly named (should be named |
||
259 | * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer. |
||
260 | * |
||
261 | * @param mixed $data Warning! Even if this is expected to be a value as returned by |
||
262 | * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee |
||
263 | * this. This is not even guaranteed to be an array! |
||
264 | * |
||
265 | * @throws IllegalValueException if $data is not in the expected format. Subclasses of |
||
266 | * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer. |
||
267 | * @return self|QuantityValue Either an unbounded or bounded quantity value object. |
||
268 | */ |
||
269 | public static function newFromArray( $data ) { |
||
270 | self::requireArrayFields( $data, [ 'amount', 'unit' ] ); |
||
271 | |||
272 | if ( !isset( $data['upperBound'] ) && !isset( $data['lowerBound'] ) ) { |
||
273 | return new self( |
||
274 | DecimalValue::newFromArray( $data['amount'] ), |
||
0 ignored issues
–
show
|
|||
275 | $data['unit'] |
||
276 | ); |
||
277 | } else { |
||
278 | self::requireArrayFields( $data, [ 'upperBound', 'lowerBound' ] ); |
||
279 | |||
280 | return new QuantityValue( |
||
281 | DecimalValue::newFromArray( $data['amount'] ), |
||
0 ignored issues
–
show
The method
DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
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. ![]() |
|||
282 | $data['unit'], |
||
283 | DecimalValue::newFromArray( $data['upperBound'] ), |
||
0 ignored issues
–
show
The method
DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
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. ![]() |
|||
284 | DecimalValue::newFromArray( $data['lowerBound'] ) |
||
0 ignored issues
–
show
The method
DataValues\DecimalValue::newFromArray() has been deprecated with message: since 0.8.3. Static DataValue::newFromArray constructors like this are underspecified (not in the DataValue interface), and misleadingly named (should be named newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
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. ![]() |
|||
285 | ); |
||
286 | } |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * |
||
291 | * @param mixed $target |
||
292 | * |
||
293 | * @return bool |
||
294 | */ |
||
295 | 12 | public function equals( $target ) { |
|
296 | 12 | if ( $this === $target ) { |
|
297 | 3 | return true; |
|
298 | } |
||
299 | |||
300 | 12 | return $target instanceof self |
|
301 | 12 | && $this->toArray() === $target->toArray(); |
|
302 | } |
||
303 | |||
304 | } |
||
305 |
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.