Completed
Pull Request — master (#791)
by Devin
17:46
created

formatting.php ➔ give_format_decimal()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 6
Bugs 0 Features 2
Metric Value
cc 2
eloc 6
c 6
b 0
f 2
nc 2
nop 1
dl 0
loc 10
rs 9.4285
ccs 0
cts 10
cp 0
crap 6
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 25 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Formatting functions for taking care of proper number formats and such
4
 *
5
 * @package     Give
6
 * @subpackage  Functions/Formatting
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
18
/**
19
 * Get decimal count
20
 *
21
 * @since 1.6
22
 *
23
 * @return mixed
24
 */
25
function give_get_price_decimals() {
26
    return apply_filters( 'give_sanitize_amount_decimals', 2 );
27
}
28
29 52
/**
30 52
 * Get thousand separator
31 52
 *
32
 * @since 1.6
33
 *
34 52
 * @return mixed
35
 */
36
function give_get_price_thousand_separator() {
37
    return give_get_option( 'thousands_separator', ',' );
38
}
39
40
/**
41
 * Get decimal separator
42 52
 *
43
 * @since 1.6
44
 *
45
 * @return mixed
46 52
 */
47
function give_get_price_decimal_separator() {
48
    return give_get_option( 'decimal_separator', '.' );
49
}
50 52
51 52
/**
52 52
 * Sanitize Amount
53
 *
54 52
 * Returns a sanitized amount by stripping out thousands separators.
55
 *
56
 * @since      1.0
57
 *
58 52
 * @param  float|string $number     Expects either a float or a string with a decimal separator only (no thousands)
59
 * @param  bool         $trim_zeros From end of string
60
 *
61
 *
62
 * @return string $amount Newly sanitized amount
63
 */
64
function give_sanitize_amount( $number, $trim_zeros = false ) {
65
    $thousand_separator = give_get_price_thousand_separator();
66
67
    $locale   = localeconv();
68
    $decimals = array( give_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] );
69
70
    // Remove locale from string
71
    if ( ! is_float( $number ) ) {
72
        $number = str_replace( $decimals, '.', $number );
73 43
    }
74 43
75
    // Remove thousand amount formatting if amount has.
76
    // This condition use to add backward compatibility to version before 1.6, because before version 1.6 we were saving formatted amount to db.
77 43
    if( false !== strpos( $number, $thousand_separator ) ) {
78
        $number = str_replace( $thousand_separator, '', $number );
79
    }
80
81
    // Remove non numeric entity before decimal separator.
82
    $number   = preg_replace( '/[^0-9\.]/', '', $number );
83
84 43
    $decimals = give_get_price_decimals();
85
    $decimals = apply_filters( 'give_sanitize_amount_decimals', $decimals, $number );
86
87
    $number = number_format( floatval( $number ), $decimals, '.', '' );
88
89 43
    // Reset negative amount to zero.
90
	if ( 0 > $number ) {
91
		$number = number_format( 0, 2, '.' );
92
	}
93
94
    // Trim zeros.
95
    if ( $trim_zeros && strstr( $number, '.' ) ) {
96
        $number = rtrim( rtrim( $number, '0' ), '.' );
97
    }
98
99 43
	return apply_filters( 'give_sanitize_amount', $number );
100
}
101
102
/**
103 43
 * Returns a nicely formatted amount.
104 2
 *
105 2
 * @since 1.0
106
 *
107 43
 * @param string      $amount   Price amount to format
108
 * @param bool|string $decimals Whether or not to use decimals. Useful when set to false for non-currency numbers.
109 43
 *
110
 * @return string $amount Newly formatted amount or Price Not Available
111 43
 */
