/mvc/helpers/number
[return to app]1
<?php
2 /**
3 * Number Helper.
4 *
5 * This is CakePHP 2.0 NumberHelper class updated to PHP5 syntax for Vork
6 *
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
9 *
10 * Licensed under The MIT License
11 * Redistributions of files must retain the above copyright notice.
12 *
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
14 * @link http://cakephp.org CakePHP(tm) Project
15 * @package cake.libs.view.helpers
16 * @since CakePHP(tm) v 0.10.0.1076
17 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
18 */
19
20 /**
21 * Number helper library.
22 *
23 * Methods to make numbers more readable.
24 *
25 * @package cake.libs.view.helpers
26 * @link http://book.cakephp.org/view/1452/Number
27 */
28
29 class numberHelper{
30
31 /**
32 * Currencies supported by the helper. You can add additional currency formats
33 * with NumberHelper::addFormat
34 *
35 * @var array
36 * @access protected
37 */
38 protected $_currencies = array(
39 'USD' => array(
40 'wholeSymbol' => '$', 'wholePosition' => 'before', 'fractionSymbol' => 'c', 'fractionPosition' =>
'after',
41 'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()', 'escape' =>
true
42 ),
43 'GBP' => array(
44 'wholeSymbol'=>'£', 'wholePosition' => 'before', 'fractionSymbol' => 'p',
45 'fractionPosition' => 'after', 'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.',
46 'negative' => '()','escape' => false
47 ),
48 'EUR' => array(
49 'wholeSymbol'=>'€', 'wholePosition' => 'before', 'fractionSymbol' => false,
50 'fractionPosition' => 'after', 'zero' => 0, 'places' => 2, 'thousands' => '.', 'decimals' => ',',
51 'negative' => '()', 'escape' => false
52 )
53 );
54
55 /**
56 * Default options for currency formats
57 *
58 * @var array
59 * @access protected
60 */
61 protected $_currencyDefaults = array(
62 'wholeSymbol'=>'', 'wholePosition' => 'before', 'fractionSymbol' => '', 'fractionPosition' => 'after',
63 'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true
64 );
65
66 /**
67 * Formats a number with a level of precision.
68 *
69 * @param float $number A floating point number.
70 * @param integer $precision The precision of the returned number.
71 * @return float Formatted float.
72 * @access public
73 * @link http://book.cakephp.org/view/1454/precision
74 */
75 public function precision($number, $precision = 3) {
76 return sprintf("%01.{$precision}f", $number);
77 }
78
79 /**
80 * Returns a formatted-for-humans file size.
81 *
82 * @param integer $length Size in bytes
83 * @return string Human readable size
84 * @access public
85 * @link http://book.cakephp.org/view/1456/toReadableSize
86 */
87 public function toReadableSize($size) {
88 $basics = get::helper('cakeBasics');
89 switch (true) {
90 case $size < 1024:
91 return $basics->_dn('cake', '%d Byte', '%d Bytes', $size, $size);
92 case round($size / 1024) < 1024:
93 return $basics->_d('cake', '%d KB', $this->precision($size / 1024, 0));
94 case round($size / 1024 / 1024, 2) < 1024:
95 return $basics->_d('cake', '%.2f MB', $this->precision($size / 1024 / 1024, 2));
96 case round($size / 1024 / 1024 / 1024, 2) < 1024:
97 return $basics->_d('cake', '%.2f GB', $this->precision($size / 1024 / 1024 / 1024, 2));
98 default:
99 return $basics->_d('cake', '%.2f TB', $this->precision($size / 1024 / 1024 / 1024 / 1024, 2));
100 }
101 }
102
103 /**
104 * Formats a number into a percentage string.
105 *
106 * @param float $number A floating point number
107 * @param integer $precision The precision of the returned number
108 * @return string Percentage string
109 * @access public
110 * @link http://book.cakephp.org/view/1455/toPercentage
111 */
112 public function toPercentage($number, $precision = 2) {
113 return $this->precision($number, $precision) . '%';
114 }
115
116 /**
117 * Formats a number into a currency format.
118 *
119 * @param float $number A floating point number
120 * @param integer $options if int then places, if string then before, if (,.-) then use it
121 * or array with places and before keys
122 * @return string formatted number
123 * @access public
124 * @link http://book.cakephp.org/view/1457/format
125 */
126 public function format($number, $options = false) {
127 $places = 0;
128 if (is_int($options)) {
129 $places = $options;
130 }
131
132 $separators = array(',', '.', '-', ':');
133
134 $before = $after = null;
135 if (is_string($options) && !in_array($options, $separators)) {
136 $before = $options;
137 }
138 $thousands = ',';
139 if (!is_array($options) && in_array($options, $separators)) {
140 $thousands = $options;
141 }
142 $decimals = '.';
143 if (!is_array($options) && in_array($options, $separators)) {
144 $decimals = $options;
145 }
146
147 $escape = true;
148 if (is_array($options)) {
149 $options = array_merge(array('before'=>'$', 'places' => 2,
150 'thousands' => ',', 'decimals' => '.'), $options);
151 extract($options);
152 }
153
154 $out = $before . number_format($number, $places, $decimals, $thousands) . $after;
155
156 if ($escape) {
157 $basics = get::helper('cakeBasics');
158 return $basics->h($out);
159 }
160 return $out;
161 }
162
163 /**
164 * Formats a number into a currency format.
165 *
166 * ### Options
167 *
168 * - `before` - The currency symbol to place before whole numbers ie. '$'
169 * - `after` - The currency symbol to place after decimal numbers ie. 'c'. Set to boolean false to
170 * use no decimal symbol. eg. 0.35 => $0.35.
171 * - `zero` - The text to use for zero values, can be a string or a number. ie. 0, 'Free!'
172 * - `places` - Number of decimal places to use. ie. 2
173 * - `thousands` - Thousands separator ie. ','
174 * - `decimals` - Decimal separator symbol ie. '.'
175 * - `negative` - Symbol for negative numbers. If equal to '()', the number will be wrapped with ( and )
176 * - `escape` - Should the output be htmlentity escaped? Defaults to true
177 *
178 * @param float $number
179 * @param string $currency Shortcut to default options. Valid values are 'USD', 'EUR', 'GBP', otherwise
180 * set at least 'before' and 'after' options.
181 * @param array $options
182 * @return string Number formatted as a currency.
183 * @access public
184 * @link http://book.cakephp.org/view/1453/currency
185 */
186 public function currency($number, $currency = 'USD', $options = array()) {
187 $default = $this->_currencyDefaults;
188
189 if (isset($this->_currencies[$currency])) {
190 $default = $this->_currencies[$currency];
191 } elseif (is_string($currency)) {
192 $options['before'] = $currency;
193 }
194
195 $options = array_merge($default, $options);
196
197 if (isset($options['before']) && $options['before'] !== '') {
198 $options['wholeSymbol'] = $options['before'];
199 }
200 if (isset($options['after']) && !$options['after'] !== '') {
201 $options['fractionSymbol'] = $options['after'];
202 }
203
204 $result = $options['before'] = $options['after'] = null;
205
206 $symbolKey = 'whole';
207 if ($number == 0 ) {
208 if ($options['zero'] !== 0 ) {
209 return $options['zero'];
210 }
211 } elseif ($number < 1 && $number > -1 ) {
212 if ($options['fractionSymbol'] !== false) {
213 $multiply = intval('1' . str_pad('', $options['places'], '0'));
214 $number = $number * $multiply;
215 $options['places'] = null;
216 $symbolKey = 'fraction';
217 }
218 }
219
220 $position = $options[$symbolKey.'Position'] != 'after' ? 'before' : 'after';
221 $options[$position] = $options[$symbolKey.'Symbol'];
222
223 $abs = abs($number);
224 $result = $this->format($abs, $options);
225
226 if ($number < 0 ) {
227 if ($options['negative'] == '()') {
228 $result = '(' . $result .')';
229 } else {
230 $result = $options['negative'] . $result;
231 }
232 }
233 return $result;
234 }
235
236 /**
237 * Add a currency format to the Number helper. Makes reusing
238 * currency formats easier.
239 *
240 * {{{ $number->addFormat('NOK', array('before' => 'Kr. ')); }}}
241 *
242 * You can now use `NOK` as a shortform when formatting currency amounts.
243 *
244 * {{{ $number->currency($value, 'NOK'); }}}
245 *
246 * Added formats are merged with the following defaults.
247 *
248 * {{{
249 * array(
250 * 'before' => '$', 'after' => 'c', 'zero' => 0, 'places' => 2, 'thousands' => ',',
251 * 'decimals' => '.', 'negative' => '()', 'escape' => true
252 * )
253 * }}}
254 *
255 * @param string $formatName The format name to be used in the future.
256 * @param array $options The array of options for this format.
257 * @return void
258 * @see NumberHelper::currency()
259 */
260 public function addFormat($formatName, $options) {
261 $this->_currencies[$formatName] = $options + $this->_currencyDefaults;
262 }
263 }