Test Failed
Push — issues/1944 ( ef3669...b2a977 )
by Ravinder
05:02
created

functions.php ➔ give_donation_amount()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 2
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Payment Functions
4
 *
5
 * @package     Give
6
 * @subpackage  Payments
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Get Payments
19
 *
20
 * Retrieve payments from the database.
21
 *
22
 * Since 1.0, this function takes an array of arguments, instead of individual
23
 * parameters. All of the original parameters remain, but can be passed in any
24
 * order via the array.
25
 *
26
 * @since 1.0
27
 *
28
 * @param array $args     {
29
 *                        Optional. Array of arguments passed to payments query.
30
 *
31
 * @type int    $offset   The number of payments to offset before retrieval.
32
 *                            Default is 0.
33
 * @type int    $number   The number of payments to query for. Use -1 to request all
34
 *                            payments. Default is 20.
35
 * @type string $mode     Default is 'live'.
36
 * @type string $order    Designates ascending or descending order of payments.
37
 *                            Accepts 'ASC', 'DESC'. Default is 'DESC'.
38
 * @type string $orderby  Sort retrieved payments by parameter. Default is 'ID'.
39
 * @type string $status   The status of the payments. Default is 'any'.
40
 * @type string $user     User. Default is null.
41
 * @type string $meta_key Custom field key. Default is null.
42
 *
43
 * }
44
 *
45
 * @return array $payments Payments retrieved from the database
46
 */
47
function give_get_payments( $args = array() ) {
48
49
	// Fallback to post objects to ensure backwards compatibility.
50
	if ( ! isset( $args['output'] ) ) {
51
		$args['output'] = 'posts';
52
	}
53
54
	$args     = apply_filters( 'give_get_payments_args', $args );
55
	$payments = new Give_Payments_Query( $args );
56
57
	return $payments->get_payments();
58
}
59
60
/**
61
 * Retrieve payment by a given field
62
 *
63
 * @since  1.0
64
 *
65
 * @param  string $field The field to retrieve the payment with.
66
 * @param  mixed  $value The value for $field.
67
 *
68
 * @return mixed
69
 */
70
function give_get_payment_by( $field = '', $value = '' ) {
71
72
	if ( empty( $field ) || empty( $value ) ) {
73
		return false;
74
	}
75
76
	switch ( strtolower( $field ) ) {
77
78
		case 'id':
79
			$payment = new Give_Payment( $value );
80
			$id      = $payment->ID;
81
82
			if ( empty( $id ) ) {
83
				return false;
84
			}
85
86
			break;
87
88 View Code Duplication
		case 'key':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
			$payment = give_get_payments( array(
90
				'meta_key'       => '_give_payment_purchase_key',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
91
				'meta_value'     => $value,
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
92
				'posts_per_page' => 1,
93
				'fields'         => 'ids',
94
			) );
95
96
			if ( $payment ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
97
				$payment = new Give_Payment( $payment[0] );
98
			}
99
100
			break;
101
102 View Code Duplication
		case 'payment_number':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
			$payment = give_get_payments( array(
104
				'meta_key'       => '_give_payment_number',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
105
				'meta_value'     => $value,
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
106
				'posts_per_page' => 1,
107
				'fields'         => 'ids',
108
			) );
109
110
			if ( $payment ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
111
				$payment = new Give_Payment( $payment[0] );
112
			}
113
114
			break;
115
116
		default:
117
			return false;
118
	}// End switch().
119
120
	if ( $payment ) {
121
		return $payment;
122
	}
123
124
	return false;
125
}
126
127
/**
128
 * Insert Payment
129
 *
130
 * @since  1.0
131
 *
132
 * @param  array $payment_data Arguments passed.
133
 *
134
 * @return int|bool Payment ID if payment is inserted, false otherwise.
135
 */
136
function give_insert_payment( $payment_data = array() ) {
137
138
	if ( empty( $payment_data ) ) {
139
		return false;
140
	}
141
142
	/**
143
	 * Fire the filter on donation data before insert.
144
	 *
145
	 * @since 1.8.15
146
	 *
147
	 * @param array $payment_data Arguments passed.
148
	 */
149
	$payment_data = apply_filters( 'give_pre_insert_payment', $payment_data );
150
151
	$payment    = new Give_Payment();
152
	$gateway    = ! empty( $payment_data['gateway'] ) ? $payment_data['gateway'] : '';
153
	$gateway    = empty( $gateway ) && isset( $_POST['give-gateway'] ) ? $_POST['give-gateway'] : $gateway;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
154
	$form_id    = isset( $payment_data['give_form_id'] ) ? $payment_data['give_form_id'] : 0;
155
	$price_id   = give_get_payment_meta_price_id( $payment_data );
156
	$form_title = isset( $payment_data['give_form_title'] ) ? $payment_data['give_form_title'] : get_the_title( $form_id );
157
158
	// Set properties.
159
	$payment->total          = $payment_data['price'];
160
	$payment->status         = ! empty( $payment_data['status'] ) ? $payment_data['status'] : 'pending';
161
	$payment->currency       = ! empty( $payment_data['currency'] ) ? $payment_data['currency'] : give_get_currency( $payment_data['give_form_id'], $payment_data );
162
	$payment->user_info      = $payment_data['user_info'];
163
	$payment->gateway        = $gateway;
164
	$payment->form_title     = $form_title;
165
	$payment->form_id        = $form_id;
166
	$payment->price_id       = $price_id;
167
	$payment->donor_id       = ( ! empty( $payment_data['donor_id'] ) ? $payment_data['donor_id'] : '' );
168
	$payment->user_id        = $payment_data['user_info']['id'];
169
	$payment->email          = $payment_data['user_email'];
170
	$payment->first_name     = $payment_data['user_info']['first_name'];
171
	$payment->last_name      = $payment_data['user_info']['last_name'];
172
	$payment->email          = $payment_data['user_info']['email'];
173
	$payment->ip             = give_get_ip();
174
	$payment->key            = $payment_data['purchase_key'];
175
	$payment->mode           = ( ! empty( $payment_data['mode'] ) ? (string) $payment_data['mode'] : ( give_is_test_mode() ? 'test' : 'live' ) );
176
	$payment->parent_payment = ! empty( $payment_data['parent'] ) ? absint( $payment_data['parent'] ) : '';
177
178
	// Add the donation.
179
	$args = array(
180
		'price'    => $payment->total,
181
		'price_id' => $payment->price_id,
182
	);
183
184
	$payment->add_donation( $payment->form_id, $args );
185
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
186
187
	// Set date if present.
188
	if ( isset( $payment_data['post_date'] ) ) {
189
		$payment->date = $payment_data['post_date'];
190
	}
191
192
	// Handle sequential payments.
193
	if ( give_get_option( 'enable_sequential' ) ) {
194
		$number          = give_get_next_payment_number();
195
		$payment->number = give_format_payment_number( $number );
196
		update_option( 'give_last_payment_number', $number );
197
	}
198
199
	// Save payment.
200
	$payment->save();
201
202
	/**
203
	 * Fires while inserting payments.
204
	 *
205
	 * @since 1.0
206
	 *
207
	 * @param int   $payment_id   The payment ID.
208
	 * @param array $payment_data Arguments passed.
209
	 */
210
	do_action( 'give_insert_payment', $payment->ID, $payment_data );
211
212
	// Return payment ID upon success.
213
	if ( ! empty( $payment->ID ) ) {
214
		return $payment->ID;
215
	}
216
217
	// Return false if no payment was inserted.
218
	return false;
219
220
}
221
222
/**
223
 * Create payment.
224
 *
225
 * @param $payment_data
226
 *
227
 * @return bool|int
228
 */
229
function give_create_payment( $payment_data ) {
230
231
	$form_id  = intval( $payment_data['post_data']['give-form-id'] );
232
	$price_id = isset( $payment_data['post_data']['give-price-id'] ) ? $payment_data['post_data']['give-price-id'] : '';
233
234
	// Collect payment data.
235
	$insert_payment_data = array(
236
		'price'           => $payment_data['price'],
237
		'give_form_title' => $payment_data['post_data']['give-form-title'],
238
		'give_form_id'    => $form_id,
239
		'give_price_id'   => $price_id,
240
		'date'            => $payment_data['date'],
241
		'user_email'      => $payment_data['user_email'],
242
		'purchase_key'    => $payment_data['purchase_key'],
243
		'currency'        => give_get_currency( $form_id, $payment_data ),
244
		'user_info'       => $payment_data['user_info'],
245
		'status'          => 'pending',
246
		'gateway'         => 'paypal',
247
	);
248
249
	/**
250
	 * Filter the payment params.
251
	 *
252
	 * @since 1.8
253
	 *
254
	 * @param array $insert_payment_data
255
	 */
256
	$insert_payment_data = apply_filters( 'give_create_payment', $insert_payment_data );
257
258
	// Record the pending payment.
259
	return give_insert_payment( $insert_payment_data );
260
}
261
262
/**
263
 * Updates a payment status.
264
 *
265
 * @param  int    $payment_id Payment ID.
266
 * @param  string $new_status New Payment Status. Default is 'publish'.
267
 *
268
 * @since  1.0
269
 *
270
 * @return bool
271
 */
