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