Issues (4296)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/formatting.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
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
 * Get Currency Formatting Settings for each donation.
19
 *
20
 * @param int|string $id_or_currency_code Donation ID or Currency code.
21
 *
22
 * @since 1.8.15
23
 *
24
 * @return mixed
25
 */
26
function give_get_currency_formatting_settings( $id_or_currency_code = null ) {
27
	$give_options = give_get_settings();
28
	$setting      = array();
29 52
30 52
	if ( ! empty( $id_or_currency_code ) ) {
31 52
		$currencies = give_get_currencies( 'all' );
32
33
		// Set default formatting setting only if currency not set as global currency.
34 52
		if (
35
			is_string( $id_or_currency_code ) &&
36
			! empty( $give_options['currency'] ) &&
37
			$id_or_currency_code !== $give_options['currency'] &&
38
			array_key_exists( $id_or_currency_code, $currencies )
39
		) {
40
			$setting = $currencies[ $id_or_currency_code ]['setting'];
41
		} elseif ( is_numeric( $id_or_currency_code ) && 'give_payment' === get_post_type( $id_or_currency_code ) ) {
42 52
			$currency = give_get_meta( $id_or_currency_code, '_give_payment_currency', true );
43
44
			if (
45
				! empty( $currency) &&
0 ignored issues
show
Expected 1 spaces before closing bracket; 0 found
Loading history...
46 52
				$give_options['currency'] !== $currency
47
			) {
48
				$setting = $currencies[ $currency ]['setting'];
49
			}
50 52
		}
51 52
	}
52 52
53
	if ( empty( $setting ) ) {
54 52
		// Set thousand separator.
55
		$thousand_separator = isset( $give_options['thousands_separator'] ) ? $give_options['thousands_separator'] : ',';
56
		$thousand_separator = empty( $thousand_separator ) ? ' ' : $thousand_separator;
57
58 52
		// Set decimal separator.
59
		$default_decimal_separators = array(
60
			'.' => ',',
61
			',' => '.',
62
		);
63
64
		$default_decimal_separator = in_array( $thousand_separator, $default_decimal_separators ) ?
65
			$default_decimal_separators[ $thousand_separator ] :
66
			'.';
67
68
		$decimal_separator = ! empty( $give_options['decimal_separator'] ) ? $give_options['decimal_separator'] : $default_decimal_separator;
69
70
		$setting = array(
71
			'currency_position'   => give_get_option( 'currency_position', 'before' ),
72
			'thousands_separator' => $thousand_separator,
73 43
			'decimal_separator'   => $decimal_separator,
74 43
			'number_decimals'     => give_get_option( 'number_decimals', 0 ),
75
		);
76
	}
77 43
78
	/**
79
	 * Filter the currency formatting setting.
80
	 *
81
	 * @since 1.8.15
82
	 */
83
	return apply_filters( 'give_get_currency_formatting_settings', $setting, $id_or_currency_code );
84 43
}
85
86
/**
87
 * Get decimal count
88
 *
89 43
 * @since 1.6
90
 *
91
 * @param int|string $id_or_currency_code
92
 *
93
 * @return mixed
94
 */
95 View Code Duplication
function give_get_price_decimals( $id_or_currency_code = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
	// Set currency on basis of donation id.
97
	if ( empty( $id_or_currency_code ) ) {
98
		$id_or_currency_code = give_get_currency();
99 43
	}
100
101
	$number_of_decimals = 0;
102
103 43
	if ( ! give_is_zero_based_currency( $id_or_currency_code ) ) {
104 2
		$setting            = give_get_currency_formatting_settings( $id_or_currency_code );
105 2
		$number_of_decimals = $setting['number_decimals'];
106
	}
107 43
108
	/**
109 43
	 * Filter the number of decimals
110
	 *
111 43
	 * @since 1.6
112
	 */
113
	return apply_filters( 'give_sanitize_amount_decimals', $number_of_decimals, $id_or_currency_code );
114
}
115
116
/**
117
 * Get thousand separator
118
 *
119
 * @param int|string $id_or_currency_code
120
 *
121
 * @since 1.6
122
 *
123
 * @return mixed
124
 */
