Completed
Push — tests ( 7f3eb9...4036fb )
by Ravinder
55:16 queued 35:10
created

formatting.php ➔ give_check_variable()   C

Complexity

Conditions 9
Paths 10

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 14
nc 10
nop 3
dl 0
loc 23
rs 5.8541
c 0
b 0
f 0
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     https://opensource.org/licenses/gpl-license 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', give_get_option( 'number_decimals', 0 ) );
27
}
28
29
/**
30
 * Get thousand separator
31
 *
32
 * @since 1.6
33
 *
34
 * @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
 *
43
 * @since 1.6
44
 *
45
 * @return mixed
46
 */
47
function give_get_price_decimal_separator() {
48
	return give_get_option( 'decimal_separator', '.' );
49
}
50
51
/**
52
 * Sanitize Amount
53
 *
54
 * Returns a sanitized amount by stripping out thousands separators.
55
 *
56
 * @since      1.0
57
 *
58
 * @param  int|float|string $number     Expects either a float or a string with a decimal separator only (no thousands)
59
 * @param  int|bool         $dp         Number of decimals
60
 * @param  bool             $trim_zeros From end of string
61
 *
62
 * @return string $amount Newly sanitized amount
63
 */
64
function give_sanitize_amount( $number, $dp = false, $trim_zeros = false ) {
65
66
	// Bailout.
67
	if ( empty( $number ) ) {
68
		return $number;
69
	}
70
71
	// Remove slash from amount.
72
	// If thousand or decimal separator is set to ' then in $_POST or $_GET param we will get an escaped number.
73
	// To prevent notices and warning remove slash from amount/number.
74
	$number = wp_unslash( $number );
75
76
	$thousand_separator = give_get_price_thousand_separator();
77
78
	$locale   = localeconv();
79
	$decimals = array( give_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] );
80
81
	// Remove locale from string
82
	if ( ! is_float( $number ) ) {
83
		$number = str_replace( $decimals, '.', $number );
84
	}
85
86
	// Remove thousand amount formatting if amount has.
87
	// This condition use to add backward compatibility to version before 1.6, because before version 1.6 we were saving formatted amount to db.
88
	// Do not replace thousand separator from price if it is same as decimal separator, because it will be already replace by above code.
89
	if ( ! in_array( $thousand_separator, $decimals ) && ( false !== strpos( $number, $thousand_separator ) ) ) {
90
		$number = str_replace( $thousand_separator, '', $number );
91
	} elseif ( in_array( $thousand_separator, $decimals ) ) {
92
		$number = preg_replace( '/\.(?=.*\.)/', '', $number );
93
	}
94
95
	// Remove non numeric entity before decimal separator.
96
	$number     = preg_replace( '/[^0-9\.]/', '', $number );
97
	$default_dp = give_get_price_decimals();
98
99
	// Reset negative amount to zero.
100
	if ( 0 > $number ) {
101
		$number = number_format( 0, $default_dp, '.' );
102
	}
103
104
	// If number does not have decimal then add number of decimals to it.
105
	if (
106
		false === strpos( $number, '.' )
107
		|| ( $default_dp > strlen( substr( $number, strpos( $number, '.' ) + 1 ) ) )
108
	) {
109
		$number = number_format( $number, $default_dp, '.', '' );
110
	}
111
112
	// Format number by custom number of decimals.
113
	if ( false !== $dp ) {
114
		$dp     = intval( empty( $dp ) ? $default_dp : $dp );
115
		$dp     = apply_filters( 'give_sanitize_amount_decimals', $dp, $number );
116
		$number = number_format( floatval( $number ), $dp, '.', '' );
117
	}
118
119
	// Trim zeros.
120
	if ( $trim_zeros && strstr( $number, '.' ) ) {
121
		$number = rtrim( rtrim( $number, '0' ), '.' );
122
	}
123
124
	return apply_filters( 'give_sanitize_amount', $number );
125
}
126
127
/**
128
 * Returns a nicely formatted amount.
129
 *
130
 * @since 1.0
131
 *
132
 * @param string $amount   Price amount to format
133
 * @param bool   $decimals Whether or not to use decimals. Useful when set to false for non-currency numbers.
134
 *
135
 * @return string $amount   Newly formatted amount or Price Not Available
136
 */
