PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.11
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.11
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Support / Number.php

Number.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.11, at vendor/wpfluent/framework/src/WPFluent/Support/Number.php

563 lines 13.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Support;
4
5 use RangeException;
6 use TypeError;
7
8 class Number
9 {
10 /**
11 * Format a number depending on the locale
12 *
13 * @param int|float $value
14 * @param integer $dec
15 * @return Formatted number
16 */
17 public static function format($value, $dec = 0)
18 {
19 return number_format_i18n($value, $dec);
20 }
21
22 /**
23 * Format a number as int
24 *
25 * @param int|float $value
26 * @return int
27 */
28 public static function toInt($val)
29 {
30 return intval(static::format($val));
31 }
32
33 /**
34 * Format a number as float
35 *
36 * @param int|float $value
37 * @param integer $dec
38 * @return float
39 */
40 public static function toFloat($val, $dec = 2)
41 {
42 return static::format($val, $dec);
43 }
44
45 /**
46 * Convert a number to bool
47 *
48 * @param int $val
49 * @return bool
50 */
51 public static function toBool($val)
52 {
53 return boolval(intval($val));
54 }
55
56 /**
57 * Format a number to currency depending on the locale
58 *
59 * @param int|float $value
60 * @param array $before Options fpr formatting
61 * @return Formatted number with currency symbol
62 */
63 public static function toCurrency($value, $options = [])
64 {
65 $defaults = [
66 'locale' => get_locale(),
67 'currency_symbol' => '$',
68 'number_of_decimals' => 0,
69 'space_with_currency' => 0,
70 'currency_position' => 'left',
71 ];
72
73 $args = wp_parse_args($options, $defaults);
74
75 $originalLocale = get_locale();
76 switch_to_locale($args['locale']);
77 $formattedNumber = static::format($value, $args['number_of_decimals']);
78 switch_to_locale($originalLocale);
79
80 $symbol = $args['currency_symbol'];
81
82 $space = $args['space_with_currency'] ? ' ' : '';
83
84 if ($args['currency_position'] === 'left') {
85 return $symbol . $space . $formattedNumber;
86 } else {
87 return $formattedNumber . $space . $symbol;
88 }
89 }
90
91 /**
92 * Notation to numbers.
93 *
94 * This function transforms the php.ini notation
95 * for numbers (like '2M') to an integer.
96 *
97 * @param string $size Size value.
98 * @return int
99 */
100 public static function notationToNum($num)
101 {
102 $l = substr($num, -1);
103
104 $ret = (int) substr($num, 0, -1);
105
106 switch (strtoupper($l)) {
107 case 'P':
108 $ret *= 1024;
109 // No break.
110 case 'T':
111 $ret *= 1024;
112 // No break.
113 case 'G':
114 $ret *= 1024;
115 // No break.
116 case 'M':
117 $ret *= 1024;
118 // No break.
119 case 'K':
120 $ret *= 1024;
121 // No break.
122 }
123
124 return $ret;
125 }
126
127 /**
128 * Calculates the percentage/$percent from the $value/$total
129 *
130 * @param int|float $percent
131 * @param int|float $total
132 * @return int|float
133 */
134 public static function getPercentage($percent, $total)
135 {
136 return ($percent / 100) * $total;
137 }
138
139 /**
140 * Converts a number of bytes to human readable format
141 * using the maximum unit available to convert the bytes.
142 *
143 * @param int|float $bytes
144 * @param integer $decimals
145 * @return Formatted size units of bytes, i.e: 1mb/1gb e.t.c.
146 */
147 public static function formatBytes($bytes, $decimals = 0)
148 {
149 return size_format($bytes, $decimals);
150 }
151
152 /**
153 * Makes an ordinal number from the integer
154 *
155 * @param int $number
156 * @return The ordinal number, i.e: 1st, 5th e.t.c.
157 */
158 public static function toOrdinal($number)
159 {
160 if (!is_numeric($number)) {
161 return $number;
162 }
163
164 if (($number % 100) >= 11 && ($number % 100) <= 13) {
165 $suffix = 'th';
166 } else {
167 switch ($number % 10) {
168 case 1:
169 $suffix = 'st';
170 break;
171 case 2:
172 $suffix = 'nd';
173 break;
174 case 3:
175 $suffix = 'rd';
176 break;
177 default:
178 $suffix = 'th';
179 break;
180 }
181 }
182
183 return $number . $suffix;
184 }
185
186 /**
187 * Convert the number to its human readable equivalent.
188 *
189 * @param int $number
190 * @param int $precision
191 * @param int|null $maxPrecision
192 * @return string
193 */
194 public static function forHumans($number, $precision = 0, $maxPrecision = null, $abbr = false)
195 {
196 return static::summarize($number, $precision, $maxPrecision, $abbr ? [
197 3 => 'K',
198 6 => 'M',
199 9 => 'B',
200 12 => 'T',
201 15 => 'Q',
202 ] : [
203 3 => ' thousand',
204 6 => ' million',
205 9 => ' billion',
206 12 => ' trillion',
207 15 => ' quadrillion',
208 ]);
209 }
210
211 /**
212 * Convert the number to its human readable equivalent.
213 *
214 * @param int $number
215 * @param int $precision
216 * @param int|null $maxPrecision
217 * @param array $units
218 * @return string
219 */
220 protected static function summarize($number, $precision = 0, $maxPrecision = null, $units = [])
221 {
222 if (empty($units)) {
223 $units = [
224 3 => 'K',
225 6 => 'M',
226 9 => 'B',
227 12 => 'T',
228 15 => 'Q',
229 ];
230 }
231
232 switch (true) {
233 case floatval($number) === 0.0:
234 return $precision > 0 ? static::format(0, $precision, $maxPrecision) : '0';
235 case $number < 0:
236 return sprintf('-%s', static::summarize(abs($number), $precision, $maxPrecision, $units));
237 case $number >= 1e15:
238 return sprintf('%s'.end($units), static::summarize($number / 1e15, $precision, $maxPrecision, $units));
239 }
240
241 $numberExponent = floor(log10($number));
242 $displayExponent = $numberExponent - ($numberExponent % 3);
243 $number /= pow(10, $displayExponent);
244
245 return trim(
246 sprintf('%s%s', static::format(
247 $number, $precision, $maxPrecision
248 ), $units[$displayExponent] ?? '')
249 );
250 }
251
252 /**
253 * Converts a numeric number in words
254 *
255 * @param int|float $number
256 * @param boolean $round whether to round (float to int)
257 * @param boolean $inCents whether the result should say "and n cents" for the fraction
258 * @return string number in words (in human readable words), i.e: from 199900010500.91 to:
259 * one hundred and ninety nine billion nine hundred million ten thousand five hundred and
260 * ninety one cents
261 * @throws \RangeException
262 */
263 public static function inWords($number, $options = [])
264 {
265 $defaults = [
266 'should_round' => false,
267 'thousand_seperator' => ',',
268 'decimal_seperator' => '.',
269 'use_cents_for_decimal' => true
270 ];
271
272 $args = wp_parse_args($defaults, $options);
273
274 if (!is_numeric($number)) {
275 throw new TypeError('Not a number.');
276 }
277
278 if (is_int($number) && $number > strval(PHP_INT_MAX)) {
279 throw new RangeException('out of range', 500);
280 } elseif (is_float($number) && printf('%0.0f', $number) > PHP_FLOAT_MAX) {
281 throw new RangeException('out of range', 500);
282 }
283
284 $result = '';
285
286 $numberWords = [
287 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
288 'nine','ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
289 'sixteen','seventeen', 'eighteen', 'nineteen'
290 ];
291
292 $tensWords = [
293 '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
294 ];
295
296 $decimalSeparator = $args['decimal_seperator'];
297
298 $thousandSeparator = $args['thousand_seperator'];
299
300 $number = str_replace($thousandSeparator, '', $number);
301
302 if (!is_numeric($number) || $number < 0) {
303 return 'Invalid number';
304 }
305
306 $precision = 0;
307
308 if (str_contains($number, $decimalSeparator)) {
309 $precision = 2;
310 }
311
312 if ($args['should_round']) {
313 $precision = 0;
314 }
315
316 $numberStr = str_replace($thousandSeparator, '', static::format($number, $precision));
317
318 $integerPart = strstr($numberStr, $decimalSeparator, true) ?: $numberStr;
319
320 $decimalPart = strstr($numberStr, $decimalSeparator);
321
322 if (intval($integerPart) > 0) {
323 $result .= static::spellInteger($integerPart, $numberWords, $tensWords);
324 } else {
325 $result .= 'zero';
326 }
327
328 if ($decimalPart !== false && $precision) {
329 if (!$args['use_cents_for_decimal']) {
330 $result .= ' point ' . static::spellDecimal(
331 $decimalPart, $numberWords, $decimalSeparator
332 );
333 } else {
334 $decimalPart = (int) str_replace($decimalSeparator, '', $decimalPart);
335
336 $cents = static::toCents($decimalPart, $numberWords, $tensWords);
337
338 if ($cents != 'zero') {
339 $result .= ' and ' . $cents . ' cents';
340 }
341 }
342 }
343
344 return $result;
345 }
346
347 /**
348 * Make words from integers
349 *
350 * @param int $number
351 * @param array $numberWords
352 * @param array $tensWords
353 * @return string
354 */
355 protected static function spellInteger($number, $numberWords, $tensWords)
356 {
357 $result = '';
358
359 $result .= static::convertToWords($number, $numberWords, $tensWords);
360
361 return trim($result);
362 }
363
364 /**
365 * Make words from fraction part
366 *
367 * @param int $number
368 * @param array $numberWords
369 * @return string
370 */
371 protected static function spellDecimal($number, $numberWords, $decimalSeparator)
372 {
373 $result = '';
374
375 $decimalPosition = strpos($number, $decimalSeparator);
376
377 if ($decimalPosition !== false) {
378
379 $decimalAsString = substr($number, $decimalPosition + 1);
380
381 for ($i = 0; $i < strlen($decimalAsString); $i++) {
382
383 $digit = intval($decimalAsString[$i]);
384
385 $result .= $numberWords[$digit] . ' ';
386 }
387 } else {
388 $result .= 'zero';
389 }
390
391 return trim($result);
392 }
393
394 /**
395 * Main function to make the unit words
396 *
397 * @param int|float $number
398 * @param array $numberWords
399 * @param array $tensWords
400 * @return string
401 */
402 protected static function convertToWords($number, $numberWords, $tensWords)
403 {
404 if ($number < 20) {
405 return $numberWords[$number];
406
407 } elseif ($number < 100) {
408
409 $result = $tensWords[intval($number / 10)];
410
411 if (intval($number) % 10 !== 0) {
412 $result .= ' ' . static::convertToWords(
413 intval($number) % 10, $numberWords, $tensWords
414 );
415 }
416
417 return $result;
418
419 } elseif ($number < 1000) {
420
421 $result = $numberWords[intval($number / 100)] . ' hundred';
422
423 if (intval($number) % 100 !== 0) {
424 $result .= ' and ' . static::convertToWords(
425 intval($number) % 100, $numberWords, $tensWords
426 );
427 }
428
429 return $result;
430
431 } elseif ($number < 1000000) {
432
433 $result = static::convertToWords(
434 intval($number / 1000), $numberWords, $tensWords
435 );
436
437 $result .= ' thousand';
438
439 if (intval($number) % 1000 !== 0) {
440 $result .= ' ' . static::convertToWords(
441 intval($number) % 1000, $numberWords, $tensWords
442 );
443 }
444
445 return $result;
446
447 } elseif ($number < 1000000000) {
448
449 $result = static::convertToWords(
450 intval($number / 1000000), $numberWords, $tensWords
451 );
452
453 $result .= ' million';
454
455 if (intval($number) % 1000000 !== 0) {
456 $result .= ' ' . static::convertToWords(
457 intval($number) % 1000000, $numberWords, $tensWords
458 );
459 }
460
461 return $result;
462
463 } elseif ($number < 1000000000000) {
464
465 $result = static::convertToWords(
466 intval($number / 1000000000), $numberWords, $tensWords
467 );
468
469 $result .= ' billion';
470
471 if (intval($number) % 1000000000 !== 0) {
472 $result .= ' ' . static::convertToWords(
473 intval($number) % 1000000000, $numberWords, $tensWords
474 );
475 }
476
477 return $result;
478
479 } elseif ($number < 1000000000000000) {
480
481 $result = static::convertToWords(
482 intval($number / 1000000000000), $numberWords, $tensWords
483 );
484
485 $result .= ' trillion';
486
487 if (intval($number) % 1000000000000 !== 0) {
488 $result .= ' ' . static::convertToWords(
489 intval($number) % 1000000000000, $numberWords, $tensWords
490 );
491 }
492
493 return $result;
494
495 } elseif (intval($number) < 1000000000000000000) {
496
497 $result = static::convertToWords(
498 intval($number / 1000000000000000), $numberWords, $tensWords
499 );
500
501 $result .= ' quadrillion';
502
503 if (intval($number) % 1000000000000000 !== 0) {
504 $result .= ' ' . static::convertToWords(
505 intval($number) % 1000000000000000, $numberWords, $tensWords
506 );
507 }
508
509 return $result;
510
511 } elseif (intval($number) < 1000000000000000000000) {
512
513 $result = static::convertToWords(
514 intval($number / 1000000000000000000), $numberWords, $tensWords
515 );
516
517 $result .= ' quintillion';
518
519 if (intval($number) % 1000000000000000000 !== 0) {
520 $result .= ' ' . static::convertToWords(
521 intval($number) % 1000000000000000000, $numberWords, $tensWords
522 );
523 }
524
525 return $result;
526 } else {
527 throw new RangeException('Out of range', 500);
528 }
529 }
530
531 /**
532 * Make words for cents
533 *
534 * @param int|float $cents
535 * @param array $numberWords
536 * @param array $tensWords
537 * @return string
538 */
539 protected static function toCents($cents, $numberWords, $tensWords)
540 {
541 if (array_key_exists($cents, $numberWords)) {
542 return $numberWords[$cents];
543 } elseif (array_key_exists($cents, $tensWords)) {
544 return $tensWords[$cents];
545 }
546
547 $result = '';
548 $tens = substr(floor($cents / 10) * 10, 0, 1);
549 $unitsPart = $cents % 10;
550
551 if (array_key_exists($tens, $tensWords)) {
552 $result .= $tensWords[$tens];
553 if ($unitsPart > 0) {
554 $result .= ' ' . $numberWords[$unitsPart];
555 }
556 } elseif (array_key_exists($unitsPart, $numberWords)) {
557 $result .= $numberWords[$unitsPart];
558 }
559
560 return $result;
561 }
562 }
563