125
function give_get_price_thousand_separator( $id_or_currency_code = null ) {
126
	$setting = give_get_currency_formatting_settings( $id_or_currency_code );
127
128
	/**
129
	 * Filter the thousand separator
130
	 *
131
	 * @since 1.6
132
	 */
133
	return apply_filters( 'give_get_price_thousand_separator', $setting['thousands_separator'], $id_or_currency_code );
134
}
135
136
/**
137
 * Get decimal separator
138
 *
139
 * @param string $id_or_currency_code
140
 *
141
 * @since 1.6
142
 *
143
 * @return mixed
144
 */
145
function give_get_price_decimal_separator( $id_or_currency_code = null ) {
146 45
	$setting = give_get_currency_formatting_settings( $id_or_currency_code );
147 45
148 45
	/**
149
	 * Filter the thousand separator
150 45
	 *
151
	 * @since 1.6
152 45
	 */
153
	return apply_filters( 'give_get_price_decimal_separator', $setting['decimal_separator'], $id_or_currency_code );
154 45
}
155
156
157
/**
158 45
 * Sanitize Amount before saving to database
159
 *
160 45
 * @since      1.8.12
161
 *
162 45
 * @param  int|float|string $number Expects either a float or a string with a decimal separator only (no thousands)
163 45
 * @param  array|bool       $args   It accepts 'number_decimals', 'trim_zeros', 'currency'.
164 45
 *
165 45
 * @return string $amount Newly sanitized amount
166 45
 */
167 45
function give_sanitize_amount_for_db( $number, $args = array() ) {
168 45
	$args['number_decimals'] = 6;
169 45
170 45
	return give_maybe_sanitize_amount( $number, $args );
171 45
}
172 45
173 45
/**
174 45
 * Sanitize Amount before saving to database
175 45
 *
176 45
 * @since      1.8.12
177 45
 *
178 45
 * @param  int|float|string $number Expects either a float or a string with a decimal separator only (no thousands)
179 45
 * @param  array|bool       $args   It accepts 'number_decimals', 'trim_zeros', 'currency'.
180 45
 *
181 45
 * @return string $amount Newly sanitized amount
182 45
 */