272
function give_update_payment_status( $payment_id, $new_status = 'publish' ) {
273
274
	$updated = false;
275
	$payment = new Give_Payment( $payment_id );
276
277
	if ( $payment && $payment->ID > 0 ) {
278
279
		$payment->status = $new_status;
280
		$updated         = $payment->save();
281
282
	}
283
284
	return $updated;
285
}
286
287
288
/**
289
 * Deletes a Donation
290
 *
291
 * @since  1.0
292
 *
293
 * @param  int $payment_id Payment ID (default: 0).
294
 * @param  bool $update_donor If we should update the donor stats (default:true).
295
 *
296
 * @return void
297
 */
298
function give_delete_donation( $payment_id = 0, $update_donor = true ) {
299
	$payment     = new Give_Payment( $payment_id );
300
	$amount      = give_get_payment_amount( $payment_id );
301
	$status      = $payment->post_status;
302
303
	$donor_id = give_get_payment_donor_id( $payment_id );
304
	$donor    = new Give_Donor( $donor_id );
0 ignored issues
show
Documentation introduced by
$donor_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
305
306
	// Only undo donations that aren't these statuses.
307
	$dont_undo_statuses = apply_filters( 'give_undo_donation_statuses', array(
308
		'pending',
309
		'cancelled',
310
	) );
311
312
	if ( ! in_array( $status, $dont_undo_statuses ) ) {
313
		give_undo_donation( $payment_id );
314
	}
315
316
	if ( $status == 'publish' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
317
318
		// Only decrease earnings if they haven't already been decreased (or were never increased for this payment).
319
		give_decrease_total_earnings( $amount );
320
321
		// @todo: Refresh only range related stat cache
322
		give_delete_donation_stats();
323
324
		if ( $donor->id && $update_donor ) {
325
326
			// Decrement the stats for the donor.
327
			$donor->decrease_donation_count();
328
			$donor->decrease_value( $amount );
329
330
		}
331
	}
332
333
	/**
334
	 * Fires before deleting payment.
335
	 *
336
	 * @param int $payment_id Payment ID.
337
	 *
338
	 * @since 1.0
339
	 */
340
	do_action( 'give_payment_delete', $payment_id );
341
342
	if ( $donor->id && $update_donor ) {
343
344
		// Remove the payment ID from the donor.
345
		$donor->remove_payment( $payment_id );
346
347
	}
348
349
	// Remove the payment.
350
	wp_delete_post( $payment_id, true );
351
352
	// Remove related sale log entries.
353
	Give()->logs->delete_logs( $payment_id );
354
355
	/**
356
	 * Fires after payment deleted.
357
	 *
358
	 * @param int $payment_id Payment ID.
359
	 *
360
	 * @since 1.0
361
	 */
362
	do_action( 'give_payment_deleted', $payment_id );
363
}
364
365
/**
366
 * Undo Donation
367
 *
368
 * Undoes a donation, including the decrease of donations and earning stats.
369
 * Used for when refunding or deleting a donation.
370
 *
371
 * @param  int $payment_id Payment ID.
372
 *
373
 * @since  1.0
374
 *
375
 * @return void
376
 */
377
function give_undo_donation( $payment_id ) {
378
379
	$payment = new Give_Payment( $payment_id );
380
381
	$maybe_decrease_earnings = apply_filters( 'give_decrease_earnings_on_undo', true, $payment, $payment->form_id );
382
	if ( true === $maybe_decrease_earnings ) {
383
		// Decrease earnings.
384
		give_decrease_earnings( $payment->form_id, $payment->total );
385
	}
386
387
	$maybe_decrease_donations = apply_filters( 'give_decrease_donations_on_undo', true, $payment, $payment->form_id );
388
	if ( true === $maybe_decrease_donations ) {
389
		// Decrease donation count.
390
		give_decrease_donation_count( $payment->form_id );
391
	}
392
393
}
394
395
396
/**
397
 * Count Payments
398
 *
399
 * Returns the total number of payments recorded.
400
 *
401
 * @param  array $args Arguments passed.
402
 *
403
 * @since  1.0
404
 *
405
 * @return object $stats Contains the number of payments per payment status.
406
 */