112
function give_format_amount( $amount, $decimals = true ) {
113
114
	$thousands_sep = give_get_option( 'thousands_separator', ',' );
115
	$decimal_sep   = give_get_option( 'decimal_separator', '.' );
116
117
	// Format the amount
118
	if ( $decimal_sep == ',' && false !== ( $sep_found = strpos( $amount, $decimal_sep ) ) ) {
119
		$whole  = substr( $amount, 0, $sep_found );
120
		$part   = substr( $amount, $sep_found + 1, ( strlen( $amount ) - 1 ) );
121
		$amount = $whole . '.' . $part;
122
	}
123
124
	// Strip , from the amount (if set as the thousands separator)
125
	if ( $thousands_sep == ',' && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) {
126
		$amount = str_replace( ',', '', $amount );
127
	}
128
129
	// Strip . from the amount (if set as the thousands separator) AND , set to decimal separator
130
	if ( $thousands_sep == '.' && $decimal_sep == ',' && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) {
131
		$amount      = explode( '.', $amount );
132
		$array_count = count( $amount );
133
		if ( $decimals == true ) {
134
			unset( $amount[ $array_count - 1 ] );
135
		}
136
		$amount = implode( '', $amount );
137
	}
138
139
	// Strip ' ' from the amount (if set as the thousands separator)
140
	if ( $thousands_sep == ' ' && false !== ( $found = strpos( $amount, $thousands_sep ) ) ) {
141
		$amount = str_replace( ' ', '', $amount );
142
	}
143
144
	if ( empty( $amount ) ) {
145
		$amount = 0;
146 45
	}
147 45
148 45
	$decimals = give_get_price_decimals();
149
150 45
	$formatted = number_format( $amount, $decimals, $decimal_sep, $thousands_sep );
151
152 45
	return apply_filters( 'give_format_amount', $formatted, $amount, $decimals, $decimal_sep, $thousands_sep );
153
}
154 45
155
156
/**
157
 * Get human readable amount.
158 45
 *
159
 * Note: This function only support large number formatting from million to trillion
160 45
 *
161
 * @since 1.6
162 45
 *
163 45
 * @use  give_get_price_thousand_separator Get thousand separator.
164 45
 *
165 45
 * @param string $amount formatted amount number.
166 45
 * @return float|string  formatted amount number with large number names.
167 45
 */
168 45
function give_human_format_large_amount( $amount ) {
169 45
170 45
    // Get thousand separator.
171 45
    $thousands_sep = give_get_price_thousand_separator();
172 45
173 45
    // Sanitize amount.
174 45
    $sanitize_amount = give_sanitize_amount( $amount );
175 45
176 45
    // Explode amount to calculate name of large numbers.
177 45
	$amount_array = explode( $thousands_sep, $amount );
178 45
179 45
    // Calculate amount parts count.
180 45
    $amount_count_parts = count( $amount_array );
181 45
182 45
    // Calculate large number formatted amount.
183 45
    if ( 4 < $amount_count_parts ){
184 45
        $sanitize_amount =  sprintf( __( '%s trillion', 'give' ), round( ( $sanitize_amount / 1000000000000 ), 2 ) );
185 45
    } elseif ( 3 < $amount_count_parts ){
186 45
        $sanitize_amount =  sprintf( __( '%s billion', 'give' ), round( ( $sanitize_amount / 1000000000 ), 2 ));
187 45
    } elseif ( 2 < $amount_count_parts  ) {
188 45
        $sanitize_amount =  sprintf( __( '%s million', 'give' ), round( ( $sanitize_amount / 1000000), 2 ) );
189 45
    } else{
190 45
        $sanitize_amount = give_format_amount( $amount );
191 45
    }
192
193
    return apply_filters( 'give_human_format_large_amount', $sanitize_amount, $amount );
194
}
195
196
/**
197
 * Returns a nicely formatted amount with custom decimal separator.
198
 *
199 45
 * @since 1.0
200 45
 *
201
 * @param string      $amount   Formatted or sanitized price
202
 *
203
 * @return string $amount Newly formatted amount or Price Not Available
204
 */
205
function give_format_decimal( $amount ){
206
    $decimal_separator = give_get_price_decimal_separator();
207
    $formatted_amount  = give_sanitize_amount( $amount );
208
209
    if( false !== strpos( $formatted_amount, '.' ) ) {
210
        $formatted_amount = str_replace( '.', $decimal_separator, $formatted_amount );
211
    }
212
213
    return apply_filters( 'give_format_decimal', $formatted_amount, $amount, $decimal_separator );
214
}
215
216
217
/**
218
 * Format Multi-level Amount
219
 *
220
 * Loops through CMB2 repeater field and updates amount field using give_format_amount()
221
 *
222
 * @param $field_args
223
 * @param $field
224
 *
225
 * @return bool
226
 */
227
function give_format_admin_multilevel_amount( $field_args, $field ) {
0 ignored issues
show
Unused Code introduced by
The parameter $field_args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
228
229
	if ( empty( $field->value ) ) {
230
		return false;
231
	}
232
233
	$field->value = give_format_decimal( $field->value );
234
}
235
236
/**
237
 * Formats the currency display
238 45
 *
239
 * @since 1.0
240
 *
241
 * @param string $price
242
 * @param string $currency
243 45
 *
244
 * @return mixed|string|void
245
 */