183 45
function give_maybe_sanitize_amount( $number, $args = array() ) {
184 45
	// Bailout.
185 45
	if ( empty( $number ) || ( ! is_numeric( $number ) && ! is_string( $number ) ) ) {
186 45
		return $number;
187 45
	}
188 45
189 45
	$func_args = func_get_args();
190 45
191 45
	// Backward compatibility.
192 View Code Duplication
	if ( isset( $func_args[1] ) && ( is_bool( $func_args[1] ) || is_numeric( $func_args[1] ) ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
		$args = array(
194
			'number_decimals' => $func_args[1],
195
			'trim_zeros'      => isset( $func_args[2] ) ? $func_args[2] : false,
196
		);
197
	}
198
199 45
	$args = wp_parse_args(
200 45
		$args,
201
		array(
202
			'number_decimals' => false,
203
			'trim_zeros'      => false,
204
			'currency'        => give_get_currency(),
205
		)
206
	);
207
208
	$thousand_separator = give_get_price_thousand_separator( $args['currency'] );
209
	$decimal_separator  = give_get_price_decimal_separator( $args['currency'] );
210
	$number_decimals    = is_bool( $args['number_decimals'] ) ?
211
		give_get_price_decimals() :
212
		$args['number_decimals'];
213
214
	// Explode number by . decimal separator.
215
	$number_parts = explode( '.', $number );
216
217
	// Remove currency symbols from number if any.
218
	$number = trim( str_replace( give_currency_symbols( true ), '', $number ) );
219
220
	if (
221
		// Non formatted number.
222
		false === strpos( $number, $thousand_separator )
223
		&& false === strpos( $number, $decimal_separator )
224
	) {
225
		return number_format( $number, $number_decimals, '.', '' );
226
	} elseif (
227
		// Decimal formatted number.
228
		// If number of decimal place set to non zero and
229
		// number only contains `.` as separator, precision set to less then or equal to number of decimal
230
		// then number will be consider as decimal formatted which means number is already sanitized.
231
		$number_decimals
232
		&& '.' === $thousand_separator
233
		&& false !== strpos( $number, $thousand_separator )
234
		&& false === strpos( $number, $decimal_separator )
235
		&& 2 === count( $number_parts )
236
		&& ( $number_decimals >= strlen( $number_parts[1] ) )
237
	){
238 45
		return number_format( $number, $number_decimals, '.', '' );
239
	}
240
241
	// Handle thousand separator as '.'
242
	// Handle sanitize database values.
243 45
	$is_db_sanitize_val = ( 2 === count( $number_parts ) &&
244
							is_numeric( $number_parts[0] ) &&
245
							is_numeric( $number_parts[1] ) &&
246
							( 6 === strlen( $number_parts[1] ) ) );
247
248
	if ( $is_db_sanitize_val ) {
249
		// Sanitize database value.
250
		return number_format( $number, $number_decimals, '.', '' );
251
252
	} elseif (
253
		'.' === $thousand_separator &&
254
		false !== strpos( $number, $thousand_separator )
255
	) {
256
		// Fix point thousand separator value.
257 55
		$number = str_replace( '.', '', $number );
258
	}
259
260 55
	return give_sanitize_amount( $number, $args );
261 55
}
262 55
263 55
/**
264
 * Sanitize Amount
265
 *
266
 * Note: Do not this function to sanitize amount instead use give_maybe_sanitize_amount function.
267
 *
268
 * Returns a sanitized amount by stripping out thousands separators.
269 55
 *
270
 * @since      1.0
271
 *
272
 * @param  int|float|string $number Expects either a float or a string with a decimal separator only (no thousands)
273
 * @param  array|bool       $args   It accepts 'number_decimals', 'trim_zeros', 'currency'.
274
 *
275
 * @return string $amount Newly sanitized amount
276
 */
277
function give_sanitize_amount( $number, $args = array() ) {
278
279
	// Bailout.
280
	if ( empty( $number ) || ( ! is_numeric( $number ) && ! is_string( $number ) ) ) {
281
		return $number;
282
	}
283
284
	// Get function arguments.
285
	$func_args = func_get_args();
286
287
	// Backward compatibility.
288 View Code Duplication
	if ( isset( $func_args[1] ) && ( is_bool( $func_args[1] ) || is_numeric( $func_args[1] ) ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
289
		$args = array(
290
			'number_decimals' => $func_args[1],
291
			'trim_zeros'      => isset( $func_args[2] ) ? $func_args[2] : false,
292
		);
293
	}
294
295
	$args = wp_parse_args(
296
		$args,
297
		array(
298
			'number_decimals' => false,
299
			'trim_zeros'      => false,
300
			'currency'        => give_get_currency(),
301
		)
302
	);
303
304
	// Remove slash from amount.
305
	// If thousand or decimal separator is set to ' then in $_POST or $_GET param we will get an escaped number.
306
	// To prevent notices and warning remove slash from amount/number.
307
	$number = wp_unslash( $number );
308
309
	$thousand_separator = give_get_price_thousand_separator( $args['currency'] );
310
311
	$locale   = localeconv();
312
	$decimals = array(
313
		give_get_price_decimal_separator( $args['currency'] ),
314
		$locale['decimal_point'],
315
		$locale['mon_decimal_point'],
316
	);
317
318
	// Remove locale from string
319
	if ( ! is_float( $number ) ) {
320
		$number = str_replace( $decimals, '.', $number );
321
	}
322
323
	// Remove thousand amount formatting if amount has.
324
	// This condition use to add backward compatibility to version before 1.6, because before version 1.6 we were saving formatted amount to db.
325
	// Do not replace thousand separator from price if it is same as decimal separator, because it will be already replace by above code.
326
	if ( ! in_array( $thousand_separator, $decimals ) && ( false !== strpos( $number, $thousand_separator ) ) ) {
327
		$number = str_replace( $thousand_separator, '', $number );
328
	} elseif ( in_array( $thousand_separator, $decimals ) ) {
329
		$number = preg_replace( '/\.(?=.*\.)/', '', $number );
330
	}
331
332
	// Remove non numeric entity before decimal separator.
333
	$number     = preg_replace( '/[^0-9\.]/', '', $number );
334
	$default_dp = give_get_price_decimals( $args['currency'] );
335
336
	// Reset negative amount to zero.
337
	if ( 0 > $number ) {
338
		$number = number_format( 0, $default_dp, '.' );
339
	}
340
341
	// If number does not have decimal then add number of decimals to it.
342
	if (
343
		false === strpos( $number, '.' )
344
		|| ( $default_dp > strlen( substr( $number, strpos( $number, '.' ) + 1 ) ) )
345
	) {
346
		$number = number_format( $number, $default_dp, '.', '' );
347
	}
348
349
	// Format number by custom number of decimals.
350
	if ( false !== $args['number_decimals'] ) {
351
		$dp     = intval( is_bool( $args['number_decimals'] ) ? $default_dp : $args['number_decimals'] );
352
		$dp     = apply_filters( 'give_sanitize_amount_decimals', $dp, $number );
353
		$number = number_format( floatval( $number ), $dp, '.', '' );
354
	}
355
356
	// Trim zeros.
357
	if ( $args['trim_zeros'] && strstr( $number, '.' ) ) {
358
		$number = rtrim( rtrim( $number, '0' ), '.' );
359
	}
360
361
	/**
362
	 * Filter the sanitize amount
363
	 *
364
	 * @since 1.0
365
	 */
366
	return apply_filters( 'give_sanitize_amount', $number );
367
}
368
369
/**
370
 * Returns a nicely formatted amount.
371
 *
372
 * @since 1.0
373
 *
374
 * @param string $amount Price amount to format
375
 * @param array  $args   Array of arguments.
376
 *
377
 * @return string $amount   Newly formatted amount or Price Not Available
378
 */
379
function give_format_amount( $amount, $args = array() ) {
380
	// Backward compatibility.
381
	if ( is_bool( $args ) ) {
382
		$args = array(
383
			'decimal' => $args,
384
		);
385
	}
386
387
	$default_args = array(
388
		'decimal'     => true,
389
		'sanitize'    => true,
390
		'donation_id' => 0,
391
		'currency'    => '',
392
	);
393
394
	$args = wp_parse_args( $args, $default_args );
395
396
	// Set Currency based on donation id, if required.
397
	if ( $args['donation_id'] && empty( $args['currency'] ) ) {
398
		$args['currency'] = give_get_meta( $args['donation_id'], '_give_payment_currency', true );
399
	}
400
401
	$formatted     = 0;
402
	$currency      = ! empty( $args['currency'] ) ? $args['currency'] : give_get_currency( $args['donation_id'] );
403
	$thousands_sep = give_get_price_thousand_separator( $currency );
404
	$decimal_sep   = give_get_price_decimal_separator( $currency );
405
	$decimals      = ! empty( $args['decimal'] ) ? give_get_price_decimals( $currency ) : 0;
406
407
	if ( ! empty( $amount ) ) {
408
		// Sanitize amount before formatting.
409
		$amount = ! empty( $args['sanitize'] ) ?
410
			give_maybe_sanitize_amount( $amount, array( 'number_decimals' => $decimals, 'currency' => $currency ) ) :
411
			number_format( $amount, $decimals, '.', '' );
412
413
		switch ( $currency ) {
414
			case 'INR':
415
				$decimal_amount = '';
416
417
				// Extract decimals from amount
418
				if ( ( $pos = strpos( $amount, '.' ) ) !== false ) {
0 ignored issues
show
Found "!== false". Use Yoda Condition checks, you must
Loading history...
419
					if ( ! empty( $decimals ) ) {
420
						$decimal_amount = substr( round( substr( $amount, $pos ), $decimals ), 1 );
421
						$amount         = substr( $amount, 0, $pos );
422
423
						if ( ! $decimal_amount ) {
424
							$decimal_amount = substr( "{$decimal_sep}0000000000", 0, ( $decimals + 1 ) );
425
						} elseif ( ( $decimals + 1 ) > strlen( $decimal_amount ) ) {
426
							$decimal_amount = substr( "{$decimal_amount}000000000", 0, ( $decimals + 1 ) );
427
						}
428
					} else {
429
						$amount = number_format( $amount, $decimals, $decimal_sep, '' );
430
					}
431
				}
432
433
				// Extract last 3 from amount
434
				$result = substr( $amount, - 3 );
435
				$amount = substr( $amount, 0, - 3 );
436
437
				// Apply digits 2 by 2
438
				while ( strlen( $amount ) > 0 ) {
439
					$result = substr( $amount, - 2 ) . $thousands_sep . $result;
440
					$amount = substr( $amount, 0, - 2 );
441
				}
442
443
				$formatted = $result . $decimal_amount;
444
				break;
445
446
			default:
447
				$formatted = number_format( $amount, $decimals, $decimal_sep, $thousands_sep );
448
		}
449
	}
450
451
	/**
452
	 * Filter the formatted amount
453
	 *
454
	 * @since 1.0
455
	 */
456
	return apply_filters( 'give_format_amount', $formatted, $amount, $decimals, $decimal_sep, $thousands_sep, $currency, $args );
457
}
458
459
460
/**
461
 * Get human readable amount.
462
 *
463
 * Note: This function only support large number formatting from million to trillion
464
 *
465
 * @since 1.6
466
 *
467
 * @use   give_get_price_thousand_separator Get thousand separator.
468
 *
469
 * @param string $amount formatted amount number.
470
 * @param array  $args   Array of arguments.
471
 *
472
 * @return string  formatted amount number with large number names.
473
 */
474
function give_human_format_large_amount( $amount, $args = array() ) {
475
	// Sanitize amount.
476
	$sanitize_amount = give_maybe_sanitize_amount( $amount );
477
478
	// Bailout.
479
	if ( ! floatval( $sanitize_amount ) ) {
480
		return '0';
481
	};
482
483
	// Set default currency;
484
	if ( empty( $args['currency'] ) ) {
485
		$args['currency'] = give_get_currency();
486
	}
487
488
	// Get thousand separator.
489
	$thousands_sep = give_get_price_thousand_separator();
490
491
	// Explode amount to calculate name of large numbers.
492
	$amount_array = explode( $thousands_sep, $amount );
493
494
	// Calculate amount parts count.
495
	$amount_count_parts = count( $amount_array );
496
497
	// Human format amount (default).
498
	$human_format_amount = $amount;
499
500
	switch ( $args['currency'] ) {
501 View Code Duplication
		case 'INR':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
502
			// Calculate large number formatted amount.
503
			if ( 4 < $amount_count_parts ) {
504
				$human_format_amount = sprintf( esc_html__( '%s arab', 'give' ), round( ( $sanitize_amount / 1000000000 ), 2 ) );
505
			} elseif ( 3 < $amount_count_parts ) {
506
				$human_format_amount = sprintf( esc_html__( '%s crore', 'give' ), round( ( $sanitize_amount / 10000000 ), 2 ) );
507
			} elseif ( 2 < $amount_count_parts ) {
508
				$human_format_amount = sprintf( esc_html__( '%s lakh', 'give' ), round( ( $sanitize_amount / 100000 ), 2 ) );
509
			}
510
			break;
511 View Code Duplication
		default:
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
512
			// Calculate large number formatted amount.
513
			if ( 4 < $amount_count_parts ) {
514
				$human_format_amount = sprintf( esc_html__( '%s trillion', 'give' ), round( ( $sanitize_amount / 1000000000000 ), 2 ) );
515
			} elseif ( 3 < $amount_count_parts ) {
516
				$human_format_amount = sprintf( esc_html__( '%s billion', 'give' ), round( ( $sanitize_amount / 1000000000 ), 2 ) );
517
			} elseif ( 2 < $amount_count_parts ) {
518
				$human_format_amount = sprintf( esc_html__( '%s million', 'give' ), round( ( $sanitize_amount / 1000000 ), 2 ) );
519
			}
520
	}
521
522
	return apply_filters( 'give_human_format_large_amount', $human_format_amount, $amount, $sanitize_amount );
523
}
524
525
/**
526
 * Returns a nicely formatted amount with custom decimal separator.
527
 *
528
 * @since 1.0
529
 *
530
 * @param int|float|string $amount   Formatted or sanitized price
531
 * @param int|bool         $dp       number of decimals
532
 * @param bool             $sanitize Whether or not sanitize number
533
 *
534
 * @return string $amount Newly formatted amount or Price Not Available
535
 */
536
function give_format_decimal( $amount, $dp = false, $sanitize = true ) {
537
	$decimal_separator = give_get_price_decimal_separator();
538
	$formatted_amount  = $sanitize ?
539
		give_maybe_sanitize_amount( $amount, array( 'number_decimals' => $dp ) ) :
540
		number_format( $amount, ( is_bool( $dp ) ? give_get_price_decimals() : $dp ), '.', '' );
541
542
	if ( false !== strpos( $formatted_amount, '.' ) ) {
543
		$formatted_amount = str_replace( '.', $decimal_separator, $formatted_amount );
544
	}
545
546
	return apply_filters( 'give_format_decimal', $formatted_amount, $amount, $decimal_separator );
547
}
548
549
/**
550
 * Get date format string on basis of given context.
551
 *
552
 * @since 1.7
553
 *
554
 * @param  string $date_context Date format context name.
555
 *
556
 * @return string                  Date format string
557
 */
558
function give_date_format( $date_context = '' ) {
559
	/**
560
	 * Filter the date context
561
	 *
562
	 * You can add your own date context or use already exist context.
563
	 * For example:
564
	 *    add_filter( 'give_date_format_contexts', 'add_new_date_contexts' );
565
	 *    function add_new_date_contexts( $date_format_contexts ) {
566
	 *        // You can add single context like this $date_format_contexts['checkout'] = 'F j, Y';
567
	 *        // Instead add multiple date context at once.
568
	 *        $new_date_format_contexts = array(
569
	 *            'checkout' => 'F j, Y',
570
	 *            'report'   => 'Y-m-d',
571
	 *            'email'    => 'm/d/Y',
572
	 *        );
573
	 *
574
	 *       // Merge date contexts array only if you are adding multiple date contexts at once otherwise return  $date_format_contexts.
575
	 *       return array_merge( $new_date_format_contexts, $date_format_contexts );
576
	 *
577
	 *    }
578
	 */
579
	$date_format_contexts = apply_filters( 'give_date_format_contexts', array() );
580
581
	// Set date format to default date format.
582
	$date_format = get_option( 'date_format' );
583
584
	// Update date format if we have non empty date format context array and non empty date format string for that context.
585
	if ( $date_context && ! empty( $date_format_contexts ) && array_key_exists( $date_context, $date_format_contexts ) ) {
586
		$date_format = ! empty( $date_format_contexts[ $date_context ] )
587
			? $date_format_contexts[ $date_context ]
588
			: $date_format;
589
	}
590
591
	return apply_filters( 'give_date_format', $date_format );
592
}
593
594
/**
595
 * Get cache key.
596
 *
597
 * @since      1.7
598
 * @deprecated 1.8.7 You can access this function from Give_Cache.
599
 *
600
 * @param  string $action     Cache key prefix.
601
 * @param array  $query_args Query array.
602
 *
603
 * @return string
604
 */
605
function give_get_cache_key( $action, $query_args ) {
606
	return Give_Cache::get_key( $action, $query_args );
607
}
608
609
/**
610
 * Clean variables using sanitize_text_field. Arrays are cleaned recursively.
611
 * Non-scalar values are ignored.
612
 *
613
 * @since  1.8
614
 *
615
 * @param  string|array $var
616
 *
617
 * @return string|array
618
 */
619
function give_clean( $var ) {
620
	if ( is_array( $var ) ) {
621
		return array_map( 'give_clean', $var );
622
	} else {
623
		return is_scalar( $var ) ? sanitize_text_field( wp_unslash( $var ) ) : $var;
624
	}
625
}
626
627
/**
628
 * Transforms php.ini notation for numbers (like '2M') to an integer.
629
 *
630
 * @since 1.8
631
 *
632
 * @param $size
633
 *
634
 * @return int
635
 */
636
function give_let_to_num( $size ) {
637
	$l   = substr( $size, - 1 );
638
	$ret = substr( $size, 0, - 1 );
639
	switch ( strtoupper( $l ) ) {
640
		case 'P':
641
			$ret *= 1024;
642
		case 'T':
643
			$ret *= 1024;
644
		case 'G':
645
			$ret *= 1024;
646
		case 'M':
647
			$ret *= 1024;
648
		case 'K':
649
			$ret *= 1024;
650
	}
651
652
	return $ret;
653
}
654
655
/**
656
 * Verify nonce.
657
 *
658
 * @since 1.8
659
 *
660
 * @param string $nonce       Nonce Hash.
661
 * @param int    $action      Nonce verification action.
662
 * @param array  $wp_die_args Nonce fail arguments.
663
 *
664
 * @return bool
665
 */
666
function give_validate_nonce( $nonce, $action = - 1, $wp_die_args = array() ) {
667
668
	// Verify nonce.
669
	$verify_nonce = wp_verify_nonce( $nonce, $action );
670
671
	// On ajax request send nonce verification status.
672
	if ( wp_doing_ajax() ) {
673
		return $verify_nonce;
674
	}
675
676
	if ( ! $verify_nonce ) {
677
		$wp_die_args = wp_parse_args(
678
			$wp_die_args,
679
			array(
680
				'message' => __( 'Nonce verification has failed.', 'give' ),
681
				'title'   => __( 'Error', 'give' ),
682
				'args'    => array(
683
					'response' => 403,
684
				),
685
			)
686
		);
687
688
		wp_die(
689
			$wp_die_args['message'],
690
			$wp_die_args['title'],
691
			$wp_die_args['args']
692
		);
693
	}
694
695
	return true;
696
}
697
698
/**
699
 * Verify nonce while processing donation form.
700
 *
701
 * @since 2.0
702
 *
703
 * @param string $nonce   Nonce value.
704
 * @param int    $form_id Donation Form ID.
705
 *
706
 * @return bool
707
 */
708
function give_verify_donation_form_nonce( $nonce = '', $form_id ) {
709
710
	// Form nonce action.
711
	$nonce_action = "give_donation_form_nonce_{$form_id}";
712
713
	// Nonce validation.
714
	$verify_nonce = give_validate_nonce( $nonce, $nonce_action );
715
716
	if ( ! $verify_nonce ) {
717
		give_set_error( 'donation_form_nonce', __( 'Nonce verification has failed.', 'give' ) );
718
	}
719
720
	return $verify_nonce;
721
}
722
723
/**
724
 * Check variable and get default or valid value.
725
 *
726
 * Helper function to check if a variable is set, empty, etc.
727
 *
728
 * @since 1.8
729
 *
730
 * @param                   $variable
731
 * @param string (optional) $conditional    default value: isset
732
 * @param mixed (optional)  $default        default value: false
733
 * @param string (optional) $array_key_name default value: false
734
 *
735
 * @return mixed
736
 */
737
function give_check_variable( $variable, $conditional = '', $default = false, $array_key_name = '' ) {
738
	// Get value from array if array key non empty.
739
	if( empty( $array_key_name ) ) {
0 ignored issues
show
Space after opening control structure is required
Loading history...
No space before opening parenthesis is prohibited
Loading history...
740
		switch ( $conditional ) {
741
			case 'isset_empty':
742
				$variable = ( isset( $variable ) && ! empty( $variable ) ) ? $variable : $default;
743
				break;
744
745
			case 'empty':
746
				$variable = ! empty( $variable ) ? $variable : $default;
747
				break;
748
749
			case 'null':
750
				$variable = ! is_null( $variable ) ? $variable : $default;
751
				break;
752
753
			default:
754
				$variable = isset( $variable ) ? $variable : $default;
755
		}
756
	} else {
757
		$isset = array_key_exists( $array_key_name, $variable );
758
759
		switch ( $conditional ) {
760
			case 'isset_empty':
761
				$variable = ( $isset && ! empty( $variable[ $array_key_name ] ) ) ? $variable[ $array_key_name ] : $default;
762
				break;
763
764
			case 'empty':
765
				$variable = ! empty( $variable[ $array_key_name ] ) ? $variable[ $array_key_name ] : $default;
766
				break;
767
768
			case 'null':
769
				$variable = $isset && ! is_null( $variable[ $array_key_name ] ) ? $variable[ $array_key_name ] : $default;
770
				break;
771
772
			default:
773
				$variable = $isset && isset( $variable[ $array_key_name ] ) ? $variable[ $array_key_name ] : $default;
774
		}
775
	}
776
777
	return $variable;
778
779
}
780