407
function give_count_payments( $args = array() ) {
408
409
	global $wpdb;
410
	$meta_table      = __give_v20_bc_table_details( 'payment' );
411
	$donor_meta_type = Give()->donor_meta->meta_type;
412
413
	$defaults = array(
414
		'user'       => null,
415
		's'          => null,
416
		'start-date' => null,
417
		'end-date'   => null,
418
		'form_id'    => null,
419
	);
420
421
	$args = wp_parse_args( $args, $defaults );
422
423
	$select = 'SELECT p.post_status,count( * ) AS num_posts';
424
	$join   = '';
425
	$where  = "WHERE p.post_type = 'give_payment' AND p.post_status IN ('" . implode( "','", give_get_payment_status_keys() ) . "')";
426
427
	// Count payments for a specific user.
428
	if ( ! empty( $args['user'] ) ) {
429
430
		if ( is_email( $args['user'] ) ) {
431
			$field = 'email';
432
		} elseif ( is_numeric( $args['user'] ) ) {
433
			$field = 'id';
434
		} else {
435
			$field = '';
436
		}
437
438
		$join = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
439
440
		if ( ! empty( $field ) ) {
441
			$where .= "
442
				AND m.meta_key = '_give_payment_user_{$field}'
443
				AND m.meta_value = '{$args['user']}'";
444
		}
445
	} elseif ( ! empty( $args['donor'] ) ) {
446
447
		$join  = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
448
		$where .= "
449
			AND m.meta_key = '_give_payment_{$donor_meta_type}_id'
450
			AND m.meta_value = '{$args['donor']}'";
451
452
		// Count payments for a search.
453
	} elseif ( ! empty( $args['s'] ) ) {
454
455
		if ( is_email( $args['s'] ) || strlen( $args['s'] ) == 32 ) {
456
457
			if ( is_email( $args['s'] ) ) {
458
				$field = '_give_payment_donor_email';
459
			} else {
460
				$field = '_give_payment_purchase_key';
461
			}
462
463
			$join  = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
464
			$where .= $wpdb->prepare( '
465
                AND m.meta_key = %s
466
                AND m.meta_value = %s', $field, $args['s'] );
467
468
		} elseif ( '#' == substr( $args['s'], 0, 1 ) ) {
469
470
			$search = str_replace( '#:', '', $args['s'] );
471
			$search = str_replace( '#', '', $search );
472
473
			$select = 'SELECT p.post_status,count( * ) AS num_posts ';
474
			$join   = '';
475
			$where  = $wpdb->prepare( 'WHERE p.post_type=%s  AND p.ID = %d ', 'give_payment', $search );
476
477
		} elseif ( is_numeric( $args['s'] ) ) {
478
479
			$join  = "LEFT JOIN {$meta_table['column']} m ON (p.ID = m.{$meta_table['column']})";
480
			$where .= $wpdb->prepare( "
481
				AND m.meta_key = '_give_payment_donor_id'
482
				AND m.meta_value = %d", $args['s'] );
483
484
		} else {
485
			$search = $wpdb->esc_like( $args['s'] );
486
			$search = '%' . $search . '%';
487
488
			$where .= $wpdb->prepare( 'AND ((p.post_title LIKE %s) OR (p.post_content LIKE %s))', $search, $search );
489
		}// End if().
490
	}// End if().
491
492
	if ( ! empty( $args['form_id'] ) && is_numeric( $args['form_id'] ) ) {
493
494
		$join  = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
495
		$where .= $wpdb->prepare( '
496
                AND m.meta_key = %s
497
                AND m.meta_value = %s', '_give_payment_form_id', $args['form_id'] );
498
	}
499
500
	// Limit payments count by date.
501
	if ( ! empty( $args['start-date'] ) && false !== strpos( $args['start-date'], '/' ) ) {
502
503
		$date_parts = explode( '/', $args['start-date'] );
504
		$month      = ! empty( $date_parts[0] ) && is_numeric( $date_parts[0] ) ? $date_parts[0] : 0;
505
		$day        = ! empty( $date_parts[1] ) && is_numeric( $date_parts[1] ) ? $date_parts[1] : 0;
506
		$year       = ! empty( $date_parts[2] ) && is_numeric( $date_parts[2] ) ? $date_parts[2] : 0;
507
508
		$is_date = checkdate( $month, $day, $year );
509 View Code Duplication
		if ( false !== $is_date ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
510
511
			$date  = new DateTime( $args['start-date'] );
512
			$where .= $wpdb->prepare( " AND p.post_date >= '%s'", $date->format( 'Y-m-d' ) );
513
514
		}
515
516
		// Fixes an issue with the payments list table counts when no end date is specified (with stats class).
517
		if ( empty( $args['end-date'] ) ) {
518
			$args['end-date'] = $args['start-date'];
519
		}
520
	}
521
522
	if ( ! empty( $args['end-date'] ) && false !== strpos( $args['end-date'], '/' ) ) {
523
524
		$date_parts = explode( '/', $args['end-date'] );
525
526
		$month = ! empty( $date_parts[0] ) ? $date_parts[0] : 0;
527
		$day   = ! empty( $date_parts[1] ) ? $date_parts[1] : 0;
528
		$year  = ! empty( $date_parts[2] ) ? $date_parts[2] : 0;
529
530
		$is_date = checkdate( $month, $day, $year );
531 View Code Duplication
		if ( false !== $is_date ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
532
533
			$date  = new DateTime( $args['end-date'] );
534
			$where .= $wpdb->prepare( " AND p.post_date <= '%s'", $date->format( 'Y-m-d' ) );
535
536
		}
537
	}
538
539
	$where = apply_filters( 'give_count_payments_where', $where );
540
	$join  = apply_filters( 'give_count_payments_join', $join );
541
542
	$query = "$select
543
		FROM $wpdb->posts p
544
		$join
545
		$where
546
		GROUP BY p.post_status
547
	";
548
549
	$cache_key = md5( $query );
550
551
	$count = wp_cache_get( $cache_key, 'counts' );
552
	if ( false !== $count ) {
553
		return $count;
554
	}
555
556
	$count = $wpdb->get_results( $query, ARRAY_A );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
557
558
	$stats    = array();
559
	$statuses = get_post_stati();
560
	if ( isset( $statuses['private'] ) && empty( $args['s'] ) ) {
561
		unset( $statuses['private'] );
562
	}
563
564
	foreach ( $statuses as $state ) {
565
		$stats[ $state ] = 0;
566
	}
567
568
	foreach ( (array) $count as $row ) {
569
570
		if ( 'private' == $row['post_status'] && empty( $args['s'] ) ) {
571
			continue;
572
		}
573
574
		$stats[ $row['post_status'] ] = $row['num_posts'];
575
	}
576
577
	$stats = (object) $stats;
578
	wp_cache_set( $cache_key, $stats, 'counts' );
579
580
	return $stats;
581
}
582
583
584
/**
585
 * Check For Existing Payment
586
 *
587
 * @param  int $payment_id Payment ID.
588
 *
589
 * @since  1.0
590
 *
591
 * @return bool $exists True if payment exists, false otherwise.
592
 */
593
function give_check_for_existing_payment( $payment_id ) {
594
	$exists  = false;
595
	$payment = new Give_Payment( $payment_id );
596
597
	if ( $payment_id === $payment->ID && 'publish' === $payment->status ) {
598
		$exists = true;
599
	}
600
601
	return $exists;
602
}
603
604
/**
605
 * Get Payment Status
606
 *
607
 * @param WP_Post|Give_Payment|int $payment      Payment object or payment ID.
608
 * @param bool                     $return_label Whether to return the translated status label instead of status value. Default false.
609
 *
610
 * @since 1.0
611
 *
612
 * @return bool|mixed True if payment status exists, false otherwise.
613
 */
614
function give_get_payment_status( $payment, $return_label = false ) {
615
616
	if ( is_numeric( $payment ) ) {
617
618
		$payment = new Give_Payment( $payment );
619
620
		if ( ! $payment->ID > 0 ) {
621
			return false;
622
		}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
623
624
	}
625
626
	if ( ! is_object( $payment ) || ! isset( $payment->post_status ) ) {
627
		return false;
628
	}
629
630
	$statuses = give_get_payment_statuses();
631
632
	if ( ! is_array( $statuses ) || empty( $statuses ) ) {
633
		return false;
634
	}
635
636
	// Get payment object if not already given.
637
	$payment = $payment instanceof Give_Payment ? $payment : new Give_Payment( $payment->ID );
638
639
	if ( array_key_exists( $payment->status, $statuses ) ) {
640
		if ( true === $return_label ) {
641
			// Return translated status label.
642
			return $statuses[ $payment->status ];
643
		} else {
644
			// Account that our 'publish' status is labeled 'Complete'
645
			$post_status = 'publish' === $payment->status ? 'Complete' : $payment->post_status;
646
647
			// Make sure we're matching cases, since they matter
648
			return array_search( strtolower( $post_status ), array_map( 'strtolower', $statuses ) );
649
		}
650
	}
651
652
	return false;
653
}
654
655
/**
656
 * Retrieves all available statuses for payments.
657
 *
658
 * @since  1.0
659
 *
660
 * @return array $payment_status All the available payment statuses.
661
 */
662
function give_get_payment_statuses() {
663
	$payment_statuses = array(
664
		'pending'     => __( 'Pending', 'give' ),
665
		'publish'     => __( 'Complete', 'give' ),
666
		'refunded'    => __( 'Refunded', 'give' ),
667
		'failed'      => __( 'Failed', 'give' ),
668
		'cancelled'   => __( 'Cancelled', 'give' ),
669
		'abandoned'   => __( 'Abandoned', 'give' ),
670
		'preapproval' => __( 'Pre-Approved', 'give' ),
671
		'processing'  => __( 'Processing', 'give' ),
672
		'revoked'     => __( 'Revoked', 'give' ),
673
	);
674
675
	return apply_filters( 'give_payment_statuses', $payment_statuses );
676
}
677
678
/**
679
 * Get Payment Status Keys
680
 *
681
 * Retrieves keys for all available statuses for payments
682
 *
683
 * @since 1.0
684
 *
685
 * @return array $payment_status All the available payment statuses.
686
 */
687
function give_get_payment_status_keys() {
688
	$statuses = array_keys( give_get_payment_statuses() );
689
	asort( $statuses );
690
691
	return array_values( $statuses );
692
}
693
694
/**
695
 * Get Earnings By Date
696
 *
697
 * @param int $day       Day number. Default is null.
698
 * @param int $month_num Month number. Default is null.
699
 * @param int $year      Year number. Default is null.
700
 * @param int $hour      Hour number. Default is null.
701
 *
702
 * @since 1.0
703
 *
704
 * @return int $earnings Earnings
705
 */
706
function give_get_earnings_by_date( $day = null, $month_num, $year = null, $hour = null ) {
707
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_earnings() method instead.
708
709
	global $wpdb;
710
	$meta_table = __give_v20_bc_table_details( 'payment' );
711
712
	$args = array(
713
		'post_type'              => 'give_payment',
714
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
715
		'year'                   => $year,
716
		'monthnum'               => $month_num,
717
		'post_status'            => array( 'publish' ),
718
		'fields'                 => 'ids',
719
		'update_post_term_cache' => false,
720
	);
721
	if ( ! empty( $day ) ) {
722
		$args['day'] = $day;
723
	}
724
725
	if ( isset( $hour ) ) {
726
		$args['hour'] = $hour;
727
	}
728
729
	$args = apply_filters( 'give_get_earnings_by_date_args', $args );
730
	$key  = Give_Cache::get_key( 'give_stats', $args );
731
732 View Code Duplication
	if ( ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'give-refresh-reports' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
733
		$earnings = false;
734
	} else {
735
		$earnings = Give_Cache::get( $key );
736
	}
737
738
	if ( false === $earnings ) {
739
		$donations = get_posts( $args );
740
		$earnings  = 0;
741 View Code Duplication
		if ( $donations ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
742
			$donations = implode( ',', $donations );
743
744
			$earnings = $wpdb->get_var( "SELECT SUM(meta_value) FROM {$meta_table['name']} WHERE meta_key = '_give_payment_total' AND {$meta_table['column']['id']} IN ({$donations})" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
745
746
		}
747
		// Cache the results for one hour.
748
		Give_Cache::set( $key, $earnings, HOUR_IN_SECONDS );
749
	}
750
751
	return round( $earnings, 2 );
752
}
753
754
/**
755
 * Get Donations (sales) By Date
756
 *
757
 * @param int $day       Day number. Default is null.
758
 * @param int $month_num Month number. Default is null.
759
 * @param int $year      Year number. Default is null.
760
 * @param int $hour      Hour number. Default is null.
761
 *
762
 * @since 1.0
763
 *
764
 * @return int $count Sales
765
 */
766
function give_get_sales_by_date( $day = null, $month_num = null, $year = null, $hour = null ) {
767
768
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_sales() method instead.
769
	$args = array(
770
		'post_type'              => 'give_payment',
771
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
772
		'year'                   => $year,
773
		'fields'                 => 'ids',
774
		'post_status'            => array( 'publish' ),
775
		'update_post_meta_cache' => false,
776
		'update_post_term_cache' => false,
777
	);
778
779
	$show_free = apply_filters( 'give_sales_by_date_show_free', true, $args );
780
781
	if ( false === $show_free ) {
782
		$args['meta_query'] = array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
783
			array(
784
				'key'     => '_give_payment_total',
785
				'value'   => 0,
786
				'compare' => '>',
787
				'type'    => 'NUMERIC',
788
			),
789
		);
790
	}
791
792
	if ( ! empty( $month_num ) ) {
793
		$args['monthnum'] = $month_num;
794
	}
795
796
	if ( ! empty( $day ) ) {
797
		$args['day'] = $day;
798
	}
799
800
	if ( isset( $hour ) ) {
801
		$args['hour'] = $hour;
802
	}
803
804
	$args = apply_filters( 'give_get_sales_by_date_args', $args );
805
806
	$key = Give_Cache::get_key( 'give_stats', $args );
807
808 View Code Duplication
	if ( ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'give-refresh-reports' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
809
		$count = false;
810
	} else {
811
		$count = Give_Cache::get( $key );
812
	}
813
814
	if ( false === $count ) {
815
		$donations = new WP_Query( $args );
816
		$count     = (int) $donations->post_count;
817
		// Cache the results for one hour.
818
		Give_Cache::set( $key, $count, HOUR_IN_SECONDS );
819
	}
820
821
	return $count;
822
}
823
824
/**
825
 * Checks whether a payment has been marked as complete.
826
 *
827
 * @param int $payment_id Payment ID to check against.
828
 *
829
 * @since 1.0
830
 *
831
 * @return bool $ret True if complete, false otherwise.
832
 */
833
function give_is_payment_complete( $payment_id ) {
834
	$payment = new Give_Payment( $payment_id );
835
836
	$ret = false;
837
838
	if ( $payment->ID > 0 ) {
839
840
		if ( (int) $payment_id === (int) $payment->ID && 'publish' == $payment->status ) {
841
			$ret = true;
842
		}
843
	}
844
845
	return apply_filters( 'give_is_payment_complete', $ret, $payment_id, $payment->post_status );
846
}
847
848
/**
849
 * Get Total Donations.
850
 *
851
 * @since 1.0
852
 *
853
 * @return int $count Total number of donations.
854
 */
855
function give_get_total_donations() {
856
857
	$payments = give_count_payments();
858
859
	return $payments->publish;
860
}
861
862
/**
863
 * Get Total Earnings
864
 *
865
 * @param bool $recalculate Recalculate earnings forcefully.
866
 *
867
 * @since 1.0
868
 *
869
 * @return float $total Total earnings.
870
 */
871
function give_get_total_earnings( $recalculate = false ) {
872
873
	$total = get_option( 'give_earnings_total', 0 );
874
	$meta_table = __give_v20_bc_table_details( 'payment' );
875
876
	// Calculate total earnings.
877
	if ( ! $total || $recalculate ) {
878
		global $wpdb;
879
880
		$total = (float) 0;
881
882
		$args = apply_filters( 'give_get_total_earnings_args', array(
883
			'offset' => 0,
884
			'number' => - 1,
885
			'status' => array( 'publish' ),
886
			'fields' => 'ids',
887
		) );
888
889
		$payments = give_get_payments( $args );
890
		if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
891
892
			/**
893
			 * If performing a donation, we need to skip the very last payment in the database,
894
			 * since it calls give_increase_total_earnings() on completion,
895
			 * which results in duplicated earnings for the very first donation.
896
			 */
897
			if ( did_action( 'give_update_payment_status' ) ) {
898
				array_pop( $payments );
899
			}
900
901 View Code Duplication
			if ( ! empty( $payments ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
902
				$payments = implode( ',', $payments );
903
				$total    += $wpdb->get_var( "SELECT SUM(meta_value) FROM {$meta_table['name']} WHERE meta_key = '_give_payment_total' AND {$meta_table['column']['id']} IN({$payments})" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
904
			}
905
		}
906
907
		update_option( 'give_earnings_total', $total, 'no' );
908
	}
909
910
	if ( $total < 0 ) {
911
		$total = 0; // Don't ever show negative earnings.
912
	}
913
914
	return apply_filters( 'give_total_earnings', round( $total, give_get_price_decimals() ), $total );
915
}
916
917
/**
918
 * Increase the Total Earnings
919
 *
920
 * @param int $amount The amount you would like to increase the total earnings by. Default is 0.
921
 *
922
 * @since 1.0
923
 *
924
 * @return float $total Total earnings.
925
 */
926
function give_increase_total_earnings( $amount = 0 ) {
927
	$total = give_get_total_earnings();
928
	$total += $amount;
929
	update_option( 'give_earnings_total', $total );
930
931
	return $total;
932
}
933
934
/**
935
 * Decrease the Total Earnings
936
 *
937
 * @param int $amount The amount you would like to decrease the total earnings by.
938
 *
939
 * @since 1.0
940
 *
941
 * @return float $total Total earnings.
942
 */
943
function give_decrease_total_earnings( $amount = 0 ) {
944
	$total = give_get_total_earnings();
945
	$total -= $amount;
946
	if ( $total < 0 ) {
947
		$total = 0;
948
	}
949
	update_option( 'give_earnings_total', $total );
950
951
	return $total;
952
}
953
954
/**
955
 * Get Payment Meta for a specific Payment
956
 *
957
 * @param int    $payment_id Payment ID.
958
 * @param string $meta_key   The meta key to pull.
959
 * @param bool   $single     Pull single meta entry or as an object.
960
 *
961
 * @since 1.0
962
 *
963
 * @return mixed $meta Payment Meta.
964
 */
965
function give_get_payment_meta( $payment_id = 0, $meta_key = '_give_payment_meta', $single = true ) {
966
	$payment = new Give_Payment( $payment_id );
967
968
	return $payment->get_meta( $meta_key, $single );
969
}
970
971
/**
972
 * Update the meta for a payment
973
 *
974
 * @param  int    $payment_id Payment ID.
975
 * @param  string $meta_key   Meta key to update.
976
 * @param  string $meta_value Value to update to.
977
 * @param  string $prev_value Previous value.
978
 *
979
 * @return mixed Meta ID if successful, false if unsuccessful.
980
 */
981
function give_update_payment_meta( $payment_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
982
	$payment = new Give_Payment( $payment_id );
983
984
	return $payment->update_meta( $meta_key, $meta_value, $prev_value );
985
}
986
987
/**
988
 * Get the user_info Key from Payment Meta
989
 *
990
 * @param int $payment_id Payment ID.
991
 *
992
 * @since 1.0
993
 *
994
 * @return array $user_info User Info Meta Values.
995
 */
996
function give_get_payment_meta_user_info( $payment_id ) {
997
	$payment = new Give_Payment( $payment_id );
998
999
	return $payment->user_info;
1000
}
1001
1002
/**
1003
 * Get the donations Key from Payment Meta
1004
 *
1005
 * Retrieves the form_id from a (Previously titled give_get_payment_meta_donations)
1006
 *
1007
 * @param int $payment_id Payment ID.
1008
 *
1009
 * @since 1.0
1010
 *
1011
 * @return int $form_id Form ID.
1012
 */
1013
function give_get_payment_form_id( $payment_id ) {
1014
	$payment = new Give_Payment( $payment_id );
1015
1016
	return $payment->form_id;
1017
}
1018
1019
/**
1020
 * Get the user email associated with a payment
1021
 *
1022
 * @param int $payment_id Payment ID.
1023
 *
1024
 * @since 1.0
1025
 *
1026
 * @return string $email User email.
1027
 */
1028
function give_get_payment_user_email( $payment_id ) {
1029
	$payment = new Give_Payment( $payment_id );
1030
1031
	return $payment->email;
1032
}
1033
1034
/**
1035
 * Is the payment provided associated with a user account
1036
 *
1037
 * @param int $payment_id The payment ID.
1038
 *
1039
 * @since 1.3
1040
 *
1041
 * @return bool $is_guest_payment If the payment is associated with a user (false) or not (true)
1042
 */
1043
function give_is_guest_payment( $payment_id ) {
1044
	$payment_user_id  = give_get_payment_user_id( $payment_id );
1045
	$is_guest_payment = ! empty( $payment_user_id ) && $payment_user_id > 0 ? false : true;
1046
1047
	return (bool) apply_filters( 'give_is_guest_payment', $is_guest_payment, $payment_id );
1048
}
1049
1050
/**
1051
 * Get the user ID associated with a payment
1052
 *
1053
 * @param int $payment_id Payment ID.
1054
 *
1055
 * @since 1.3
1056
 *
1057
 * @return int $user_id User ID.
1058
 */
1059
function give_get_payment_user_id( $payment_id ) {
1060
	$payment = new Give_Payment( $payment_id );
1061
1062
	return $payment->user_id;
1063
}
1064
1065
/**
1066
 * Get the donor ID associated with a payment.
1067
 *
1068
 * @param int $payment_id Payment ID.
1069
 *
1070
 * @since 1.0
1071
 *
1072
 * @return int $payment->customer_id Donor ID.
1073
 */
1074
function give_get_payment_donor_id( $payment_id ) {
1075
	$payment = new Give_Payment( $payment_id );
1076
1077
	return $payment->customer_id;
1078
}
1079
1080
/**
1081
 * Get the IP address used to make a donation
1082
 *
1083
 * @param int $payment_id Payment ID.
1084
 *
1085
 * @since 1.0
1086
 *
1087
 * @return string $ip User IP.
1088
 */
1089
function give_get_payment_user_ip( $payment_id ) {
1090
	$payment = new Give_Payment( $payment_id );
1091
1092
	return $payment->ip;
1093
}
1094
1095
/**
1096
 * Get the date a payment was completed
1097
 *
1098
 * @param int $payment_id Payment ID.
1099
 *
1100
 * @since 1.0
1101
 *
1102
 * @return string $date The date the payment was completed.
1103
 */
1104
function give_get_payment_completed_date( $payment_id = 0 ) {
1105
	$payment = new Give_Payment( $payment_id );
1106
1107
	return $payment->completed_date;
1108
}
1109
1110
/**
1111
 * Get the gateway associated with a payment
1112
 *
1113
 * @param int $payment_id Payment ID.
1114
 *
1115
 * @since 1.0
1116
 *
1117
 * @return string $gateway Gateway.
1118
 */
1119
function give_get_payment_gateway( $payment_id ) {
1120
	$payment = new Give_Payment( $payment_id );
1121
1122
	return $payment->gateway;
1123
}
1124
1125
/**
1126
 * Get the currency code a payment was made in
1127
 *
1128
 * @param int $payment_id Payment ID.
1129
 *
1130
 * @since 1.0
1131
 *
1132
 * @return string $currency The currency code.
1133
 */
1134
function give_get_payment_currency_code( $payment_id = 0 ) {
1135
	$payment = new Give_Payment( $payment_id );
1136
1137
	return $payment->currency;
1138
}
1139
1140
/**
1141
 * Get the currency name a payment was made in
1142
 *
1143
 * @param int $payment_id Payment ID.
1144
 *
1145
 * @since 1.0
1146
 *
1147
 * @return string $currency The currency name.
1148
 */
1149
function give_get_payment_currency( $payment_id = 0 ) {
1150
	$currency = give_get_payment_currency_code( $payment_id );
1151
1152
	return apply_filters( 'give_payment_currency', give_get_currency_name( $currency ), $payment_id );
1153
}
1154
1155
/**
1156
 * Get the key for a donation
1157
 *
1158
 * @param int $payment_id Payment ID.
1159
 *
1160
 * @since 1.0
1161
 *
1162
 * @return string $key Donation key.
1163
 */
1164
function give_get_payment_key( $payment_id = 0 ) {
1165
	$payment = new Give_Payment( $payment_id );
1166
1167
	return $payment->key;
1168
}
1169
1170
/**
1171
 * Get the payment order number
1172
 *
1173
 * This will return the payment ID if sequential order numbers are not enabled or the order number does not exist
1174
 *
1175
 * @param int $payment_id Payment ID.
1176
 *
1177
 * @since 1.0
1178
 *
1179
 * @return string $number Payment order number.
1180
 */
1181
function give_get_payment_number( $payment_id = 0 ) {
1182
	$payment = new Give_Payment( $payment_id );
1183
1184
	return $payment->number;
1185
}
1186
1187
/**
1188
 * Formats the payment number with the prefix and postfix
1189
 *
1190
 * @param int $number The payment number to format.
1191
 *
1192
 * @since 1.3
1193
 *
1194
 * @return string      The formatted payment number.
1195
 */
1196
function give_format_payment_number( $number ) {
1197
1198
	if ( ! give_get_option( 'enable_sequential' ) ) {
1199
		return $number;
1200
	}
1201
1202
	if ( ! is_numeric( $number ) ) {
1203
		return $number;
1204
	}
1205
1206
	$prefix  = give_get_option( 'sequential_prefix' );
1207
	$number  = absint( $number );
1208
	$postfix = give_get_option( 'sequential_postfix' );
1209
1210
	$formatted_number = $prefix . $number . $postfix;
1211
1212
	return apply_filters( 'give_format_payment_number', $formatted_number, $prefix, $number, $postfix );
1213
}
1214
1215
/**
1216
 * Gets the next available order number
1217
 *
1218
 * This is used when inserting a new payment
1219
 *
1220
 * @since 1.0
1221
 *
1222
 * @return string $number The next available payment number.
1223
 */
1224
function give_get_next_payment_number() {
1225
1226
	if ( ! give_get_option( 'enable_sequential' ) ) {
1227
		return false;
1228
	}
1229
1230
	$number           = get_option( 'give_last_payment_number' );
1231
	$start            = give_get_option( 'sequential_start', 1 );
1232
	$increment_number = true;
1233
1234
	if ( false !== $number ) {
1235
1236
		if ( empty( $number ) ) {
1237
1238
			$number           = $start;
1239
			$increment_number = false;
1240
1241
		}
1242
	} else {
1243
1244
		// This case handles the first addition of the new option, as well as if it get's deleted for any reason.
1245
		$payments     = new Give_Payments_Query( array(
1246
			'number'  => 1,
1247
			'order'   => 'DESC',
1248
			'orderby' => 'ID',
1249
			'output'  => 'posts',
1250
			'fields'  => 'ids',
1251
		) );
1252
		$last_payment = $payments->get_payments();
1253
1254
		if ( ! empty( $last_payment ) ) {
1255
1256
			$number = give_get_payment_number( $last_payment[0] );
1257
1258
		}
1259
1260
		if ( ! empty( $number ) && $number !== (int) $last_payment[0] ) {
1261
1262
			$number = give_remove_payment_prefix_postfix( $number );
1263
1264
		} else {
1265
1266
			$number           = $start;
1267
			$increment_number = false;
1268
		}
1269
	}// End if().
1270
1271
	$increment_number = apply_filters( 'give_increment_payment_number', $increment_number, $number );
1272
1273
	if ( $increment_number ) {
1274
		$number ++;
1275
	}
1276
1277
	return apply_filters( 'give_get_next_payment_number', $number );
1278
}
1279
1280
/**
1281
 * Given a given a number, remove the pre/postfix
1282
 *
1283
 * @param string $number The formatted Current Number to increment.
1284
 *
1285
 * @since 1.3
1286
 *
1287
 * @return string The new Payment number without prefix and postfix.
1288
 */
1289
function give_remove_payment_prefix_postfix( $number ) {
1290
1291
	$prefix  = give_get_option( 'sequential_prefix' );
1292
	$postfix = give_get_option( 'sequential_postfix' );
1293
1294
	// Remove prefix.
1295
	$number = preg_replace( '/' . $prefix . '/', '', $number, 1 );
1296
1297
	// Remove the postfix.
1298
	$length      = strlen( $number );
1299
	$postfix_pos = strrpos( $number, $postfix );
1300
	if ( false !== $postfix_pos ) {
1301
		$number = substr_replace( $number, '', $postfix_pos, $length );
1302
	}
1303
1304
	// Ensure it's a whole number.
1305
	$number = intval( $number );
1306
1307
	return apply_filters( 'give_remove_payment_prefix_postfix', $number, $prefix, $postfix );
1308
1309
}
1310
1311
/**
1312
 * Get Payment Amount
1313
 *
1314
 * Get the fully formatted donation amount. The donation amount is retrieved using give_get_donation_amount() and is then
1315
 * sent through give_currency_filter() and  give_format_amount() to format the amount correctly.
1316
 *
1317
 * @param int    $donation_id Donation ID.
1318
 * @param string $type        String parameter which will define context of donation amount.
1319
 *
1320
 * @since 1.0
1321
 * @since 1.8.17 Added filter and internally use functions.
1322
 *
1323
 * @return string $amount Fully formatted donation amount.
1324
 */
1325
function give_donation_amount( $donation_id = 0, $type = '' ) {
1326
	$donation_currency = give_get_payment_currency_code( $donation_id );
1327
	$amount            = give_get_payment_amount( $donation_id );
1328
1329
	$formatted_amount = give_currency_filter(
1330
		give_format_amount(
1331
			$amount,
1332
			array(
1333
				'sanitize' => false,
1334
				'currency' => $donation_currency,
1335
			)
1336
		),
1337
		$donation_currency
1338
	);
1339
1340
	/**
1341
	 * Filter payment amount.
1342
	 *
1343
	 * @since 1.8.17
1344
	 *
1345
	 * @param string  $formatted_amount Formatted amount.
1346
	 * @param double  $amount           Donation amount.
1347
	 * @param integer $donation_id      Donation ID.
1348
	 * @param string  $type             String parameter which will define context of donation amount..
1349
	 */
1350
	return apply_filters( 'give_get_donation_amount', $formatted_amount, $amount, $donation_id, $type );
1351
}
1352
1353
/**
1354
 * Get the amount associated with a payment
1355
 *
1356
 * @param int $payment_id Payment ID.
1357
 *
1358
 * @access public
1359
 * @since  1.0
1360
 *
1361
 * @return mixed
1362
 */
1363
function give_get_payment_amount( $payment_id ) {
1364
1365
	$payment = new Give_Payment( $payment_id );
1366
1367
	return apply_filters( 'give_payment_amount', floatval( $payment->total ), $payment_id );
1368
}
1369
1370
/**
1371
 * Payment Subtotal
1372
 *
1373
 * Retrieves subtotal for payment and then returns a full formatted amount. This
1374
 * function essentially calls give_get_payment_subtotal()
1375
 *
1376
 * @param int $payment_id Payment ID.
1377
 *
1378
 * @since 1.5
1379
 *
1380
 * @see   give_get_payment_subtotal()
1381
 *
1382
 * @return array Fully formatted payment subtotal.
1383
 */
1384
function give_payment_subtotal( $payment_id = 0 ) {
1385
	$subtotal = give_get_payment_subtotal( $payment_id );
1386
1387
	return give_currency_filter( give_format_amount( $subtotal, array( 'sanitize' => false ) ), give_get_payment_currency_code( $payment_id ) );
1388
}
1389
1390
/**
1391
 * Get Payment Subtotal
1392
 *
1393
 * Retrieves subtotal for payment and then returns a non formatted amount.
1394
 *
1395
 * @param int $payment_id Payment ID.
1396
 *
1397
 * @since 1.5
1398
 *
1399
 * @return float $subtotal Subtotal for payment (non formatted).
1400
 */
1401
function give_get_payment_subtotal( $payment_id = 0 ) {
1402
	$payment = new Give_Payment( $payment_id );
1403
1404
	return $payment->subtotal;
1405
}
1406
1407
/**
1408
 * Retrieves the donation ID
1409
 *
1410
 * @param int $payment_id Payment ID.
1411
 *
1412
 * @since  1.0
1413
 *
1414
 * @return string The donation ID.
1415
 */
1416
function give_get_payment_transaction_id( $payment_id = 0 ) {
1417
	$payment = new Give_Payment( $payment_id );
1418
1419
	return $payment->transaction_id;
1420
}
1421
1422
/**
1423
 * Sets a Transaction ID in post meta for the given Payment ID.
1424
 *
1425
 * @param int    $payment_id     Payment ID.
1426
 * @param string $transaction_id The transaction ID from the gateway.
1427
 *
1428
 * @since  1.0
1429
 *
1430
 * @return bool|mixed
1431
 */
1432
function give_set_payment_transaction_id( $payment_id = 0, $transaction_id = '' ) {
1433
1434
	if ( empty( $payment_id ) || empty( $transaction_id ) ) {
1435
		return false;
1436
	}
1437
1438
	$transaction_id = apply_filters( 'give_set_payment_transaction_id', $transaction_id, $payment_id );
1439
1440
	return give_update_payment_meta( $payment_id, '_give_payment_transaction_id', $transaction_id );
1441
}
1442
1443
/**
1444
 * Retrieve the donation ID based on the key
1445
 *
1446
 * @param string  $key  the key to search for.
1447
 *
1448
 * @since 1.0
1449
 * @global object $wpdb Used to query the database using the WordPress Database API.
1450
 *
1451
 * @return int $purchase Donation ID.
1452
 */
1453 View Code Duplication
function give_get_purchase_id_by_key( $key ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1454
	global $wpdb;
1455
	$meta_table = __give_v20_bc_table_details( 'payment' );
1456
1457
	$purchase = $wpdb->get_var( $wpdb->prepare( "SELECT {$meta_table['column']['id']} FROM {$meta_table['name']} WHERE meta_key = '_give_payment_purchase_key' AND meta_value = %s LIMIT 1", $key ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1458
1459
	if ( $purchase != null ) {
1460
		return $purchase;
1461
	}
1462
1463
	return 0;
1464
}
1465
1466
1467
/**
1468
 * Retrieve the donation ID based on the transaction ID
1469
 *
1470
 * @param string  $key  The transaction ID to search for.
1471
 *
1472
 * @since 1.3
1473
 * @global object $wpdb Used to query the database using the WordPress Database API.
1474
 *
1475
 * @return int $purchase Donation ID.
1476
 */
1477 View Code Duplication
function give_get_purchase_id_by_transaction_id( $key ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1478
	global $wpdb;
1479
	$meta_table = __give_v20_bc_table_details('payment');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
1480
1481
	$purchase = $wpdb->get_var( $wpdb->prepare( "SELECT {$meta_table['column']['id']} FROM {$meta_table['name']} WHERE meta_key = '_give_payment_transaction_id' AND meta_value = %s LIMIT 1", $key ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1482
1483
	if ( $purchase != null ) {
1484
		return $purchase;
1485
	}
1486
1487
	return 0;
1488
}
1489
1490
/**
1491
 * Retrieve all notes attached to a donation
1492
 *
1493
 * @param int    $payment_id The donation ID to retrieve notes for.
1494
 * @param string $search     Search for notes that contain a search term.
1495
 *
1496
 * @since 1.0
1497
 *
1498
 * @return array $notes Donation Notes
1499
 */
1500
function give_get_payment_notes( $payment_id = 0, $search = '' ) {
1501
1502
	if ( empty( $payment_id ) && empty( $search ) ) {
1503
		return false;
1504
	}
1505
1506
	remove_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1507
	remove_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10 );
1508
1509
	$notes = get_comments( array(
1510
		'post_id' => $payment_id,
1511
		'order'   => 'ASC',
1512
		'search'  => $search,
1513
	) );
1514
1515
	add_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1516
	add_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10, 2 );
1517
1518
	return $notes;
1519
}
1520
1521
1522
/**
1523
 * Add a note to a payment
1524
 *
1525
 * @param int    $payment_id The payment ID to store a note for.
1526
 * @param string $note       The note to store.
1527
 *
1528
 * @since 1.0
1529
 *
1530
 * @return int The new note ID
1531
 */
1532
function give_insert_payment_note( $payment_id = 0, $note = '' ) {
1533
	if ( empty( $payment_id ) ) {
1534
		return false;
1535
	}
1536
1537
	/**
1538
	 * Fires before inserting payment note.
1539
	 *
1540
	 * @param int    $payment_id Payment ID.
1541
	 * @param string $note       The note.
1542
	 *
1543
	 * @since 1.0
1544
	 */
1545
	do_action( 'give_pre_insert_payment_note', $payment_id, $note );
1546
1547
	$note_id = wp_insert_comment( wp_filter_comment( array(
1548
		'comment_post_ID'      => $payment_id,
1549
		'comment_content'      => $note,
1550
		'user_id'              => is_admin() ? get_current_user_id() : 0,
1551
		'comment_date'         => current_time( 'mysql' ),
1552
		'comment_date_gmt'     => current_time( 'mysql', 1 ),
1553
		'comment_approved'     => 1,
1554
		'comment_parent'       => 0,
1555
		'comment_author'       => '',
1556
		'comment_author_IP'    => '',
1557
		'comment_author_url'   => '',
1558
		'comment_author_email' => '',
1559
		'comment_type'         => 'give_payment_note',
1560
1561
	) ) );
1562
1563
	/**
1564
	 * Fires after payment note inserted.
1565
	 *
1566
	 * @param int    $note_id    Note ID.
1567
	 * @param int    $payment_id Payment ID.
1568
	 * @param string $note       The note.
1569
	 *
1570
	 * @since 1.0
1571
	 */
1572
	do_action( 'give_insert_payment_note', $note_id, $payment_id, $note );
1573
1574
	return $note_id;
1575
}
1576
1577
/**
1578
 * Deletes a payment note
1579
 *
1580
 * @param int $comment_id The comment ID to delete.
1581
 * @param int $payment_id The payment ID the note is connected to.
1582
 *
1583
 * @since 1.0
1584
 *
1585
 * @return bool True on success, false otherwise.
1586
 */
1587
function give_delete_payment_note( $comment_id = 0, $payment_id = 0 ) {
1588
	if ( empty( $comment_id ) ) {
1589
		return false;
1590
	}
1591
1592
	/**
1593
	 * Fires before deleting donation note.
1594
	 *
1595
	 * @param int $comment_id Note ID.
1596
	 * @param int $payment_id Payment ID.
1597
	 *
1598
	 * @since 1.0
1599
	 */
1600
	do_action( 'give_pre_delete_payment_note', $comment_id, $payment_id );
1601
1602
	$ret = wp_delete_comment( $comment_id, true );
1603
1604
	/**
1605
	 * Fires after donation note deleted.
1606
	 *
1607
	 * @param int $comment_id Note ID.
1608
	 * @param int $payment_id Payment ID.
1609
	 *
1610
	 * @since 1.0
1611
	 */
1612
	do_action( 'give_post_delete_payment_note', $comment_id, $payment_id );
1613
1614
	return $ret;
1615
}
1616
1617
/**
1618
 * Gets the payment note HTML
1619
 *
1620
 * @param object|int $note       The comment object or ID.
1621
 * @param int        $payment_id The payment ID the note is connected to.
1622
 *
1623
 * @since 1.0
1624
 *
1625
 * @return string
1626
 */
1627
function give_get_payment_note_html( $note, $payment_id = 0 ) {
1628
1629
	if ( is_numeric( $note ) ) {
1630
		$note = get_comment( $note );
1631
	}
1632
1633
	if ( ! empty( $note->user_id ) ) {
1634
		$user = get_userdata( $note->user_id );
1635
		$user = $user->display_name;
1636
	} else {
1637
		$user = __( 'System', 'give' );
1638
	}
1639
1640
	$date_format = give_date_format() . ', ' . get_option( 'time_format' );
1641
1642
	$delete_note_url = wp_nonce_url( add_query_arg( array(
1643
		'give-action' => 'delete_payment_note',
1644
		'note_id'     => $note->comment_ID,
1645
		'payment_id'  => $payment_id,
1646
	) ), 'give_delete_payment_note_' . $note->comment_ID );
1647
1648
	$note_html = '<div class="give-payment-note" id="give-payment-note-' . $note->comment_ID . '">';
1649
	$note_html .= '<p>';
1650
	$note_html .= '<strong>' . $user . '</strong>&nbsp;&ndash;&nbsp;<span style="color:#aaa;font-style:italic;">' . date_i18n( $date_format, strtotime( $note->comment_date ) ) . '</span><br/>';
1651
	$note_html .= $note->comment_content;
1652
	$note_html .= '&nbsp;&ndash;&nbsp;<a href="' . esc_url( $delete_note_url ) . '" class="give-delete-payment-note" data-note-id="' . absint( $note->comment_ID ) . '" data-payment-id="' . absint( $payment_id ) . '" aria-label="' . __( 'Delete this donation note.', 'give' ) . '">' . __( 'Delete', 'give' ) . '</a>';
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
1653
	$note_html .= '</p>';
1654
	$note_html .= '</div>';
1655
1656
	return $note_html;
1657
1658
}
1659
1660
/**
1661
 * Exclude notes (comments) on give_payment post type from showing in Recent
1662
 * Comments widgets
1663
 *
1664
 * @param object $query WordPress Comment Query Object.
1665
 *
1666
 * @since 1.0
1667
 *
1668
 * @return void
1669
 */
1670
function give_hide_payment_notes( $query ) {
1671
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.1', '>=' ) ) {
1672
		$types = isset( $query->query_vars['type__not_in'] ) ? $query->query_vars['type__not_in'] : array();
1673
		if ( ! is_array( $types ) ) {
1674
			$types = array( $types );
1675
		}
1676
		$types[]                           = 'give_payment_note';
1677
		$query->query_vars['type__not_in'] = $types;
1678
	}
1679
}
1680
1681
add_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1682
1683
/**
1684
 * Exclude notes (comments) on give_payment post type from showing in Recent Comments widgets
1685
 *
1686
 * @param array  $clauses          Comment clauses for comment query.
1687
 * @param object $wp_comment_query WordPress Comment Query Object.
1688
 *
1689
 * @since 1.0
1690
 *
1691
 * @return array $clauses Updated comment clauses.
1692
 */
1693
function give_hide_payment_notes_pre_41( $clauses, $wp_comment_query ) {
0 ignored issues
show
Unused Code introduced by
The parameter $wp_comment_query is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1694
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.1', '<' ) ) {
1695
		$clauses['where'] .= ' AND comment_type != "give_payment_note"';
1696
	}
1697
1698
	return $clauses;
1699
}
1700
1701
add_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10, 2 );
1702
1703
1704
/**
1705
 * Exclude notes (comments) on give_payment post type from showing in comment feeds
1706
 *
1707
 * @param string $where
1708
 * @param object $wp_comment_query WordPress Comment Query Object.
1709
 *
1710
 * @since 1.0
1711
 *
1712
 * @return string $where
1713
 */
1714
function give_hide_payment_notes_from_feeds( $where, $wp_comment_query ) {
0 ignored issues
show
Unused Code introduced by
The parameter $wp_comment_query is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1715
	global $wpdb;
1716
1717
	$where .= $wpdb->prepare( ' AND comment_type != %s', 'give_payment_note' );
1718
1719
	return $where;
1720
}
1721
1722
add_filter( 'comment_feed_where', 'give_hide_payment_notes_from_feeds', 10, 2 );
1723
1724
1725
/**
1726
 * Remove Give Comments from the wp_count_comments function
1727
 *
1728
 * @param array $stats   (empty from core filter).
1729
 * @param int   $post_id Post ID.
1730
 *
1731
 * @access public
1732
 * @since  1.0
1733
 *
1734
 * @return array|object Array of comment counts.
1735
 */
1736
function give_remove_payment_notes_in_comment_counts( $stats, $post_id ) {
1737
	global $wpdb, $pagenow;
1738
1739
	if ( 'index.php' != $pagenow ) {
1740
		return $stats;
1741
	}
1742
1743
	$post_id = (int) $post_id;
1744
1745
	if ( apply_filters( 'give_count_payment_notes_in_comments', false ) ) {
1746
		return $stats;
1747
	}
1748
1749
	$stats = wp_cache_get( "comments-{$post_id}", 'counts' );
1750
1751
	if ( false !== $stats ) {
1752
		return $stats;
1753
	}
1754
1755
	$where = 'WHERE comment_type != "give_payment_note"';
1756
1757
	if ( $post_id > 0 ) {
1758
		$where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id );
1759
	}
1760
1761
	$count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} {$where} GROUP BY comment_approved", ARRAY_A );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
1762
1763
	$total    = 0;
1764
	$approved = array(
1765
		'0'            => 'moderated',
0 ignored issues
show
introduced by
Detected usage of 0, possible slow query.
Loading history...
1766
		'1'            => 'approved',
1767
		'spam'         => 'spam',
1768
		'trash'        => 'trash',
1769
		'post-trashed' => 'post-trashed',
1770
	);
1771
	foreach ( (array) $count as $row ) {
1772
		// Don't count post-trashed toward totals.
1773
		if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
1774
			$total += $row['num_comments'];
1775
		}
1776
		if ( isset( $approved[ $row['comment_approved'] ] ) ) {
1777
			$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
1778
		}
1779
	}
1780
1781
	$stats['total_comments'] = $total;
1782
	foreach ( $approved as $key ) {
1783
		if ( empty( $stats[ $key ] ) ) {
1784
			$stats[ $key ] = 0;
1785
		}
1786
	}
1787
1788
	$stats = (object) $stats;
1789
	wp_cache_set( "comments-{$post_id}", $stats, 'counts' );
1790
1791
	return $stats;
1792
}
1793
1794
add_filter( 'wp_count_comments', 'give_remove_payment_notes_in_comment_counts', 10, 2 );
1795
1796
1797
/**
1798
 * Filter where older than one week
1799
 *
1800
 * @param string $where Where clause.
1801
 *
1802
 * @access public
1803
 * @since  1.0
1804
 *
1805
 * @return string $where Modified where clause.
1806
 */