246
function give_currency_filter( $price = '', $currency = '' ) {
247
248
	if ( empty( $currency ) ) {
249
		$currency = give_get_currency();
250
	}
251
252
	$position = give_get_option( 'currency_position', 'before' );
253
254
	$negative = $price < 0;
255
256
	if ( $negative ) {
257 55
		$price = substr( $price, 1 ); // Remove proceeding "-" -
258
	}
259
260 55
	$symbol = give_currency_symbol( $currency );
261 55
262 55
	if ( $position == 'before' ):
263 55
		switch ( $currency ):
264
			case 'GBP' :
265
			case 'BRL' :
266
			case 'EUR' :
267
			case 'USD' :
268
			case 'AUD' :
269 55
			case 'CAD' :
270
			case 'HKD' :
271
			case 'MXN' :
272
			case 'NZD' :
273
			case 'SGD' :
274
			case 'JPY' :
275
			case 'THB' :
276
			case 'INR' :
277
			case 'RIAL' :
278
			case 'TRY' :
279
			case 'RUB' :
280
			case 'SEK' :
281
			case 'PLN' :
282
			case 'PHP' :
283
			case 'TWD' :
284
			case 'MYR' :
285
			case 'CZK' :
286
			case 'DKK' :
287
			case 'HUF' :
288
			case 'ILS' :
289
			case 'MAD' :
290
			case 'KRW' :
291
			case 'ZAR' :
292
				$formatted = $symbol . $price;
293
				break;
294
			case 'NOK' :
295
				$formatted = $symbol . ' ' . $price;
296
				break;
297
			default :
298
				$formatted = $currency . ' ' . $price;
299
				break;
300
		endswitch;
301
		$formatted = apply_filters( 'give_' . strtolower( $currency ) . '_currency_filter_before', $formatted, $currency, $price );
302
	else :
303
		switch ( $currency ) :
304
			case 'GBP' :
305
			case 'BRL' :
306
			case 'EUR' :
307
			case 'USD' :
308
			case 'AUD' :
309
			case 'CAD' :
310
			case 'HKD' :
311
			case 'MXN' :
312
			case 'SGD' :
313
			case 'JPY' :
314
			case 'THB' :
315
			case 'INR' :
316
			case 'RIAL' :
317
			case 'TRY' :
318
			case 'RUB' :
319
			case 'SEK' :
320
			case 'PLN' :
321
			case 'PHP' :
322
			case 'TWD' :
323
			case 'CZK' :
324
			case 'DKK' :
325
			case 'HUF' :
326
			case 'MYR' :
327
			case 'ILS' :
328
			case 'MAD' :
329
			case 'KRW' :
330
			case 'ZAR' :
331
				$formatted = $price . $symbol;
332
				break;
333
			default :
334
				$formatted = $price . ' ' . $currency;
335
				break;
336
		endswitch;
337
		$formatted = apply_filters( 'give_' . strtolower( $currency ) . '_currency_filter_after', $formatted, $currency, $price );
338
	endif;
339
340
	if ( $negative ) {
341
		// Prepend the mins sign before the currency sign
342
		$formatted = '-' . $formatted;
343
	}
344
345
	return $formatted;
346
}
347
348
/**
349
 * Set the number of decimal places per currency
350
 *
351
 * @since 1.0
352
 *
353
 * @param int $decimals Number of decimal places
354
 *
355
 * @return int $decimals
356
 */
357
function give_currency_decimal_filter( $decimals = 2 ) {
358
359
	$currency = give_get_currency();
360
361
	switch ( $currency ) {
362
		case 'RIAL' :
363
		case 'JPY' :
364
		case 'TWD' :
365
		case 'HUF' :
366
367
			$decimals = 0;
368
			break;
369
	}
370
371
	return apply_filters( 'give_currency_decimal_count', $decimals, $currency );
372
}
373
374
add_filter( 'give_sanitize_amount_decimals', 'give_currency_decimal_filter' );
375
add_filter( 'give_format_amount_decimals', 'give_currency_decimal_filter' );
376
377
/**
378
 * Sanitize thousand separator
379
 *
380
 * @since 1.6
381
 *
382
 * @param string $value
383
 * @param array  $field_args
384
 * @param object $field
385
 *
386
 * @return mixed
387
 */
388
function give_sanitize_thousand_separator( $value, $field_args, $field ){
0 ignored issues
show
Unused Code introduced by
The parameter $field_args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
389
    return $value;
390
}