137
function give_format_amount( $amount, $decimals = true ) {
138
	$thousands_sep = give_get_option( 'thousands_separator', ',' );
139
	$decimal_sep   = give_get_option( 'decimal_separator', '.' );
140
141
	if ( empty( $amount ) ) {
142
		$amount = 0;
143
	} else {
144
		// Sanitize amount before formatting.
145
		$amount = give_sanitize_amount( $amount );
146
	}
147
148
	$decimals = $decimals ? give_get_price_decimals() : 0;
149
150
	$formatted = number_format( $amount, $decimals, $decimal_sep, $thousands_sep );
151
152
	return apply_filters( 'give_format_amount', $formatted, $amount, $decimals, $decimal_sep, $thousands_sep );
153
}
154
155
156
/**
157
 * Get human readable amount.
158
 *
159
 * Note: This function only support large number formatting from million to trillion
160
 *
161
 * @since 1.6
162
 *
163
 * @use   give_get_price_thousand_separator Get thousand separator.
164
 *
165
 * @param string $amount formatted amount number.
166
 *
167
 * @return float|string  formatted amount number with large number names.
168
 */
169
function give_human_format_large_amount( $amount ) {
170
171
	// Get thousand separator.
172
	$thousands_sep = give_get_price_thousand_separator();
173
174
	// Sanitize amount.
175
	$sanitize_amount = give_sanitize_amount( $amount );
176
177
	// Explode amount to calculate name of large numbers.
178
	$amount_array = explode( $thousands_sep, $amount );
179
180
	// Calculate amount parts count.
181
	$amount_count_parts = count( $amount_array );
182
183
	// Human format amount (default).
184
	$human_format_amount = $amount;
185
186
	// Calculate large number formatted amount.
187
	if ( 4 < $amount_count_parts ) {
188
		$human_format_amount = sprintf( esc_html__( '%s trillion', 'give' ), round( ( $sanitize_amount / 1000000000000 ), 2 ) );
189
	} elseif ( 3 < $amount_count_parts ) {
190
		$human_format_amount = sprintf( esc_html__( '%s billion', 'give' ), round( ( $sanitize_amount / 1000000000 ), 2 ) );
191
	} elseif ( 2 < $amount_count_parts ) {
192
		$human_format_amount = sprintf( esc_html__( '%s million', 'give' ), round( ( $sanitize_amount / 1000000 ), 2 ) );
193
	}
194
195
	return apply_filters( 'give_human_format_large_amount', $human_format_amount, $amount, $sanitize_amount );
196
}
197
198
/**
199
 * Returns a nicely formatted amount with custom decimal separator.
200
 *
201
 * @since 1.0
202
 *
203
 * @param int|float|string $amount Formatted or sanitized price
204
 * @param int|bool         $dp     number of decimals
205
 *
206
 * @return string $amount Newly formatted amount or Price Not Available
207
 */
208
function give_format_decimal( $amount, $dp = false ) {
209
	$decimal_separator = give_get_price_decimal_separator();
210
	$formatted_amount  = give_sanitize_amount( $amount, $dp );
211
212
	if ( false !== strpos( $formatted_amount, '.' ) ) {
213
		$formatted_amount = str_replace( '.', $decimal_separator, $formatted_amount );
214
	}
215
216
	return apply_filters( 'give_format_decimal', $formatted_amount, $amount, $decimal_separator );
217
}
218
219
/**
220
 * Formats the currency display
221
 *
222
 * @since 1.0
223
 *
224
 * @param string $price
225
 * @param string $currency
226
 *
227
 * @return mixed|string
228
 */