1807
function give_filter_where_older_than_week( $where = '' ) {
1808
	// Payments older than one week.
1809
	$start = date( 'Y-m-d', strtotime( '-7 days' ) );
1810
	$where .= " AND post_date <= '{$start}'";
1811
1812
	return $where;
1813
}
1814
1815
1816
/**
1817
 * Get Payment Form ID.
1818
 *
1819
 * Retrieves the form title and appends the level name if present.
1820
 *
1821
 * @param array  $payment_meta Payment meta data.
1822
 * @param bool   $only_level   If set to true will only return the level name if multi-level enabled.
1823
 * @param string $separator    The separator between the .
1824
 *
1825
 * @since 1.5
1826
 *
1827
 * @return string $form_title Returns the full title if $only_level is false, otherwise returns the levels title.
1828
 */
1829
function give_get_payment_form_title( $payment_meta, $only_level = false, $separator = '' ) {
1830
1831
	$form_id    = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : 0;
1832
	$price_id   = isset( $payment_meta['price_id'] ) ? $payment_meta['price_id'] : null;
1833
	$form_title = isset( $payment_meta['form_title'] ) ? $payment_meta['form_title'] : '';
1834
1835
	if ( $only_level == true ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
introduced by
Found "== true". Use Yoda Condition checks, you must
Loading history...
1836
		$form_title = '';
1837
	}
1838
1839
	// If multi-level, append to the form title.
1840
	if ( give_has_variable_prices( $form_id ) ) {
1841
1842
		// Only add separator if there is a form title.
1843
		if ( ! empty( $form_title ) ) {
1844
			$form_title .= ' ' . $separator . ' ';
1845
		}
1846
1847
		$form_title .= '<span class="donation-level-text-wrap">';
1848
1849
		if ( $price_id == 'custom' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
1850
			$custom_amount_text = give_get_meta( $form_id, '_give_custom_amount_text', true );
1851
			$form_title         .= ! empty( $custom_amount_text ) ? $custom_amount_text : __( 'Custom Amount', 'give' );
1852
		} else {
1853
			$form_title .= give_get_price_option_name( $form_id, $price_id );
1854
		}
1855
1856
		$form_title .= '</span>';
1857
1858
	}
1859
1860
	return apply_filters( 'give_get_payment_form_title', $form_title, $payment_meta );
1861
1862
}
1863
1864
/**
1865
 * Get Price ID
1866
 *
1867
 * Retrieves the Price ID when provided a proper form ID and price (donation) total
1868
 *
1869
 * @param int    $form_id Form ID.
1870
 * @param string $price   Price ID.
1871
 *
1872
 * @return string $price_id
1873
 */
