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