229
function give_currency_filter( $price = '', $currency = '' ) {
230
231
	if ( empty( $currency ) ) {
232
		$currency = give_get_currency();
233
	}
234
235
	$position = give_get_option( 'currency_position', 'before' );
236
237
	$negative = $price < 0;
238
239
	if ( $negative ) {
240
		// Remove proceeding "-".
241
		$price = substr( $price, 1 );
242
	}
243
244
	$symbol = give_currency_symbol( $currency );
245
246
	switch ( $currency ) :
247
		case 'GBP' :
248
		case 'BRL' :
249
		case 'EUR' :
250
		case 'USD' :
251
		case 'AUD' :
252
		case 'CAD' :
253
		case 'HKD' :
254
		case 'MXN' :
255
		case 'NZD' :
256
		case 'SGD' :
257
		case 'JPY' :
258
		case 'THB' :
259
		case 'INR' :
260
		case 'RIAL' :
261
		case 'TRY' :
262
		case 'RUB' :
263
		case 'SEK' :
264
		case 'PLN' :
265
		case 'PHP' :
266
		case 'TWD' :
267
		case 'MYR' :
268
		case 'CZK' :
269
		case 'DKK' :
270
		case 'HUF' :
271
		case 'ILS' :
272
		case 'MAD' :
273
		case 'KRW' :
274
		case 'ZAR' :
275
			$formatted = ( 'before' === $position ? $symbol . $price : $price . $symbol );
276
			break;
277
		case 'NOK' :
278
			$formatted = ( 'before' === $position ? $symbol . ' ' . $price : $price . ' ' . $symbol );
279
			break;
280
		default :
281
			$formatted = ( 'before' === $position ? $currency . ' ' . $price : $price . ' ' . $currency );
282
			break;
283
	endswitch;
284
285
	/**
286
	 * Filter formatted amount with currency
287
	 *
288
	 * Filter name depends upon current value of currency and currency position.
289
	 * For example :
290
	 *           if currency is USD and currency position is before then
291
	 *           filter name will be give_usd_currency_filter_before
292
	 *
293
	 *           and if currency is USD and currency position is after then
294
	 *           filter name will be give_usd_currency_filter_after
295
	 */
296
	$formatted = apply_filters( 'give_' . strtolower( $currency ) . "_currency_filter_{$position}", $formatted, $currency, $price );
297
298
	if ( $negative ) {
299
		// Prepend the minus sign before the currency sign.
300
		$formatted = '-' . $formatted;
301
	}
302
303
	return $formatted;
304
}
305
306
/**
307
 * Set the number of decimal places per currency
308
 *
309
 * @since 1.0
310
 * @since 1.6 $decimals parameter removed from function params
311
 * *
312
 * @return int $decimals
313
 */
314
function give_currency_decimal_filter() {
315
316
	remove_filter( 'give_sanitize_amount_decimals', 'give_currency_decimal_filter' );
317
318
	// Set default number of decimals.
319
	$decimals = give_get_price_decimals();
320
321
	add_filter( 'give_sanitize_amount_decimals', 'give_currency_decimal_filter' );
322
323
	// Get number of decimals with backward compatibility ( version < 1.6 )
324
	if ( 1 <= func_num_args() ) {
325
		$decimals = ( false === func_get_arg( 0 ) ? $decimals : absint( func_get_arg( 0 ) ) );
326
	}
327
328
	$currency = give_get_currency();
329
330
	switch ( $currency ) {
331
		case 'RIAL' :
332
		case 'JPY' :
333
		case 'TWD' :
334
		case 'HUF' :
335
336
			$decimals = 0;
337
			break;
338
	}
339
340
	return apply_filters( 'give_currency_decimal_count', $decimals, $currency );
341
}
342
343
add_filter( 'give_sanitize_amount_decimals', 'give_currency_decimal_filter' );
344
add_filter( 'give_format_amount_decimals', 'give_currency_decimal_filter' );
345
346
347
/**
348
 * Get date format string on basis of given context.
349
 *
350
 * @since 1.7
351
 *
352
 * @param  string $date_context Date format context name.
353
 *
354
 * @return string                  Date format string
355
 */
356
function give_date_format( $date_context = '' ) {
357
	/**
358
	 * Filter the date context
359
	 *
360
	 * You can add your own date context or use already exist context.
361
	 * For example:
362
	 *    add_filter( 'give_date_format_contexts', 'add_new_date_contexts' );
363
	 *    function add_new_date_contexts( $date_format_contexts ) {
364
	 *        // You can add single context like this $date_format_contexts['checkout'] = 'F j, Y';
365
	 *        // Instead add multiple date context at once.
366
	 *        $new_date_format_contexts = array(
367
	 *            'checkout' => 'F j, Y',
368
	 *            'report'   => 'Y-m-d',
369
	 *            'email'    => 'm/d/Y',
370
	 *        );
371
	 *
372
	 *       // Merge date contexts array only if you are adding multiple date contexts at once otherwise return  $date_format_contexts.
373
	 *       return array_merge( $new_date_format_contexts, $date_format_contexts );
374
	 *
375
	 *    }
376
	 */
377
	$date_format_contexts = apply_filters( 'give_date_format_contexts', array() );
378
379
	// Set date format to default date format.
380
	$date_format = get_option( 'date_format' );
381
382
	// Update date format if we have non empty date format context array and non empty date format string for that context.
383
	if ( $date_context && ! empty( $date_format_contexts ) && array_key_exists( $date_context, $date_format_contexts ) ) {
384
		$date_format = ! empty( $date_format_contexts[ $date_context ] )
385
			? $date_format_contexts[ $date_context ]
386
			: $date_format;
387
	}
388
389
	return apply_filters( 'give_date_format', $date_format );
390
}
391
392
/**
393
 * Get cache key.
394
 *
395
 * @since  1.7
396
 *
397
 * @param  string $action     Cache key prefix.
398
 * @param array  $query_args Query array.
399
 *
400
 * @return string
401
 */