1874
function give_get_price_id( $form_id, $price ) {
1875
	$price_id = null;
1876
1877
	if ( give_has_variable_prices( $form_id ) ) {
1878
1879
		$levels = give_get_meta( $form_id, '_give_donation_levels', true );
1880
1881
		foreach ( $levels as $level ) {
1882
1883
			$level_amount = give_maybe_sanitize_amount( $level['_give_amount'] );
1884
1885
			// Check that this indeed the recurring price.
1886
			if ( $level_amount == $price ) {
1887
1888
				$price_id = $level['_give_id']['level_id'];
1889
				break;
1890
1891
			}
1892
		}
1893
1894
		if ( is_null( $price_id ) && give_is_custom_price_mode( $form_id ) ) {
1895
			$price_id = 'custom';
1896
		}
1897
	}
1898
1899
	// Price ID must be numeric or string.
1900
	$price_id = ! is_numeric( $price_id ) && ! is_string( $price_id ) ? 0 : $price_id;
1901
1902
	return $price_id;
1903
}
1904
1905
/**
1906
 * Get/Print give form dropdown html
1907
 *
1908
 * This function is wrapper to public method forms_dropdown of Give_HTML_Elements class to get/print form dropdown html.
1909
 * Give_HTML_Elements is defined in includes/class-give-html-elements.php.
1910
 *
1911
 * @param array $args Arguments for form dropdown.
1912
 * @param bool  $echo This parameter decides if print form dropdown html output or not.
1913
 *
1914
 * @since 1.6
1915
 *
1916
 * @return string
1917
 */
