1 <?php
2 /**
3 * @package Joomla.Libraries
4 * @subpackage HTML
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE.txt
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * HTML helper class for rendering numbers.
14 *
15 * @since 1.6
16 */
17 abstract class JHtmlNumber
18 {
19 /**
20 * Converts bytes to more distinguishable formats such as:
21 * kilobytes, megabytes, etc.
22 *
23 * By default, the proper format will automatically be chosen.
24 * However, one of the allowed unit types (viz. 'b', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB') may also be used instead.
25 * IEC standard unit types ('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB') can be used as well.
26 *
27 * @param string $bytes The number of bytes. Can be either numeric or suffixed format: 32M, 60K, 12G or 812b
28 * @param string $unit The type of unit to return, few special values are:
29 * Blank string '' for no unit,
30 * 'auto' to choose automatically (default)
31 * 'binary' to choose automatically but use binary unit prefix
32 * @param integer $precision The number of digits to be used after the decimal place.
33 * @param bool $iec Whether to be aware of IEC standards. IEC prefixes are always acceptable in input.
34 * When IEC is ON: KiB = 1024 B, KB = 1000 B
35 * When IEC is OFF: KiB = 1024 B, KB = 1024 B
36 *
37 * @return string The number of bytes in the proper units.
38 *
39 * @since 1.6
40 * @link https://en.wikipedia.org/wiki/Binary_prefix
41 */
42 public static function bytes($bytes, $unit = 'auto', $precision = 2, $iec = false)
43 {
44 /*
45 * Allowed 123.45, 123.45 M, 123.45 Mi, 123.45 MB, 123.45 MiB, 1.2345E+12MB, 1.2345E+12 MB , 1.2345E+12 MiB etc.
46 * i.e. – Any number in decimal digits or in sci. notation, optional space, optional 1-3 letter unit suffix
47 */
48 if (is_numeric($bytes))
49 {
50 $oBytes = $bytes;
51 }
52 else
53 {
54 preg_match('/(.*?)\s?((?:[KMGTPEZY]i?)?B?)$/i', trim($bytes), $matches);
55 list(, $oBytes, $oUnit) = $matches;
56
57 if ($oUnit && is_numeric($oBytes))
58 {
59 $oBase = $iec && strpos($oUnit, 'i') === false ? 1000 : 1024;
60 $factor = pow($oBase, stripos('BKMGTPEZY', $oUnit[0]));
61 $oBytes *= $factor;
62 }
63 }
64
65 if (empty($oBytes) || !is_numeric($oBytes))
66 {
67 return 0;
68 }
69
70 $oBytes = round($oBytes);
71
72 // If no unit is requested return early
73 if ($unit === '')
74 {
75 return (string) $oBytes;
76 }
77
78 $stdSuffixes = array('b', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
79 $iecSuffixes = array('b', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB');
80
81 // User supplied method
82 if (in_array($unit, $iecSuffixes))
83 {
84 $base = 1024;
85 $i = array_search($unit, $iecSuffixes, true);
86 $suffix = $unit;
87 }
88 elseif (in_array($unit, $stdSuffixes))
89 {
90 $base = $iec ? 1000 : 1024;
91 $i = array_search($unit, $stdSuffixes, true);
92 $suffix = $unit;
93 }
94 elseif ($unit === 'binary')
95 {
96 $base = 1024;
97 $i = (int) floor(log($oBytes, $base));
98 $suffix = $iecSuffixes[$i];
99 }
100 else
101 {
102 // Default method
103 $base = $iec ? 1000 : 1024;
104 $i = (int) floor(log($oBytes, $base));
105 $suffix = $stdSuffixes[$i];
106 }
107
108 return number_format(
109 round($oBytes / pow($base, $i), (int) $precision), (int) $precision, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')
110 ) . ' ' . $suffix;
111 }
112 }
113