PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.9.0
GiveWP – Donation Plugin and Fundraising Platform v4.9.0
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / formatting.php
give / includes Last commit date
admin 9 months ago api 3 years ago database 9 months ago deprecated 9 months ago donors 9 months ago emails 9 months ago forms 9 months ago frontend 6 years ago gateways 9 months ago libraries 9 months ago payments 9 months ago actions.php 9 months ago ajax-functions.php 9 months ago class-give-async-process.php 1 year ago class-give-background-updater.php 9 months ago class-give-cache-setting.php 1 year ago class-give-cache.php 9 months ago class-give-cli-commands.php 1 year ago class-give-comment.php 9 months ago class-give-cron.php 9 months ago class-give-donate-form.php 1 year ago class-give-donor.php 2 years ago class-give-email-access.php 5 years ago class-give-license-handler.php 1 year ago class-give-logging.php 9 months ago class-give-readme-parser.php 4 years ago class-give-roles.php 6 years ago class-give-scripts.php 1 year ago class-give-session.php 9 months ago class-give-stats.php 6 years ago class-give-template-loader.php 6 years ago class-give-tooltips.php 6 years ago class-give-translation.php 4 years ago class-notices.php 9 months ago country-functions.php 1 year ago currencies-list.php 3 years ago currency-functions.php 3 years ago error-tracking.php 6 years ago filters.php 9 months ago formatting.php 9 months ago install.php 9 months ago login-register.php 2 years ago misc-functions.php 9 months ago plugin-compatibility.php 6 years ago post-types.php 1 year ago price-functions.php 6 years ago process-donation.php 1 year ago setting-functions.php 6 years ago shortcodes.php 1 year ago template-functions.php 1 year ago user-functions.php 3 years ago
formatting.php
894 lines
1 <?php
2 /**
3 * Formatting functions for taking care of proper number formats and such
4 *
5 * @package Give
6 * @since 1.0
7 * @copyright Copyright (c) 2016, GiveWP
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @subpackage Functions/Formatting
10 */
11
12 // Exit if accessed directly.
13 use Give\Helpers\Utils;
14
15 if ( ! defined('ABSPATH')) {
16 exit;
17 }
18
19 /**
20 * Get Currency Formatting Settings for each donation.
21 *
22 * @since 1.8.15
23 *
24 * @param int|string $id_or_currency_code Donation ID or Currency code.
25 *
26 * @return mixed
27 */
28 function give_get_currency_formatting_settings($id_or_currency_code = null)
29 {
30 $give_options = give_get_settings();
31 $setting = [];
32
33 if ( ! empty($id_or_currency_code)) {
34 $currencies = give_get_currencies('all');
35
36 // Set default formatting setting only if currency not set as global currency.
37 if (
38 is_string($id_or_currency_code) &&
39 ! empty($give_options['currency']) &&
40 $id_or_currency_code !== $give_options['currency'] &&
41 array_key_exists($id_or_currency_code, $currencies)
42 ) {
43 $setting = $currencies[$id_or_currency_code]['setting'];
44 } elseif (is_numeric($id_or_currency_code) && 'give_payment' === get_post_type($id_or_currency_code)) {
45 $currency = give_get_meta($id_or_currency_code, '_give_payment_currency', true);
46
47 if (
48 ! empty($currency) &&
49 $give_options['currency'] !== $currency
50 ) {
51 $setting = $currencies[$currency]['setting'];
52 }
53 }
54 }
55
56 if (empty($setting)) {
57 // Set thousand separator.
58 $thousand_separator = isset($give_options['thousands_separator']) ? $give_options['thousands_separator'] : ',';
59 $thousand_separator = empty($thousand_separator) ? ' ' : $thousand_separator;
60
61 // Set decimal separator.
62 $default_decimal_separators = [
63 '.' => ',',
64 ',' => '.',
65 ];
66
67 $default_decimal_separator = in_array($thousand_separator, $default_decimal_separators) ?
68 $default_decimal_separators[$thousand_separator] :
69 '.';
70
71 $decimal_separator = ! empty($give_options['decimal_separator']) ? $give_options['decimal_separator'] : $default_decimal_separator;
72
73 $setting = [
74 'currency_position' => give_get_option('currency_position', 'before'),
75 'thousands_separator' => $thousand_separator,
76 'decimal_separator' => $decimal_separator,
77 'number_decimals' => give_get_option('number_decimals', 0),
78 ];
79 }
80
81 /**
82 * Filter the currency formatting setting.
83 *
84 * @since 1.8.15
85 */
86 return apply_filters('give_get_currency_formatting_settings', $setting, $id_or_currency_code);
87 }
88
89 /**
90 * Get decimal count
91 *
92 * @since 1.6
93 *
94 * @param int|string $id_or_currency_code
95 *
96 * @return mixed
97 */
98 function give_get_price_decimals($id_or_currency_code = null)
99 {
100 // Set currency on basis of donation id.
101 if (empty($id_or_currency_code)) {
102 $id_or_currency_code = give_get_currency();
103 }
104
105 $number_of_decimals = 0;
106
107 if ( ! give_is_zero_based_currency($id_or_currency_code)) {
108 $setting = give_get_currency_formatting_settings($id_or_currency_code);
109 $number_of_decimals = $setting['number_decimals'];
110 }
111
112 /**
113 * Filter the number of decimals
114 *
115 * @since 1.6
116 */
117 return apply_filters('give_sanitize_amount_decimals', $number_of_decimals, $id_or_currency_code);
118 }
119
120 /**
121 * Get thousand separator
122 *
123 * @since 1.6
124 *
125 * @param int|string $id_or_currency_code
126 *
127 * @return mixed
128 */
129 function give_get_price_thousand_separator($id_or_currency_code = null)
130 {
131 $setting = give_get_currency_formatting_settings($id_or_currency_code);
132
133 /**
134 * Filter the thousand separator
135 *
136 * @since 1.6
137 */
138 return apply_filters('give_get_price_thousand_separator', $setting['thousands_separator'], $id_or_currency_code);
139 }
140
141 /**
142 * Get decimal separator
143 *
144 * @since 1.6
145 *
146 * @param string $id_or_currency_code
147 *
148 * @return mixed
149 */
150 function give_get_price_decimal_separator($id_or_currency_code = null)
151 {
152 $setting = give_get_currency_formatting_settings($id_or_currency_code);
153
154 /**
155 * Filter the thousand separator
156 *
157 * @since 1.6
158 */
159 return apply_filters('give_get_price_decimal_separator', $setting['decimal_separator'], $id_or_currency_code);
160 }
161
162 /**
163 * Check if amount sanitized
164 * Note: only for internal purpose
165 *
166 * Current this function only check if number is DB sanitize.
167 *
168 * @since 2.4.5
169 *
170 * @param string $amount
171 *
172 * @return bool
173 */
174 function give_is_amount_sanitized($amount)
175 {
176 $is_sanitize = false;
177
178 if (false === strpos($amount, '.')) {
179 return $is_sanitize;
180 }
181
182 $number_parts = explode('.', $amount);
183
184 // Handle thousand separator as '.'
185 // Handle sanitize database values.
186 $is_sanitize = (2 === count($number_parts) &&
187 is_numeric($number_parts[0]) &&
188 is_numeric($number_parts[1]) &&
189 in_array(strlen($number_parts[1]), [6, 10]));
190
191 return $is_sanitize;
192 }
193
194 /**
195 * Sanitize Amount before saving to database
196 *
197 * @since 1.8.12
198 *
199 * @param int|float|string $number Expects either a float or a string with a decimal separator only (no thousands)
200 * @param array|bool $args It accepts 'number_decimals', 'trim_zeros', 'currency'.
201 *
202 * @return string $amount Newly sanitized amount
203 */
204 function give_sanitize_amount_for_db($number, $args = [])
205 {
206 $args['number_decimals'] = 6;
207
208 if (
209 (isset($args['currency']) && 'XBT' === $args['currency'])
210 || 'XBT' === give_get_currency()
211 ) {
212 $args['number_decimals'] = 10;
213 }
214
215 return give_maybe_sanitize_amount($number, $args);
216 }
217
218 /**
219 * Sanitize Amount before saving to database
220 *
221 * @since 4.9.0 PHP 8 compatibility
222 * @since 1.8.12
223 *
224 * @param int|float|string $number Expects either a float or a string with a decimal separator only (no thousands)
225 * @param array|bool $args It accepts 'number_decimals', 'trim_zeros', 'currency'.
226 *
227 * @return string $amount Newly sanitized amount
228 */
229 function give_maybe_sanitize_amount($number, $args = [])
230 {
231 // Bailout.
232 if (empty($number) || ( ! is_numeric($number) && ! is_string($number))) {
233 return $number;
234 }
235
236 $args = wp_parse_args(
237 $args,
238 [
239 'number_decimals' => false,
240 'trim_zeros' => false,
241 'currency' => give_get_currency(),
242 ]
243 );
244
245 $thousand_separator = give_get_price_thousand_separator($args['currency']);
246 $decimal_separator = give_get_price_decimal_separator($args['currency']);
247 $number_decimals = is_bool($args['number_decimals']) ?
248 give_get_price_decimals($args['currency']) :
249 $args['number_decimals'];
250
251 // Explode number by . decimal separator.
252 $number_parts = explode('.', $number);
253
254 // Remove currency symbols from number if any.
255 $number = trim(str_replace(give_currency_symbols(true), '', $number));
256
257 if (
258 // Non formatted number.
259 false === strpos($number, $thousand_separator)
260 && false === strpos($number, $decimal_separator)
261 ) {
262 return number_format($number, $number_decimals, '.', '');
263 } elseif (
264 // Decimal formatted number.
265 // If number of decimal place set to non zero and
266 // number only contains `.` as separator, precision set to less then or equal to number of decimal
267 // then number will be consider as decimal formatted which means number is already sanitized.
268 $number_decimals
269 && '.' === $thousand_separator
270 && false !== strpos($number, $thousand_separator)
271 && false === strpos($number, $decimal_separator)
272 && 2 === count($number_parts)
273 && ($number_decimals >= strlen($number_parts[1]))
274 ) {
275 return number_format($number, $number_decimals, '.', '');
276 }
277
278 if (give_is_amount_sanitized($number)) {
279 // Sanitize database value.
280 return number_format($number, $number_decimals, '.', '');
281 } elseif (
282 '.' === $thousand_separator &&
283 false !== strpos($number, $thousand_separator)
284 ) {
285 // Fix point thousand separator value.
286 $number = str_replace('.', '', $number);
287 }
288
289 return give_sanitize_amount($number, $args);
290 }
291
292 /**
293 * Sanitize Amount
294 *
295 * Note: Do not this function to sanitize amount instead use give_maybe_sanitize_amount function.
296 *
297 * Returns a sanitized amount by stripping out thousands separators.
298 *
299 * @since 4.9.0 PHP 8 compatibility
300 * @since 1.0
301 *
302 * @param int|float|string $number Expects either a float or a string with a decimal separator only (no thousands)
303 * @param array|bool $args It accepts 'number_decimals', 'trim_zeros', 'currency'.
304 *
305 * @return string $amount Newly sanitized amount
306 */
307 function give_sanitize_amount($number, $args = [])
308 {
309 // Bailout.
310 if (empty($number) || ( ! is_numeric($number) && ! is_string($number))) {
311 return $number;
312 }
313
314 $args = wp_parse_args(
315 $args,
316 [
317 'number_decimals' => false,
318 'trim_zeros' => false,
319 'currency' => give_get_currency(),
320 ]
321 );
322
323 // Remove slash from amount.
324 // If thousand or decimal separator is set to ' then in $_POST or $_GET param we will get an escaped number.
325 // To prevent notices and warning remove slash from amount/number.
326 $number = wp_unslash($number);
327
328 $thousand_separator = give_get_price_thousand_separator($args['currency']);
329
330 $locale = localeconv();
331 $decimals = [
332 give_get_price_decimal_separator($args['currency']),
333 $locale['decimal_point'],
334 $locale['mon_decimal_point'],
335 ];
336
337 // Remove locale from string
338 if ( ! is_float($number)) {
339 $number = str_replace($decimals, '.', $number);
340 }
341
342 // Remove thousand amount formatting if amount has.
343 // This condition use to add backward compatibility to version before 1.6, because before version 1.6 we were saving formatted amount to db.
344 // Do not replace thousand separator from price if it is same as decimal separator, because it will be already replace by above code.
345 if ( ! in_array($thousand_separator, $decimals) && (false !== strpos($number, $thousand_separator))) {
346 $number = str_replace($thousand_separator, '', $number);
347 } elseif (in_array($thousand_separator, $decimals)) {
348 $number = preg_replace('/\.(?=.*\.)/', '', $number);
349 }
350
351 // Remove non numeric entity before decimal separator.
352 $number = preg_replace('/[^0-9\.]/', '', $number);
353 $default_dp = give_get_price_decimals($args['currency']);
354
355 // Reset negative amount to zero.
356 if (0 > $number) {
357 $number = number_format(0, $default_dp, '.');
358 }
359
360 // If number does not have decimal then add number of decimals to it.
361 if (
362 false === strpos($number, '.')
363 || ($default_dp > strlen(substr($number, strpos($number, '.') + 1)))
364 ) {
365 $number = number_format($number, $default_dp, '.', '');
366 }
367
368 // Format number by custom number of decimals.
369 if (false !== $args['number_decimals']) {
370 $dp = intval(is_bool($args['number_decimals']) ? $default_dp : $args['number_decimals']);
371 $dp = apply_filters('give_sanitize_amount_decimals', $dp, $number);
372 $number = number_format(floatval($number), $dp, '.', '');
373 }
374
375 // Trim zeros.
376 if ($args['trim_zeros'] && strstr($number, '.')) {
377 $number = rtrim(rtrim($number, '0'), '.');
378 }
379
380 /**
381 * Filter the sanitize amount
382 *
383 * @since 1.0
384 */
385 return apply_filters('give_sanitize_amount', $number);
386 }
387
388 /**
389 * Returns a nicely formatted amount.
390 *
391 * @since 1.0
392 *
393 * @param string $amount Price amount to format
394 * @param array $args Array of arguments.
395 *
396 * @return string $amount Newly formatted amount or Price Not Available
397 */
398 function give_format_amount($amount, $args = [])
399 {
400 // Backward compatibility.
401 if (is_bool($args)) {
402 $args = [
403 'decimal' => $args,
404 ];
405 }
406
407 $default_args = [
408 'decimal' => true,
409 'sanitize' => true,
410 'donation_id' => 0,
411 'currency' => '',
412 ];
413
414 $args = wp_parse_args($args, $default_args);
415
416 // Set Currency based on donation id, if required.
417 if ($args['donation_id'] && empty($args['currency'])) {
418 $args['currency'] = give_get_meta($args['donation_id'], '_give_payment_currency', true);
419 }
420
421 $formatted = 0;
422 $currency = ! empty($args['currency']) ? $args['currency'] : give_get_currency($args['donation_id']);
423 $thousands_sep = give_get_price_thousand_separator($currency);
424 $decimal_sep = give_get_price_decimal_separator($currency);
425 $decimals = ! empty($args['decimal']) ? give_get_price_decimals($currency) : 0;
426
427 if ( ! empty($amount)) {
428 // Sanitize amount before formatting.
429 $amount = ! empty($args['sanitize']) ?
430 give_maybe_sanitize_amount(
431 $amount,
432 [
433 'number_decimals' => $decimals,
434 'currency' => $currency,
435 ]
436 ) :
437 number_format($amount, $decimals, '.', '');
438
439 switch ($currency) {
440 case 'INR':
441 $decimal_amount = '';
442
443 // Extract decimals from amount
444 if (($pos = strpos($amount, '.')) !== false) {
445 if ( ! empty($decimals)) {
446 $decimal_amount = substr(round(substr($amount, $pos), $decimals), 1);
447 $amount = substr($amount, 0, $pos);
448
449 if ( ! $decimal_amount) {
450 $decimal_amount = substr("{$decimal_sep}0000000000", 0, ($decimals + 1));
451 } elseif (($decimals + 1) > strlen($decimal_amount)) {
452 $decimal_amount = substr("{$decimal_amount}000000000", 0, ($decimals + 1));
453 }
454 } else {
455 $amount = number_format($amount, $decimals, $decimal_sep, '');
456 }
457 }
458
459 // Extract last 3 from amount
460 $result = substr($amount, -3);
461 $amount = substr($amount, 0, -3);
462
463 // Apply digits 2 by 2
464 while (strlen($amount) > 0) {
465 $result = substr($amount, -2) . $thousands_sep . $result;
466 $amount = substr($amount, 0, -2);
467 }
468
469 $formatted = $result . $decimal_amount;
470 break;
471
472 default:
473 $formatted = number_format($amount, $decimals, $decimal_sep, $thousands_sep);
474 }
475 }
476
477 /**
478 * Filter the formatted amount
479 *
480 * @since 1.0
481 */
482 return apply_filters(
483 'give_format_amount',
484 $formatted,
485 $amount,
486 $decimals,
487 $decimal_sep,
488 $thousands_sep,
489 $currency,
490 $args
491 );
492 }
493
494
495 /**
496 * Get human readable amount.
497 *
498 * Note: This function only support large number formatting from million to trillion
499 *
500 * @since 1.6
501 *
502 * @use give_get_price_thousand_separator Get thousand separator.
503 *
504 * @param string $amount formatted amount number.
505 * @param array $args Array of arguments.
506 *
507 * @return string formatted amount number with large number names.
508 */
509 function give_human_format_large_amount($amount, $args = [])
510 {
511 // Set default currency;
512 if (empty($args['currency'])) {
513 $args['currency'] = give_get_currency();
514 }
515
516 // Get thousand separator.
517 $thousands_sep = give_get_price_thousand_separator($args['currency']);
518
519 // Sanitize amount for calculation purpose.
520 $sanitize_amount = give_maybe_sanitize_amount(
521 $amount,
522 [
523 'currency' => $args['currency'],
524 ]
525 );
526
527 // Bailout.
528 if ( ! floatval($sanitize_amount)) {
529 return '0';
530 };
531
532 // Explode amount to calculate name of large numbers.
533 $amount_array = explode($thousands_sep, $amount);
534
535 // Calculate amount parts count.
536 $amount_count_parts = count($amount_array);
537
538 // Human format amount (default).
539 $human_format_amount = $amount;
540
541 switch ($args['currency']) {
542 case 'INR':
543 // Calculate large number formatted amount.
544 if (4 < $amount_count_parts) {
545 $human_format_amount = sprintf(
546 esc_html__('%s arab', 'give'),
547 round(($sanitize_amount / 1000000000), 2)
548 );
549 } elseif (3 < $amount_count_parts) {
550 $human_format_amount = sprintf(esc_html__('%s crore', 'give'), round(($sanitize_amount / 10000000), 2));
551 } elseif (2 < $amount_count_parts) {
552 $human_format_amount = sprintf(esc_html__('%s lakh', 'give'), round(($sanitize_amount / 100000), 2));
553 }
554 break;
555 default:
556 // Calculate large number formatted amount.
557 if (4 < $amount_count_parts) {
558 $human_format_amount = sprintf(
559 esc_html__('%s trillion', 'give'),
560 round(($sanitize_amount / 1000000000000), 2)
561 );
562 } elseif (3 < $amount_count_parts) {
563 $human_format_amount = sprintf(
564 esc_html__('%s billion', 'give'),
565 round(($sanitize_amount / 1000000000), 2)
566 );
567 } elseif (2 < $amount_count_parts) {
568 $human_format_amount = sprintf(
569 esc_html__('%s million', 'give'),
570 round(($sanitize_amount / 1000000), 2)
571 );
572 }
573 }
574
575 return apply_filters('give_human_format_large_amount', $human_format_amount, $amount, $sanitize_amount);
576 }
577
578 /**
579 * Returns a nicely formatted amount with custom decimal separator.
580 *
581 * @since 4.9.0 PHP 8 compatibility
582 * @since 1.0
583 *
584 * @param array $args {
585 *
586 * @type int|float|string $amount Formatted or sanitized price. (optional if donation id set)
587 * @type int $donation_id donation amount (optional if set amount, but provide it for better result if formatting decimal amount of donation).
588 * @type string $currency donation amount (optional if set donation id). Provide either amount or donation id
589 * @type int|bool $dp number of decimals
590 * @type bool $sanitize Whether or not sanitize number
591 * }
592 *
593 * @return string $amount Newly formatted amount or Price Not Available
594 */
595 function give_format_decimal($args)
596 {
597 $args = wp_parse_args(
598 $args,
599 [
600 'amount' => 0,
601 'donation_id' => 0,
602 'currency' => '',
603 'dp' => false,
604 'sanitize' => false,
605 ]
606 );
607
608 if ( ! empty($args['donation_id'])) {
609 // Set currency if not already done.
610 if (empty($args['currency'])) {
611 $args['currency'] = give_get_payment_currency_code($args['donation_id']);
612 }
613
614 // Set amount if not already done.
615 if (empty($args['amount'])) {
616 $args['amount'] = give_donation_amount($args['donation_id']);
617 }
618 }
619
620 $decimal_separator = give_get_price_decimal_separator();
621 $formatted_amount = $args['sanitize'] ?
622 give_maybe_sanitize_amount(
623 $args['amount'],
624 [
625 'number_decimals' => $args['dp'],
626 'currency' => $args['currency'],
627 ]
628 ) :
629 number_format(
630 $args['amount'],
631 (is_bool($args['dp']) ? give_get_price_decimals($args['currency']) : $args['dp']),
632 '.',
633 ''
634 );
635
636 if (false !== strpos($formatted_amount, '.')) {
637 $formatted_amount = str_replace('.', $decimal_separator, $formatted_amount);
638 }
639
640 return apply_filters('give_format_decimal', $formatted_amount, $args['amount'], $decimal_separator, $args);
641 }
642
643 /**
644 * Get date format string on basis of given context.
645 *
646 * @since 1.7
647 *
648 * @param string $date_context Date format context name.
649 *
650 * @return string Date format string
651 */
652 function give_date_format($date_context = '')
653 {
654 /**
655 * Filter the date context
656 *
657 * You can add your own date context or use already exist context.
658 * For example:
659 * add_filter( 'give_date_format_contexts', 'add_new_date_contexts' );
660 * function add_new_date_contexts( $date_format_contexts ) {
661 * // You can add single context like this $date_format_contexts['checkout'] = 'F j, Y';
662 * // Instead add multiple date context at once.
663 * $new_date_format_contexts = array(
664 * 'checkout' => 'F j, Y',
665 * 'report' => 'Y-m-d',
666 * 'email' => 'm/d/Y',
667 * );
668 *
669 * // Merge date contexts array only if you are adding multiple date contexts at once otherwise return $date_format_contexts.
670 * return array_merge( $new_date_format_contexts, $date_format_contexts );
671 *
672 * }
673 */
674 $date_format_contexts = apply_filters('give_date_format_contexts', []);
675
676 // Set date format to default date format.
677 $date_format = get_option('date_format');
678
679 // Update date format if we have non empty date format context array and non empty date format string for that context.
680 if ($date_context && ! empty($date_format_contexts) && array_key_exists($date_context, $date_format_contexts)) {
681 $date_format = ! empty($date_format_contexts[$date_context])
682 ? $date_format_contexts[$date_context]
683 : $date_format;
684 }
685
686 return apply_filters('give_date_format', $date_format);
687 }
688
689 /**
690 * Get cache key.
691 *
692 * @since 1.7
693 *
694 * @param string $action Cache key prefix.
695 * @param array $query_args Query array.
696 *
697 * @return string
698 * @deprecated 1.8.7 You can access this function from Give_Cache.
699 *
700 */
701 function give_get_cache_key($action, $query_args)
702 {
703 return Give_Cache::get_key($action, $query_args);
704 }
705
706 /**
707 * Clean variables using sanitize_text_field. Arrays are cleaned recursively.
708 * Non-scalar values are ignored.
709 *
710 * @since 3.19.3 Don't unserialize data by default and return an empty string when data is serialized and $allow_serialized_data is false
711 * @since 3.17.2 Safe unserialize data by default
712 * @since 1.8
713 *
714 * @param string|array $var
715 *
716 * @return string|array
717 */
718 function give_clean($var, $allow_serialized_data = false)
719 {
720 if (is_array($var)) {
721 return array_map('give_clean', $var);
722 }
723
724 if ( Utils::isSerialized($var)) {
725 $var = $allow_serialized_data ? Utils::safeUnserialize($var) : '';
726 }
727
728 return is_scalar($var) ? sanitize_text_field(wp_unslash($var)) : $var;
729 }
730
731 /**
732 * Transforms php.ini notation for numbers (like '2M') to an integer.
733 *
734 * @since 1.8
735 *
736 * @param $size
737 *
738 * @return int
739 */
740 function give_let_to_num($size)
741 {
742 $l = substr($size, -1);
743 $ret = substr($size, 0, -1);
744 switch (strtoupper($l)) {
745 case 'P':
746 $ret *= 1024;
747 case 'T':
748 $ret *= 1024;
749 case 'G':
750 $ret *= 1024;
751 case 'M':
752 $ret *= 1024;
753 case 'K':
754 $ret *= 1024;
755 }
756
757 return $ret;
758 }
759
760 /**
761 * Verify nonce.
762 *
763 * @since 1.8
764 *
765 * @param string $nonce Nonce Hash.
766 * @param int $action Nonce verification action.
767 * @param array $wp_die_args Nonce fail arguments.
768 *
769 * @return bool
770 */
771 function give_validate_nonce($nonce, $action = -1, $wp_die_args = [])
772 {
773 // Verify nonce.
774 $verify_nonce = wp_verify_nonce($nonce, $action);
775
776 // On ajax request send nonce verification status.
777 if (wp_doing_ajax()) {
778 return $verify_nonce;
779 }
780
781 if ( ! $verify_nonce) {
782 $wp_die_args = wp_parse_args(
783 $wp_die_args,
784 [
785 'message' => __(
786 'We\'re unable to recognize your session. Please refresh the screen to try again; otherwise contact your website administrator for assistance.',
787 'give'
788 ),
789 'title' => __('Error', 'give'),
790 'args' => [
791 'response' => 403,
792 ],
793 ]
794 );
795
796 wp_die(
797 $wp_die_args['message'],
798 $wp_die_args['title'],
799 $wp_die_args['args']
800 );
801 }
802
803 return true;
804 }
805
806 /**
807 * Verify nonce while processing donation form.
808 *
809 * @since 2.0
810 *
811 * @param string $nonce Nonce value.
812 * @param int $form_id Donation Form ID.
813 *
814 * @return bool
815 */
816 function give_verify_donation_form_nonce($nonce, $form_id)
817 {
818 // Form nonce action.
819 $nonce_action = "give_donation_form_nonce_{$form_id}";
820
821 // Nonce validation.
822 $verify_nonce = give_validate_nonce($nonce, $nonce_action);
823
824 if ( ! $verify_nonce) {
825 give_set_error(
826 'donation_form_nonce',
827 __(
828 'We\'re unable to recognize your session. Please refresh the screen to try again; otherwise contact your website administrator for assistance.',
829 'give'
830 )
831 );
832 }
833
834 return $verify_nonce;
835 }
836
837 /**
838 * Check variable and get default or valid value.
839 *
840 * Helper function to check if a variable is set, empty, etc.
841 *
842 * @since 1.8
843 *
844 * @param $variable
845 * @param string (optional) $conditional default value: isset
846 * @param mixed (optional) $default default value: false
847 * @param string (optional) $array_key_name default value: false
848 *
849 * @return mixed
850 */
851 function give_check_variable($variable, $conditional = '', $default = false, $array_key_name = '')
852 {
853 // Get value from array if array key non empty.
854 if (empty($array_key_name)) {
855 switch ($conditional) {
856 case 'isset_empty':
857 $variable = (isset($variable) && ! empty($variable)) ? $variable : $default;
858 break;
859
860 case 'empty':
861 $variable = ! empty($variable) ? $variable : $default;
862 break;
863
864 case 'null':
865 $variable = ! is_null($variable) ? $variable : $default;
866 break;
867
868 default:
869 $variable = isset($variable) ? $variable : $default;
870 }
871 } else {
872 $isset = is_array($variable) && array_key_exists($array_key_name, $variable);
873
874 switch ($conditional) {
875 case 'isset_empty':
876 $variable = ($isset && ! empty($variable[$array_key_name])) ? $variable[$array_key_name] : $default;
877 break;
878
879 case 'empty':
880 $variable = ! empty($variable[$array_key_name]) ? $variable[$array_key_name] : $default;
881 break;
882
883 case 'null':
884 $variable = $isset && ! is_null($variable[$array_key_name]) ? $variable[$array_key_name] : $default;
885 break;
886
887 default:
888 $variable = $isset && isset($variable[$array_key_name]) ? $variable[$array_key_name] : $default;
889 }
890 }
891
892 return $variable;
893 }
894