1918
function give_get_form_dropdown( $args = array(), $echo = false ) {
1919
	$form_dropdown_html = Give()->html->forms_dropdown( $args );
1920
1921
	if ( ! $echo ) {
1922
		return $form_dropdown_html;
1923
	}
1924
1925
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1926
}
1927
1928
/**
1929
 * Get/Print give form variable price dropdown html
1930
 *
1931
 * @param array $args Arguments for form dropdown.
1932
 * @param bool  $echo This parameter decide if print form dropdown html output or not.
1933
 *
1934
 * @since 1.6
1935
 *
1936
 * @return string|bool
1937
 */
1938
function give_get_form_variable_price_dropdown( $args = array(), $echo = false ) {
1939
1940
	// Check for give form id.
1941
	if ( empty( $args['id'] ) ) {
1942
		return false;
1943
	}
1944
1945
	$form = new Give_Donate_Form( $args['id'] );
1946
1947
	// Check if form has variable prices or not.
1948
	if ( ! $form->ID || ! $form->has_variable_prices() ) {
1949
		return false;
1950
	}
1951
1952
	$variable_prices        = $form->get_prices();
1953
	$variable_price_options = array();
1954
1955
	// Check if multi donation form support custom donation or not.
1956
	if ( $form->is_custom_price_mode() ) {
1957
		$variable_price_options['custom'] = _x( 'Custom', 'custom donation dropdown item', 'give' );
1958
	}
1959
1960
	// Get variable price and ID from variable price array.
1961
	foreach ( $variable_prices as $variable_price ) {
1962
		$variable_price_options[ $variable_price['_give_id']['level_id'] ] = ! empty( $variable_price['_give_text'] ) ? $variable_price['_give_text'] : give_currency_filter( give_format_amount( $variable_price['_give_amount'], array( 'sanitize' => false ) ) );
1963
	}
1964
1965
	// Update options.
1966
	$args = array_merge( $args, array(
1967
		'options' => $variable_price_options,
1968
	) );
1969
1970
	// Generate select html.
1971
	$form_dropdown_html = Give()->html->select( $args );
1972
1973
	if ( ! $echo ) {
1974
		return $form_dropdown_html;
1975
	}
1976
1977
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1978
}
1979
1980
/**
1981
 * Get the price_id from the payment meta.
1982
 *
1983
 * Some gateways use `give_price_id` and others were using just `price_id`;
1984
 * This checks for the difference and falls back to retrieving it from the form as a last resort.
1985
 *
1986
 * @param array $payment_meta Payment Meta.
1987
 *
1988
 * @since 1.8.6
1989
 *
1990
 * @return string
1991
 */
1992
function give_get_payment_meta_price_id( $payment_meta ) {
1993
1994
	if ( isset( $payment_meta['give_price_id'] ) ) {
1995
		$price_id = $payment_meta['give_price_id'];
1996
	} elseif ( isset( $payment_meta['price_id'] ) ) {
1997
		$price_id = $payment_meta['price_id'];
1998
	} else {
1999
		$price_id = give_get_price_id( $payment_meta['give_form_id'], $payment_meta['price'] );
2000
	}
2001
2002
	return apply_filters( 'give_get_payment_meta_price_id', $price_id );
2003
2004
}
2005