402
function give_get_cache_key( $action, $query_args ) {
403
	// Bailout.
404
	if ( ! is_array( $query_args ) || empty( $query_args ) ) {
405
		return '';
406
	}
407
408
	return "give_cache_{$action}_" . substr( md5( serialize( $query_args ) ), 0, 15 );
409
}
410
411
/**
412
 * Clean variables using sanitize_text_field. Arrays are cleaned recursively.
413
 * Non-scalar values are ignored.
414
 *
415
 * @since  1.8
416
 *
417
 * @param  string|array $var
418
 *
419
 * @return string|array
420
 */
421
function give_clean( $var ) {
422
	if ( is_array( $var ) ) {
423
		return array_map( 'give_clean', $var );
424
	} else {
425
		return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
426
	}
427
}
428
429
/**
430
 * Transforms php.ini notation for numbers (like '2M') to an integer.
431
 *
432
 * @since 1.8
433
 *
434
 * @param $size
435
 *
436
 * @return int
437
 */
438
function give_let_to_num( $size ) {
439
	$l   = substr( $size, - 1 );
440
	$ret = substr( $size, 0, - 1 );
441
	switch ( strtoupper( $l ) ) {
442
		case 'P':
443
			$ret *= 1024;
444
		case 'T':
445
			$ret *= 1024;
446
		case 'G':
447
			$ret *= 1024;
448
		case 'M':
449
			$ret *= 1024;
450
		case 'K':
451
			$ret *= 1024;
452
	}
453
454
	return $ret;
455
}
456
457
/**
458
 * Verify nonce.
459
 *
460
 * @since 1.8
461
 *
462
 * @param        $nonce
463
 * @param int   $action
464
 * @param array $wp_die_args
465
 */
466
function give_validate_nonce( $nonce, $action = - 1, $wp_die_args = array() ) {
467
468
	$default_wp_die_args = array(
469
		'message' => esc_html__( 'Nonce verification has failed.', 'give' ),
470
		'title'   => esc_html__( 'Error', 'give' ),
471
		'args'    => array( 'response' => 403 ),
472
	);
473
474
	$wp_die_args = wp_parse_args( $wp_die_args, $default_wp_die_args );
475
476
	if ( ! wp_verify_nonce( $nonce, $action ) ) {
477
		wp_die(
478
			$wp_die_args['message'],
479
			$wp_die_args['title'],
480
			$wp_die_args['args']
481
		);
482
	}
483
}
484
485
/**
486
 * Check variable and get default or valid value.
487
 *
488
 * Helper function to check if a variable is set, empty, etc.
489
 *
490
 * @since 1.8
491
 *
492
 * @param                   $variable
493
 * @param string (optional) $conditional , default value: isset
494
 * @param bool (optional)   $default     , default value: false
495
 *
496
 * @return mixed
497
 */
498
function give_check_variable( $variable, $conditional = '', $default = false ) {
499
500
	switch ( $conditional ) {
501
		case 'isset_empty':
502
			$variable = ( isset( $variable ) && ! empty( $variable ) ) ? $variable : $default;
503
			break;
504
505
		case 'empty':
506
			$variable = ! empty( $variable ) ? $variable : $default;
507
			break;
508
509
		case 'null':
510
			$variable = ! is_null( $variable ) ? $variable : $default;
511
			break;
512
513
		default:
514
			$variable = isset( $variable ) ? $variable : $default;
515
516
	}
517
518
	return $variable;
519
520
}
521