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