PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.19.0
GiveWP – Donation Plugin and Fundraising Platform v3.19.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 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 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 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
921 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.17.2 Safe unserialize data by default
739 * @since 1.8
740 *
741 * @param string|array $var
742 *
743 * @return string|array
744 */
745 function give_clean($var, $allow_serialized_data = false)
746 {
747 if (is_array($var)) {
748 return array_map('give_clean', $var);
749 }
750
751 if ( ! $allow_serialized_data) {
752 $var = Utils::safeUnserialize($var);
753 }
754
755 return is_scalar($var) ? sanitize_text_field(wp_unslash($var)) : $var;
756 }
757
758 /**
759 * Transforms php.ini notation for numbers (like '2M') to an integer.
760 *
761 * @since 1.8
762 *
763 * @param $size
764 *
765 * @return int
766 */
767 function give_let_to_num($size)
768 {
769 $l = substr($size, -1);
770 $ret = substr($size, 0, -1);
771 switch (strtoupper($l)) {
772 case 'P':
773 $ret *= 1024;
774 case 'T':
775 $ret *= 1024;
776 case 'G':
777 $ret *= 1024;
778 case 'M':
779 $ret *= 1024;
780 case 'K':
781 $ret *= 1024;
782 }
783
784 return $ret;
785 }
786
787 /**
788 * Verify nonce.
789 *
790 * @since 1.8
791 *
792 * @param string $nonce Nonce Hash.
793 * @param int $action Nonce verification action.
794 * @param array $wp_die_args Nonce fail arguments.
795 *
796 * @return bool
797 */
798 function give_validate_nonce($nonce, $action = -1, $wp_die_args = [])
799 {
800 // Verify nonce.
801 $verify_nonce = wp_verify_nonce($nonce, $action);
802
803 // On ajax request send nonce verification status.
804 if (wp_doing_ajax()) {
805 return $verify_nonce;
806 }
807
808 if ( ! $verify_nonce) {
809 $wp_die_args = wp_parse_args(
810 $wp_die_args,
811 [
812 'message' => __(
813 'We\'re unable to recognize your session. Please refresh the screen to try again; otherwise contact your website administrator for assistance.',
814 'give'
815 ),
816 'title' => __('Error', 'give'),
817 'args' => [
818 'response' => 403,
819 ],
820 ]
821 );
822
823 wp_die(
824 $wp_die_args['message'],
825 $wp_die_args['title'],
826 $wp_die_args['args']
827 );
828 }
829
830 return true;
831 }
832
833 /**
834 * Verify nonce while processing donation form.
835 *
836 * @since 2.0
837 *
838 * @param string $nonce Nonce value.
839 * @param int $form_id Donation Form ID.
840 *
841 * @return bool
842 */
843 function give_verify_donation_form_nonce($nonce, $form_id)
844 {
845 // Form nonce action.
846 $nonce_action = "give_donation_form_nonce_{$form_id}";
847
848 // Nonce validation.
849 $verify_nonce = give_validate_nonce($nonce, $nonce_action);
850
851 if ( ! $verify_nonce) {
852 give_set_error(
853 'donation_form_nonce',
854 __(
855 'We\'re unable to recognize your session. Please refresh the screen to try again; otherwise contact your website administrator for assistance.',
856 'give'
857 )
858 );
859 }
860
861 return $verify_nonce;
862 }
863
864 /**
865 * Check variable and get default or valid value.
866 *
867 * Helper function to check if a variable is set, empty, etc.
868 *
869 * @since 1.8
870 *
871 * @param $variable
872 * @param string (optional) $conditional default value: isset
873 * @param mixed (optional) $default default value: false
874 * @param string (optional) $array_key_name default value: false
875 *
876 * @return mixed
877 */
878 function give_check_variable($variable, $conditional = '', $default = false, $array_key_name = '')
879 {
880 // Get value from array if array key non empty.
881 if (empty($array_key_name)) {
882 switch ($conditional) {
883 case 'isset_empty':
884 $variable = (isset($variable) && ! empty($variable)) ? $variable : $default;
885 break;
886
887 case 'empty':
888 $variable = ! empty($variable) ? $variable : $default;
889 break;
890
891 case 'null':
892 $variable = ! is_null($variable) ? $variable : $default;
893 break;
894
895 default:
896 $variable = isset($variable) ? $variable : $default;
897 }
898 } else {
899 $isset = is_array($variable) && array_key_exists($array_key_name, $variable);
900
901 switch ($conditional) {
902 case 'isset_empty':
903 $variable = ($isset && ! empty($variable[$array_key_name])) ? $variable[$array_key_name] : $default;
904 break;
905
906 case 'empty':
907 $variable = ! empty($variable[$array_key_name]) ? $variable[$array_key_name] : $default;
908 break;
909
910 case 'null':
911 $variable = $isset && ! is_null($variable[$array_key_name]) ? $variable[$array_key_name] : $default;
912 break;
913
914 default:
915 $variable = $isset && isset($variable[$array_key_name]) ? $variable[$array_key_name] : $default;
916 }
917 }
918
919 return $variable;
920 }
921