Completed
Pull Request — master (#770)
by Devin
20:03
created

formatting.php ➔ give_sanitize_amount()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 37
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 18.348

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 6
eloc 17
c 3
b 0
f 0
nc 16
nop 2
dl 0
loc 37
rs 8.439
ccs 6
cts 20
cp 0.3
crap 18.348
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
    }
190 45
191 45
    return apply_filters( 'give_human_format_large_amount', $sanitize_amount, $amount );
192
}
193
194
/**
195
 * Returns a nicely formatted amount with custom decimal separator.
196
 *
197
 * @since 1.0
198
 *
199 45
 * @param string      $amount   Formatted or sanitized price
200 45
 *
201
 * @return string $amount Newly formatted amount or Price Not Available
202
 */
203
function give_format_decimal( $amount ){
204
    $decimal_separator = give_get_price_decimal_separator();
205
    $formatted_amount  = give_sanitize_amount( $amount );
206
207
    if( false !== strpos( $formatted_amount, '.' ) ) {
208
        $formatted_amount = str_replace( '.', $decimal_separator, $formatted_amount );
209
    }
210
211
    return apply_filters( 'give_format_decimal', $formatted_amount, $amount, $decimal_separator );
212
}
213
214
215
/**
216
 * Format Multi-level Amount
217
 *
218
 * Loops through CMB2 repeater field and updates amount field using give_format_amount()
219
 *
220
 * @param $field_args
221
 * @param $field
222
 *
223
 * @return bool
224
 */
225
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...
226
227
	if ( empty( $field->value ) ) {
228
		return false;
229
	}
230
231
	$field->value = give_format_decimal( $field->value );
232
}
233
234
/**
235
 * Formats the currency display
236
 *
237
 * @since 1.0
238 45
 *
239
 * @param string $price
240
 * @param string $currency
241
 *
242
 * @return mixed|string|void
243 45
 */
244
function give_currency_filter( $price = '', $currency = '' ) {
245
246
	if ( empty( $currency ) ) {
247
		$currency = give_get_currency();
248
	}
249
250
	$position = give_get_option( 'currency_position', 'before' );
251
252
	$negative = $price < 0;
253
254
	if ( $negative ) {
255
		$price = substr( $price, 1 ); // Remove proceeding "-" -
256
	}
257 55
258
	$symbol = give_currency_symbol( $currency );
259
260 55
	if ( $position == 'before' ):
261 55
		switch ( $currency ):
262 55
			case 'GBP' :
263 55
			case 'BRL' :
264
			case 'EUR' :
265
			case 'USD' :
266
			case 'AUD' :
267
			case 'CAD' :
268
			case 'HKD' :
269 55
			case 'MXN' :
270
			case 'NZD' :
271
			case 'SGD' :
272
			case 'JPY' :
273
			case 'THB' :
274
			case 'INR' :
275
			case 'RIAL' :
276
			case 'TRY' :
277
			case 'RUB' :
278
			case 'SEK' :
279
			case 'PLN' :
280
			case 'PHP' :
281
			case 'TWD' :
282
			case 'MYR' :
283
			case 'CZK' :
284
			case 'DKK' :
285
			case 'HUF' :
286
			case 'ILS' :
287
			case 'MAD' :
288
			case 'KRW' :
289
			case 'ZAR' :
290
				$formatted = $symbol . $price;
291
				break;
292
			case 'NOK' :
293
				$formatted = $symbol . ' ' . $price;
294
				break;
295
			default :
296
				$formatted = $currency . ' ' . $price;
297
				break;
298
		endswitch;
299
		$formatted = apply_filters( 'give_' . strtolower( $currency ) . '_currency_filter_before', $formatted, $currency, $price );
300
	else :
301
		switch ( $currency ) :
302
			case 'GBP' :
303
			case 'BRL' :
304
			case 'EUR' :
305
			case 'USD' :
306
			case 'AUD' :
307
			case 'CAD' :
308
			case 'HKD' :
309
			case 'MXN' :
310
			case 'SGD' :
311
			case 'JPY' :
312
			case 'THB' :
313
			case 'INR' :
314
			case 'RIAL' :
315
			case 'TRY' :
316
			case 'RUB' :
317
			case 'SEK' :
318
			case 'PLN' :
319
			case 'PHP' :
320
			case 'TWD' :
321
			case 'CZK' :
322
			case 'DKK' :
323
			case 'HUF' :
324
			case 'MYR' :
325
			case 'ILS' :
326
			case 'MAD' :
327
			case 'KRW' :
328
			case 'ZAR' :
329
				$formatted = $price . $symbol;
330
				break;
331
			default :
332
				$formatted = $price . ' ' . $currency;
333
				break;
334
		endswitch;
335
		$formatted = apply_filters( 'give_' . strtolower( $currency ) . '_currency_filter_after', $formatted, $currency, $price );
336
	endif;
337
338
	if ( $negative ) {
339
		// Prepend the mins sign before the currency sign
340
		$formatted = '-' . $formatted;
341
	}
342
343
	return $formatted;
344
}
345
346
/**
347
 * Set the number of decimal places per currency
348
 *
349
 * @since 1.0
350
 *
351
 * @param int $decimals Number of decimal places
352
 *
353
 * @return int $decimals
354
 */
355
function give_currency_decimal_filter( $decimals = 2 ) {
356
357
	$currency = give_get_currency();
358
359
	switch ( $currency ) {
360
		case 'RIAL' :
361
		case 'JPY' :
362
		case 'TWD' :
363
		case 'HUF' :
364
365
			$decimals = 0;
366
			break;
367
	}
368
369
	return apply_filters( 'give_currency_decimal_count', $decimals, $currency );
370
}
371
372
add_filter( 'give_sanitize_amount_decimals', 'give_currency_decimal_filter' );
373
add_filter( 'give_format_amount_decimals', 'give_currency_decimal_filter' );
374
375
/**
376
 * Sanitize thousand separator
377
 *
378
 * @since 1.6
379
 *
380
 * @param string $value
381
 * @param array  $field_args
382
 * @param object $field
383
 *
384
 * @return mixed
385
 */
386
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...
387
    return $value;
388
}