Test Failed
Push — issues/370 ( 90279e )
by Ravinder
05:35
created

functions.php ➔ give_delete_donation()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 66
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 23
nc 12
nop 2
dl 0
loc 66
rs 7.0832
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
 * @return array $payments Payments retrieved from the database
45
 */
46
function give_get_payments( $args = array() ) {
47
48
	// Fallback to post objects to ensure backwards compatibility.
49
	if ( ! isset( $args['output'] ) ) {
50
		$args['output'] = 'posts';
51
	}
52
53
	$args     = apply_filters( 'give_get_payments_args', $args );
54
	$payments = new Give_Payments_Query( $args );
55
56
	return $payments->get_payments();
57
}
58
59
/**
60
 * Retrieve payment by a given field
61
 *
62
 * @since  1.0
63
 *
64
 * @param  string $field The field to retrieve the payment with.
65
 * @param  mixed $value The value for $field.
66
 *
67
 * @return mixed
68
 */
69
function give_get_payment_by( $field = '', $value = '' ) {
70
71
	if ( empty( $field ) || empty( $value ) ) {
72
		return false;
73
	}
74
75
	switch ( strtolower( $field ) ) {
76
77
		case 'id':
78
			$payment = new Give_Payment( $value );
79
			$id      = $payment->ID;
80
81
			if ( empty( $id ) ) {
82
				return false;
83
			}
84
85
			break;
86
87 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...
88
			$payment = give_get_payments( array(
89
				'meta_key'       => '_give_payment_purchase_key',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
90
				'meta_value'     => $value,
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
91
				'posts_per_page' => 1,
92
				'fields'         => 'ids',
93
			) );
94
95
			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...
96
				$payment = new Give_Payment( $payment[0] );
97
			}
98
99
			break;
100
101 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...
102
			$payment = give_get_payments( array(
103
				'meta_key'       => '_give_payment_number',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
104
				'meta_value'     => $value,
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
105
				'posts_per_page' => 1,
106
				'fields'         => 'ids',
107
			) );
108
109
			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...
110
				$payment = new Give_Payment( $payment[0] );
111
			}
112
113
			break;
114
115
		default:
116
			return false;
117
	}// End switch().
118
119
	if ( $payment ) {
120
		return $payment;
121
	}
122
123
	return false;
124
}
125
126
/**
127
 * Insert Payment
128
 *
129
 * @since  1.0
130
 *
131
 * @param  array $payment_data Arguments passed.
132
 *
133
 * @return int|bool Payment ID if payment is inserted, false otherwise.
134
 */
135
function give_insert_payment( $payment_data = array() ) {
136
137
	if ( empty( $payment_data ) ) {
138
		return false;
139
	}
140
141
	$payment    = new Give_Payment();
142
	$gateway    = ! empty( $payment_data['gateway'] ) ? $payment_data['gateway'] : '';
143
	$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...
144
	$form_id    = isset( $payment_data['give_form_id'] ) ? $payment_data['give_form_id'] : 0;
145
	$price_id   = give_get_payment_meta_price_id( $payment_data );
146
	$form_title = isset( $payment_data['give_form_title'] ) ? $payment_data['give_form_title'] : get_the_title( $form_id );
147
148
	// Set properties.
149
	$payment->total          = $payment_data['price'];
150
	$payment->status         = ! empty( $payment_data['status'] ) ? $payment_data['status'] : 'pending';
151
	$payment->currency       = ! empty( $payment_data['currency'] ) ? $payment_data['currency'] : give_get_currency();
152
	$payment->user_info      = $payment_data['user_info'];
153
	$payment->gateway        = $gateway;
154
	$payment->form_title     = $form_title;
155
	$payment->form_id        = $form_id;
156
	$payment->price_id       = $price_id;
157
	$payment->donor_id       = ( ! empty( $payment_data['donor_id'] ) ? $payment_data['donor_id'] : '' );
158
	$payment->user_id        = $payment_data['user_info']['id'];
159
	$payment->email          = $payment_data['user_email'];
160
	$payment->first_name     = $payment_data['user_info']['first_name'];
161
	$payment->last_name      = $payment_data['user_info']['last_name'];
162
	$payment->email          = $payment_data['user_info']['email'];
163
	$payment->ip             = give_get_ip();
164
	$payment->key            = $payment_data['purchase_key'];
165
	$payment->mode           = ( ! empty( $payment_data['mode'] ) ? (string) $payment_data['mode'] : ( give_is_test_mode() ? 'test' : 'live' ) );
166
	$payment->parent_payment = ! empty( $payment_data['parent'] ) ? absint( $payment_data['parent'] ) : '';
167
168
	// Add the donation.
169
	$args = array(
170
		'price'    => $payment->total,
171
		'price_id' => $payment->price_id,
172
	);
173
174
	$payment->add_donation( $payment->form_id, $args );
175
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
176
177
	// Set date if present.
178
	if ( isset( $payment_data['post_date'] ) ) {
179
		$payment->date = $payment_data['post_date'];
180
	}
181
182
	// Handle sequential payments.
183
	if ( give_get_option( 'enable_sequential' ) ) {
184
		$number          = give_get_next_payment_number();
185
		$payment->number = give_format_payment_number( $number );
186
		update_option( 'give_last_payment_number', $number );
187
	}
188
189
	// Save payment.
190
	$payment->save();
191
192
	/**
193
	 * Fires while inserting payments.
194
	 *
195
	 * @since 1.0
196
	 *
197
	 * @param int $payment_id The payment ID.
198
	 * @param array $payment_data Arguments passed.
199
	 */
200
	do_action( 'give_insert_payment', $payment->ID, $payment_data );
201
202
	// Return payment ID upon success.
203
	if ( ! empty( $payment->ID ) ) {
204
		return $payment->ID;
205
	}
206
207
	// Return false if no payment was inserted.
208
	return false;
209
210
}
211
212
/**
213
 * Create payment.
214
 *
215
 * @param $payment_data
216
 *
217
 * @return bool|int
218
 */
219
function give_create_payment( $payment_data ) {
220
221
	$form_id  = intval( $payment_data['post_data']['give-form-id'] );
222
	$price_id = isset( $payment_data['post_data']['give-price-id'] ) ? $payment_data['post_data']['give-price-id'] : '';
223
224
	// Collect payment data.
225
	$insert_payment_data = array(
226
		'price'           => $payment_data['price'],
227
		'give_form_title' => $payment_data['post_data']['give-form-title'],
228
		'give_form_id'    => $form_id,
229
		'give_price_id'   => $price_id,
230
		'date'            => $payment_data['date'],
231
		'user_email'      => $payment_data['user_email'],
232
		'purchase_key'    => $payment_data['purchase_key'],
233
		'currency'        => give_get_currency(),
234
		'user_info'       => $payment_data['user_info'],
235
		'status'          => 'pending',
236
		'gateway'         => 'paypal',
237
	);
238
239
	/**
240
	 * Filter the payment params.
241
	 *
242
	 * @since 1.8
243
	 *
244
	 * @param array $insert_payment_data
245
	 */
246
	$insert_payment_data = apply_filters( 'give_create_payment', $insert_payment_data );
247
248
	// Record the pending payment.
249
	return give_insert_payment( $insert_payment_data );
250
}
251
252
/**
253
 * Updates a payment status.
254
 *
255
 * @since  1.0
256
 *
257
 * @param  int $payment_id Payment ID.
258
 * @param  string $new_status New Payment Status. Default is 'publish'.
259
 *
260
 * @return bool
261
 */
262
function give_update_payment_status( $payment_id, $new_status = 'publish' ) {
263
264
	$updated = false;
265
	$payment = new Give_Payment( $payment_id );
266
267
	if ( $payment && $payment->ID > 0 ) {
268
269
		$payment->status = $new_status;
270
		$updated         = $payment->save();
271
272
	}
273
274
	return $updated;
275
}
276
277
278
/**
279
 * Deletes a Donation
280
 *
281
 * @since  1.0
282
 *
283
 * @param  int $payment_id Payment ID (default: 0).
284
 * @param  bool $update_donor If we should update the donor stats (default:true).
285
 *
286
 * @return void
287
 */
288
function give_delete_donation( $payment_id = 0, $update_donor = true ) {
289
	$payment     = new Give_Payment( $payment_id );
290
	$amount      = give_get_payment_amount( $payment_id );
291
	$status      = $payment->post_status;
292
293
	$donor_id = give_get_payment_donor_id( $payment_id );
294
	$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...
295
296
	// Only undo donations that aren't these statuses.
297
	$dont_undo_statuses = apply_filters( 'give_undo_donation_statuses', array(
298
		'pending',
299
		'cancelled',
300
	) );
301
302
	if ( ! in_array( $status, $dont_undo_statuses ) ) {
303
		give_undo_donation( $payment_id );
304
	}
305
306
	if ( $status == 'publish' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
307
308
		// Only decrease earnings if they haven't already been decreased (or were never increased for this payment).
309
		give_decrease_total_earnings( $amount );
310
311
		// @todo: Refresh only range related stat cache
312
		give_delete_donation_stats();
313
314
		if ( $donor->id && $update_donor ) {
315
316
			// Decrement the stats for the donor.
317
			$donor->decrease_donation_count();
318
			$donor->decrease_value( $amount );
319
320
		}
321
	}
322
323
	/**
324
	 * Fires before deleting payment.
325
	 *
326
	 * @since 1.0
327
	 *
328
	 * @param int $payment_id Payment ID.
329
	 */
330
	do_action( 'give_payment_delete', $payment_id );
331
332
	if ( $donor->id && $update_donor ) {
333
334
		// Remove the payment ID from the donor.
335
		$donor->remove_payment( $payment_id );
336
337
	}
338
339
	// Remove the payment.
340
	wp_delete_post( $payment_id, true );
341
342
	// Remove related sale log entries.
343
	Give()->logs->delete_logs( $payment_id );
344
345
	/**
346
	 * Fires after payment deleted.
347
	 *
348
	 * @since 1.0
349
	 *
350
	 * @param int $payment_id Payment ID.
351
	 */
352
	do_action( 'give_payment_deleted', $payment_id );
353
}
354
355
/**
356
 * Undo Donation
357
 *
358
 * Undoes a donation, including the decrease of donations and earning stats.
359
 * Used for when refunding or deleting a donation.
360
 *
361
 * @since  1.0
362
 *
363
 * @param  int $payment_id Payment ID.
364
 *
365
 * @return void
366
 */
367
function give_undo_donation( $payment_id ) {
368
369
	$payment = new Give_Payment( $payment_id );
370
371
	$maybe_decrease_earnings = apply_filters( 'give_decrease_earnings_on_undo', true, $payment, $payment->form_id );
372
	if ( true === $maybe_decrease_earnings ) {
373
		// Decrease earnings.
374
		give_decrease_earnings( $payment->form_id, $payment->total );
375
	}
376
377
	$maybe_decrease_donations = apply_filters( 'give_decrease_donations_on_undo', true, $payment, $payment->form_id );
378
	if ( true === $maybe_decrease_donations ) {
379
		// Decrease donation count.
380
		give_decrease_donation_count( $payment->form_id );
381
	}
382
383
}
384
385
386
/**
387
 * Count Payments
388
 *
389
 * Returns the total number of payments recorded.
390
 *
391
 * @since  1.0
392
 *
393
 * @param  array $args Arguments passed.
394
 *
395
 * @return object $stats Contains the number of payments per payment status.
396
 */
397
function give_count_payments( $args = array() ) {
398
399
	global $wpdb;
400
	$meta_table      = __give_v20_bc_table_details( 'payment' );
401
	$donor_meta_type = Give()->donor_meta->meta_type;
402
403
	$defaults = array(
404
		'user'       => null,
405
		's'          => null,
406
		'start-date' => null,
407
		'end-date'   => null,
408
		'form_id'    => null,
409
	);
410
411
	$args = wp_parse_args( $args, $defaults );
412
413
	$select = 'SELECT p.post_status,count( * ) AS num_posts';
414
	$join   = '';
415
	$where  = "WHERE p.post_type = 'give_payment' AND p.post_status IN ('" . implode( "','", give_get_payment_status_keys() ) . "')";
416
417
	// Count payments for a specific user.
418
	if ( ! empty( $args['user'] ) ) {
419
420
		if ( is_email( $args['user'] ) ) {
421
			$field = 'email';
422
		} elseif ( is_numeric( $args['user'] ) ) {
423
			$field = 'id';
424
		} else {
425
			$field = '';
426
		}
427
428
		$join = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
429
430
		if ( ! empty( $field ) ) {
431
			$where .= "
432
				AND m.meta_key = '_give_payment_user_{$field}'
433
				AND m.meta_value = '{$args['user']}'";
434
		}
435
	} elseif ( ! empty( $args['donor'] ) ) {
436
437
		$join  = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
438
		$where .= "
439
			AND m.meta_key = '_give_payment_{$donor_meta_type}_id'
440
			AND m.meta_value = '{$args['donor']}'";
441
442
		// Count payments for a search.
443
	} elseif ( ! empty( $args['s'] ) ) {
444
445
		if ( is_email( $args['s'] ) || strlen( $args['s'] ) == 32 ) {
446
447
			if ( is_email( $args['s'] ) ) {
448
				$field = '_give_payment_donor_email';
449
			} else {
450
				$field = '_give_payment_purchase_key';
451
			}
452
453
			$join  = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
454
			$where .= $wpdb->prepare( '
455
                AND m.meta_key = %s
456
                AND m.meta_value = %s', $field, $args['s'] );
457
458
		} elseif ( '#' == substr( $args['s'], 0, 1 ) ) {
459
460
			$search = str_replace( '#:', '', $args['s'] );
461
			$search = str_replace( '#', '', $search );
462
463
			$select = 'SELECT p.post_status,count( * ) AS num_posts ';
464
			$join   = '';
465
			$where  = $wpdb->prepare( 'WHERE p.post_type=%s  AND p.ID = %d ', 'give_payment', $search );
466
467
		} elseif ( is_numeric( $args['s'] ) ) {
468
469
			$join  = "LEFT JOIN {$meta_table['column']} m ON (p.ID = m.{$meta_table['column']})";
470
			$where .= $wpdb->prepare( "
471
				AND m.meta_key = '_give_payment_donor_id'
472
				AND m.meta_value = %d", $args['s'] );
473
474
		} else {
475
			$search = $wpdb->esc_like( $args['s'] );
476
			$search = '%' . $search . '%';
477
478
			$where .= $wpdb->prepare( 'AND ((p.post_title LIKE %s) OR (p.post_content LIKE %s))', $search, $search );
479
		}// End if().
480
	}// End if().
481
482
	if ( ! empty( $args['form_id'] ) && is_numeric( $args['form_id'] ) ) {
483
484
		$join  = "LEFT JOIN {$meta_table['name']} m ON (p.ID = m.{$meta_table['column']['id']})";
485
		$where .= $wpdb->prepare( '
486
                AND m.meta_key = %s
487
                AND m.meta_value = %s', '_give_payment_form_id', $args['form_id'] );
488
	}
489
490
	// Limit payments count by date.
491
	if ( ! empty( $args['start-date'] ) && false !== strpos( $args['start-date'], '/' ) ) {
492
493
		$date_parts = explode( '/', $args['start-date'] );
494
		$month      = ! empty( $date_parts[0] ) && is_numeric( $date_parts[0] ) ? $date_parts[0] : 0;
495
		$day        = ! empty( $date_parts[1] ) && is_numeric( $date_parts[1] ) ? $date_parts[1] : 0;
496
		$year       = ! empty( $date_parts[2] ) && is_numeric( $date_parts[2] ) ? $date_parts[2] : 0;
497
498
		$is_date = checkdate( $month, $day, $year );
499 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...
500
501
			$date  = new DateTime( $args['start-date'] );
502
			$where .= $wpdb->prepare( " AND p.post_date >= '%s'", $date->format( 'Y-m-d' ) );
503
504
		}
505
506
		// Fixes an issue with the payments list table counts when no end date is specified (with stats class).
507
		if ( empty( $args['end-date'] ) ) {
508
			$args['end-date'] = $args['start-date'];
509
		}
510
	}
511
512
	if ( ! empty( $args['end-date'] ) && false !== strpos( $args['end-date'], '/' ) ) {
513
514
		$date_parts = explode( '/', $args['end-date'] );
515
516
		$month = ! empty( $date_parts[0] ) ? $date_parts[0] : 0;
517
		$day   = ! empty( $date_parts[1] ) ? $date_parts[1] : 0;
518
		$year  = ! empty( $date_parts[2] ) ? $date_parts[2] : 0;
519
520
		$is_date = checkdate( $month, $day, $year );
521 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...
522
523
			$date  = new DateTime( $args['end-date'] );
524
			$where .= $wpdb->prepare( " AND p.post_date <= '%s'", $date->format( 'Y-m-d' ) );
525
526
		}
527
	}
528
529
	$where = apply_filters( 'give_count_payments_where', $where );
530
	$join  = apply_filters( 'give_count_payments_join', $join );
531
532
	$query = "$select
533
		FROM $wpdb->posts p
534
		$join
535
		$where
536
		GROUP BY p.post_status
537
	";
538
539
	$cache_key = md5( $query );
540
541
	$count = wp_cache_get( $cache_key, 'counts' );
542
	if ( false !== $count ) {
543
		return $count;
544
	}
545
546
	$count = $wpdb->get_results( $query, ARRAY_A );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
547
548
	$stats    = array();
549
	$statuses = get_post_stati();
550
	if ( isset( $statuses['private'] ) && empty( $args['s'] ) ) {
551
		unset( $statuses['private'] );
552
	}
553
554
	foreach ( $statuses as $state ) {
555
		$stats[ $state ] = 0;
556
	}
557
558
	foreach ( (array) $count as $row ) {
559
560
		if ( 'private' == $row['post_status'] && empty( $args['s'] ) ) {
561
			continue;
562
		}
563
564
		$stats[ $row['post_status'] ] = $row['num_posts'];
565
	}
566
567
	$stats = (object) $stats;
568
	wp_cache_set( $cache_key, $stats, 'counts' );
569
570
	return $stats;
571
}
572
573
574
/**
575
 * Check For Existing Payment
576
 *
577
 * @since  1.0
578
 *
579
 * @param  int $payment_id Payment ID
580
 *
581
 * @return bool $exists True if payment exists, false otherwise.
582
 */
583
function give_check_for_existing_payment( $payment_id ) {
584
	$exists  = false;
585
	$payment = new Give_Payment( $payment_id );
586
587
	if ( $payment_id === $payment->ID && 'publish' === $payment->status ) {
588
		$exists = true;
589
	}
590
591
	return $exists;
592
}
593
594
/**
595
 * Get Payment Status
596
 *
597
 * @since 1.0
598
 *
599
 * @param WP_Post|Give_Payment|int $payment Payment object or payment ID.
600
 * @param bool $return_label Whether to return the translated status label
601
 *                                           instead of status value. Default false.
602
 *
603
 * @return bool|mixed True if payment status exists, false otherwise.
604
 */
605
function give_get_payment_status( $payment, $return_label = false ) {
606
607
	if ( is_numeric( $payment ) ) {
608
609
		$payment = new Give_Payment( $payment );
610
611
		if ( ! $payment->ID > 0 ) {
612
			return false;
613
		}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
614
615
	}
616
617
	if ( ! is_object( $payment ) || ! isset( $payment->post_status ) ) {
618
		return false;
619
	}
620
621
	$statuses = give_get_payment_statuses();
622
623
	if ( ! is_array( $statuses ) || empty( $statuses ) ) {
624
		return false;
625
	}
626
627
	// Get payment object if not already given.
628
	$payment = $payment instanceof Give_Payment ? $payment : new Give_Payment( $payment->ID );
629
630
	if ( array_key_exists( $payment->status, $statuses ) ) {
631
		if ( true === $return_label ) {
632
			// Return translated status label.
633
			return $statuses[ $payment->status ];
634
		} else {
635
			// Account that our 'publish' status is labeled 'Complete'
636
			$post_status = 'publish' == $payment->status ? 'Complete' : $payment->post_status;
637
638
			// Make sure we're matching cases, since they matter
639
			return array_search( strtolower( $post_status ), array_map( 'strtolower', $statuses ) );
640
		}
641
	}
642
643
	return false;
644
}
645
646
/**
647
 * Retrieves all available statuses for payments.
648
 *
649
 * @since  1.0
650
 *
651
 * @return array $payment_status All the available payment statuses.
652
 */
653
function give_get_payment_statuses() {
654
	$payment_statuses = array(
655
		'pending'     => __( 'Pending', 'give' ),
656
		'publish'     => __( 'Complete', 'give' ),
657
		'refunded'    => __( 'Refunded', 'give' ),
658
		'failed'      => __( 'Failed', 'give' ),
659
		'cancelled'   => __( 'Cancelled', 'give' ),
660
		'abandoned'   => __( 'Abandoned', 'give' ),
661
		'preapproval' => __( 'Pre-Approved', 'give' ),
662
		'processing'  => __( 'Processing', 'give' ),
663
		'revoked'     => __( 'Revoked', 'give' ),
664
	);
665
666
	return apply_filters( 'give_payment_statuses', $payment_statuses );
667
}
668
669
/**
670
 * Get Payment Status Keys
671
 *
672
 * Retrieves keys for all available statuses for payments
673
 *
674
 * @since  1.0
675
 *
676
 * @return array $payment_status All the available payment statuses.
677
 */
678
function give_get_payment_status_keys() {
679
	$statuses = array_keys( give_get_payment_statuses() );
680
	asort( $statuses );
681
682
	return array_values( $statuses );
683
}
684
685
/**
686
 * Get Earnings By Date
687
 *
688
 * @since  1.0
689
 *
690
 * @param  int $day Day number. Default is null.
691
 * @param  int $month_num Month number. Default is null.
692
 * @param  int $year Year number. Default is null.
693
 * @param  int $hour Hour number. Default is null.
694
 *
695
 * @return int $earnings  Earnings
696
 */
697
function give_get_earnings_by_date( $day = null, $month_num, $year = null, $hour = null ) {
698
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_earnings() method instead.
699
700
	global $wpdb;
701
	$meta_table = __give_v20_bc_table_details( 'payment' );
702
703
	$args = array(
704
		'post_type'              => 'give_payment',
705
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
706
		'year'                   => $year,
707
		'monthnum'               => $month_num,
708
		'post_status'            => array( 'publish' ),
709
		'fields'                 => 'ids',
710
		'update_post_term_cache' => false,
711
	);
712
	if ( ! empty( $day ) ) {
713
		$args['day'] = $day;
714
	}
715
716
	if ( ! empty( $hour ) ) {
717
		$args['hour'] = $hour;
718
	}
719
720
	$args = apply_filters( 'give_get_earnings_by_date_args', $args );
721
	$key  = Give_Cache::get_key( 'give_stats', $args );
722
723 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...
724
		$earnings = false;
725
	} else {
726
		$earnings = Give_Cache::get( $key );
727
	}
728
729
	if ( false === $earnings ) {
730
		$donations = get_posts( $args );
731
		$earnings  = 0;
732 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...
733
			$donations = implode( ',', $donations );
734
735
			$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...
736
737
		}
738
		// Cache the results for one hour.
739
		Give_Cache::set( $key, $earnings, HOUR_IN_SECONDS );
740
	}
741
742
	return round( $earnings, 2 );
743
}
744
745
/**
746
 * Get Donations (sales) By Date
747
 *
748
 * @since  1.0
749
 *
750
 * @param  int $day Day number. Default is null.
751
 * @param  int $month_num Month number. Default is null.
752
 * @param  int $year Year number. Default is null.
753
 * @param  int $hour Hour number. Default is null.
754
 *
755
 * @return int $count     Sales
756
 */
757
function give_get_sales_by_date( $day = null, $month_num = null, $year = null, $hour = null ) {
758
759
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_sales() method instead.
760
	$args = array(
761
		'post_type'              => 'give_payment',
762
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
763
		'year'                   => $year,
764
		'fields'                 => 'ids',
765
		'post_status'            => array( 'publish' ),
766
		'update_post_meta_cache' => false,
767
		'update_post_term_cache' => false,
768
	);
769
770
	$show_free = apply_filters( 'give_sales_by_date_show_free', true, $args );
771
772
	if ( false === $show_free ) {
773
		$args['meta_query'] = array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
774
			array(
775
				'key'     => '_give_payment_total',
776
				'value'   => 0,
777
				'compare' => '>',
778
				'type'    => 'NUMERIC',
779
			),
780
		);
781
	}
782
783
	if ( ! empty( $month_num ) ) {
784
		$args['monthnum'] = $month_num;
785
	}
786
787
	if ( ! empty( $day ) ) {
788
		$args['day'] = $day;
789
	}
790
791
	if ( ! empty( $hour ) ) {
792
		$args['hour'] = $hour;
793
	}
794
795
	$args = apply_filters( 'give_get_sales_by_date_args', $args );
796
797
	$key = Give_Cache::get_key( 'give_stats', $args );
798
799 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...
800
		$count = false;
801
	} else {
802
		$count = Give_Cache::get( $key );
803
	}
804
805
	if ( false === $count ) {
806
		$donations = new WP_Query( $args );
807
		$count     = (int) $donations->post_count;
808
		// Cache the results for one hour.
809
		Give_Cache::set( $key, $count, HOUR_IN_SECONDS );
810
	}
811
812
	return $count;
813
}
814
815
/**
816
 * Checks whether a payment has been marked as complete.
817
 *
818
 * @since  1.0
819
 *
820
 * @param  int $payment_id Payment ID to check against.
821
 *
822
 * @return bool $ret True if complete, false otherwise.
823
 */
824
function give_is_payment_complete( $payment_id ) {
825
	$payment = new Give_Payment( $payment_id );
826
827
	$ret = false;
828
829
	if ( $payment->ID > 0 ) {
830
831
		if ( (int) $payment_id === (int) $payment->ID && 'publish' == $payment->status ) {
832
			$ret = true;
833
		}
834
	}
835
836
	return apply_filters( 'give_is_payment_complete', $ret, $payment_id, $payment->post_status );
837
}
838
839
/**
840
 * Get Total Donations.
841
 *
842
 * @since  1.0
843
 *
844
 * @return int $count Total number of donations.
845
 */
846
function give_get_total_donations() {
847
848
	$payments = give_count_payments();
849
850
	return $payments->publish;
851
}
852
853
/**
854
 * Get Total Earnings
855
 *
856
 * @since  1.0
857
 *
858
 * @param bool $recalculate Recalculate earnings forcefully.
859
 *
860
 * @return float $total Total earnings.
861
 */
862
function give_get_total_earnings( $recalculate = false ) {
863
864
	$total = get_option( 'give_earnings_total', 0 );
865
	$meta_table = __give_v20_bc_table_details( 'payment' );
866
867
	// Calculate total earnings.
868
	if ( ! $total || $recalculate ) {
869
		global $wpdb;
870
871
		$total = (float) 0;
872
873
		$args = apply_filters( 'give_get_total_earnings_args', array(
874
			'offset' => 0,
875
			'number' => - 1,
876
			'status' => array( 'publish' ),
877
			'fields' => 'ids',
878
		) );
879
880
		$payments = give_get_payments( $args );
881
		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...
882
883
			/**
884
			 * If performing a donation, we need to skip the very last payment in the database,
885
			 * since it calls give_increase_total_earnings() on completion,
886
			 * which results in duplicated earnings for the very first donation.
887
			 */
888
			if ( did_action( 'give_update_payment_status' ) ) {
889
				array_pop( $payments );
890
			}
891
892 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...
893
				$payments = implode( ',', $payments );
894
				$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...
895
			}
896
		}
897
898
		update_option( 'give_earnings_total', $total, 'no' );
899
	}
900
901
	if ( $total < 0 ) {
902
		$total = 0; // Don't ever show negative earnings.
903
	}
904
905
	return apply_filters( 'give_total_earnings', round( $total, give_currency_decimal_filter() ) );
906
}
907
908
/**
909
 * Increase the Total Earnings
910
 *
911
 * @since  1.0
912
 *
913
 * @param  int $amount The amount you would like to increase the total earnings by.
914
 *                       Default is 0.
915
 *
916
 * @return float $total  Total earnings.
917
 */
918
function give_increase_total_earnings( $amount = 0 ) {
919
	$total = give_get_total_earnings();
920
	$total += $amount;
921
	update_option( 'give_earnings_total', $total );
922
923
	return $total;
924
}
925
926
/**
927
 * Decrease the Total Earnings
928
 *
929
 * @since 1.0
930
 *
931
 * @param int $amount The amount you would like to decrease the total earnings by.
932
 *
933
 * @return float $total Total earnings.
934
 */
935
function give_decrease_total_earnings( $amount = 0 ) {
936
	$total = give_get_total_earnings();
937
	$total -= $amount;
938
	if ( $total < 0 ) {
939
		$total = 0;
940
	}
941
	update_option( 'give_earnings_total', $total );
942
943
	return $total;
944
}
945
946
/**
947
 * Get Payment Meta for a specific Payment
948
 *
949
 * @since 1.0
950
 *
951
 * @param int $payment_id Payment ID.
952
 * @param string $meta_key The meta key to pull.
953
 * @param bool $single Pull single meta entry or as an object.
954
 *
955
 * @return mixed $meta Payment Meta.
956
 */
957
function give_get_payment_meta( $payment_id = 0, $meta_key = '_give_payment_meta', $single = true ) {
958
	$payment = new Give_Payment( $payment_id );
959
960
	return $payment->get_meta( $meta_key, $single );
961
}
962
963
/**
964
 * Update the meta for a payment
965
 *
966
 * @param  int $payment_id Payment ID.
967
 * @param  string $meta_key Meta key to update.
968
 * @param  string $meta_value Value to update to.
969
 * @param  string $prev_value Previous value.
970
 *
971
 * @return mixed Meta ID if successful, false if unsuccessful.
972
 */
973
function give_update_payment_meta( $payment_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
974
	$payment = new Give_Payment( $payment_id );
975
976
	return $payment->update_meta( $meta_key, $meta_value, $prev_value );
977
}
978
979
/**
980
 * Get the user_info Key from Payment Meta
981
 *
982
 * @since 1.0
983
 *
984
 * @param int $payment_id Payment ID.
985
 *
986
 * @return array $user_info User Info Meta Values.
987
 */
988
function give_get_payment_meta_user_info( $payment_id ) {
989
	$payment = new Give_Payment( $payment_id );
990
991
	return $payment->user_info;
992
}
993
994
/**
995
 * Get the donations Key from Payment Meta
996
 *
997
 * Retrieves the form_id from a (Previously titled give_get_payment_meta_donations)
998
 *
999
 * @since 1.0
1000
 *
1001
 * @param int $payment_id Payment ID.
1002
 *
1003
 * @return int $form_id Form ID.
1004
 */
1005
function give_get_payment_form_id( $payment_id ) {
1006
	$payment = new Give_Payment( $payment_id );
1007
1008
	return $payment->form_id;
1009
}
1010
1011
/**
1012
 * Get the user email associated with a payment
1013
 *
1014
 * @since 1.0
1015
 *
1016
 * @param int $payment_id Payment ID.
1017
 *
1018
 * @return string $email User email.
1019
 */
1020
function give_get_payment_user_email( $payment_id ) {
1021
	$payment = new Give_Payment( $payment_id );
1022
1023
	return $payment->email;
1024
}
1025
1026
/**
1027
 * Is the payment provided associated with a user account
1028
 *
1029
 * @since  1.3
1030
 *
1031
 * @param  int $payment_id The payment ID.
1032
 *
1033
 * @return bool $is_guest_payment If the payment is associated with a user (false) or not (true)
1034
 */
1035
function give_is_guest_payment( $payment_id ) {
1036
	$payment_user_id  = give_get_payment_user_id( $payment_id );
1037
	$is_guest_payment = ! empty( $payment_user_id ) && $payment_user_id > 0 ? false : true;
1038
1039
	return (bool) apply_filters( 'give_is_guest_payment', $is_guest_payment, $payment_id );
1040
}
1041
1042
/**
1043
 * Get the user ID associated with a payment
1044
 *
1045
 * @since 1.3
1046
 *
1047
 * @param int $payment_id Payment ID.
1048
 *
1049
 * @return int $user_id User ID.
1050
 */
1051
function give_get_payment_user_id( $payment_id ) {
1052
	$payment = new Give_Payment( $payment_id );
1053
1054
	return $payment->user_id;
1055
}
1056
1057
/**
1058
 * Get the donor ID associated with a payment.
1059
 *
1060
 * @since 1.0
1061
 *
1062
 * @param int $payment_id Payment ID.
1063
 *
1064
 * @return int $payment->customer_id Donor ID.
1065
 */
1066
function give_get_payment_donor_id( $payment_id ) {
1067
	$payment = new Give_Payment( $payment_id );
1068
1069
	return $payment->customer_id;
1070
}
1071
1072
/**
1073
 * Get the IP address used to make a donation
1074
 *
1075
 * @since 1.0
1076
 *
1077
 * @param int $payment_id Payment ID.
1078
 *
1079
 * @return string $ip User IP.
1080
 */
1081
function give_get_payment_user_ip( $payment_id ) {
1082
	$payment = new Give_Payment( $payment_id );
1083
1084
	return $payment->ip;
1085
}
1086
1087
/**
1088
 * Get the date a payment was completed
1089
 *
1090
 * @since 1.0
1091
 *
1092
 * @param int $payment_id Payment ID.
1093
 *
1094
 * @return string $date The date the payment was completed.
1095
 */
1096
function give_get_payment_completed_date( $payment_id = 0 ) {
1097
	$payment = new Give_Payment( $payment_id );
1098
1099
	return $payment->completed_date;
1100
}
1101
1102
/**
1103
 * Get the gateway associated with a payment
1104
 *
1105
 * @since 1.0
1106
 *
1107
 * @param int $payment_id Payment ID.
1108
 *
1109
 * @return string $gateway Gateway.
1110
 */
1111
function give_get_payment_gateway( $payment_id ) {
1112
	$payment = new Give_Payment( $payment_id );
1113
1114
	return $payment->gateway;
1115
}
1116
1117
/**
1118
 * Get the currency code a payment was made in
1119
 *
1120
 * @since 1.0
1121
 *
1122
 * @param int $payment_id Payment ID.
1123
 *
1124
 * @return string $currency The currency code.
1125
 */
1126
function give_get_payment_currency_code( $payment_id = 0 ) {
1127
	$payment = new Give_Payment( $payment_id );
1128
1129
	return $payment->currency;
1130
}
1131
1132
/**
1133
 * Get the currency name a payment was made in
1134
 *
1135
 * @since 1.0
1136
 *
1137
 * @param int $payment_id Payment ID.
1138
 *
1139
 * @return string $currency The currency name.
1140
 */
1141
function give_get_payment_currency( $payment_id = 0 ) {
1142
	$currency = give_get_payment_currency_code( $payment_id );
1143
1144
	return apply_filters( 'give_payment_currency', give_get_currency_name( $currency ), $payment_id );
1145
}
1146
1147
/**
1148
 * Get the key for a donation
1149
 *
1150
 * @since 1.0
1151
 *
1152
 * @param int $payment_id Payment ID.
1153
 *
1154
 * @return string $key Donation key.
1155
 */
1156
function give_get_payment_key( $payment_id = 0 ) {
1157
	$payment = new Give_Payment( $payment_id );
1158
1159
	return $payment->key;
1160
}
1161
1162
/**
1163
 * Get the payment order number
1164
 *
1165
 * This will return the payment ID if sequential order numbers are not enabled or the order number does not exist
1166
 *
1167
 * @since 1.0
1168
 *
1169
 * @param int $payment_id Payment ID.
1170
 *
1171
 * @return string $number Payment order number.
1172
 */
1173
function give_get_payment_number( $payment_id = 0 ) {
1174
	$payment = new Give_Payment( $payment_id );
1175
1176
	return $payment->number;
1177
}
1178
1179
/**
1180
 * Formats the payment number with the prefix and postfix
1181
 *
1182
 * @since  1.3
1183
 *
1184
 * @param  int $number The payment number to format.
1185
 *
1186
 * @return string      The formatted payment number.
1187
 */
1188
function give_format_payment_number( $number ) {
1189
1190
	if ( ! give_get_option( 'enable_sequential' ) ) {
1191
		return $number;
1192
	}
1193
1194
	if ( ! is_numeric( $number ) ) {
1195
		return $number;
1196
	}
1197
1198
	$prefix  = give_get_option( 'sequential_prefix' );
1199
	$number  = absint( $number );
1200
	$postfix = give_get_option( 'sequential_postfix' );
1201
1202
	$formatted_number = $prefix . $number . $postfix;
1203
1204
	return apply_filters( 'give_format_payment_number', $formatted_number, $prefix, $number, $postfix );
1205
}
1206
1207
/**
1208
 * Gets the next available order number
1209
 *
1210
 * This is used when inserting a new payment
1211
 *
1212
 * @since 1.0
1213
 * @return string $number The next available payment number.
1214
 */
1215
function give_get_next_payment_number() {
1216
1217
	if ( ! give_get_option( 'enable_sequential' ) ) {
1218
		return false;
1219
	}
1220
1221
	$number           = get_option( 'give_last_payment_number' );
1222
	$start            = give_get_option( 'sequential_start', 1 );
1223
	$increment_number = true;
1224
1225
	if ( false !== $number ) {
1226
1227
		if ( empty( $number ) ) {
1228
1229
			$number           = $start;
1230
			$increment_number = false;
1231
1232
		}
1233
	} else {
1234
1235
		// This case handles the first addition of the new option, as well as if it get's deleted for any reason.
1236
		$payments     = new Give_Payments_Query( array(
1237
			'number'  => 1,
1238
			'order'   => 'DESC',
1239
			'orderby' => 'ID',
1240
			'output'  => 'posts',
1241
			'fields'  => 'ids',
1242
		) );
1243
		$last_payment = $payments->get_payments();
1244
1245
		if ( ! empty( $last_payment ) ) {
1246
1247
			$number = give_get_payment_number( $last_payment[0] );
1248
1249
		}
1250
1251
		if ( ! empty( $number ) && $number !== (int) $last_payment[0] ) {
1252
1253
			$number = give_remove_payment_prefix_postfix( $number );
1254
1255
		} else {
1256
1257
			$number           = $start;
1258
			$increment_number = false;
1259
		}
1260
	}// End if().
1261
1262
	$increment_number = apply_filters( 'give_increment_payment_number', $increment_number, $number );
1263
1264
	if ( $increment_number ) {
1265
		$number ++;
1266
	}
1267
1268
	return apply_filters( 'give_get_next_payment_number', $number );
1269
}
1270
1271
/**
1272
 * Given a given a number, remove the pre/postfix
1273
 *
1274
 * @since  1.3
1275
 *
1276
 * @param  string $number The formatted Current Number to increment.
1277
 *
1278
 * @return string The new Payment number without prefix and postfix.
1279
 */
1280
function give_remove_payment_prefix_postfix( $number ) {
1281
1282
	$prefix  = give_get_option( 'sequential_prefix' );
1283
	$postfix = give_get_option( 'sequential_postfix' );
1284
1285
	// Remove prefix.
1286
	$number = preg_replace( '/' . $prefix . '/', '', $number, 1 );
1287
1288
	// Remove the postfix.
1289
	$length      = strlen( $number );
1290
	$postfix_pos = strrpos( $number, $postfix );
1291
	if ( false !== $postfix_pos ) {
1292
		$number = substr_replace( $number, '', $postfix_pos, $length );
1293
	}
1294
1295
	// Ensure it's a whole number.
1296
	$number = intval( $number );
1297
1298
	return apply_filters( 'give_remove_payment_prefix_postfix', $number, $prefix, $postfix );
1299
1300
}
1301
1302
1303
/**
1304
 * Get Payment Amount
1305
 *
1306
 * Get the fully formatted payment amount. The payment amount is retrieved using give_get_payment_amount() and is then
1307
 * sent through give_currency_filter() and  give_format_amount() to format the amount correctly.
1308
 *
1309
 * @since       1.0
1310
 *
1311
 * @param int $payment_id Payment ID.
1312
 *
1313
 * @return string $amount Fully formatted payment amount.
1314
 */
1315
function give_payment_amount( $payment_id = 0 ) {
1316
	$amount = give_get_payment_amount( $payment_id );
1317
1318
	return give_currency_filter( give_format_amount( $amount, array( 'sanitize' => false ) ), give_get_payment_currency_code( $payment_id ) );
1319
}
1320
1321
/**
1322
 * Get the amount associated with a payment
1323
 *
1324
 * @access public
1325
 * @since  1.0
1326
 *
1327
 * @param int $payment_id Payment ID.
1328
 *
1329
 * @return mixed
1330
 */
1331
function give_get_payment_amount( $payment_id ) {
1332
1333
	$payment = new Give_Payment( $payment_id );
1334
1335
	return apply_filters( 'give_payment_amount', floatval( $payment->total ), $payment_id );
1336
}
1337
1338
/**
1339
 * Payment Subtotal
1340
 *
1341
 * Retrieves subtotal for payment and then returns a full formatted amount. This
1342
 * function essentially calls give_get_payment_subtotal()
1343
 *
1344
 * @since 1.5
1345
 *
1346
 * @param int $payment_id Payment ID.
1347
 *
1348
 * @see   give_get_payment_subtotal()
1349
 *
1350
 * @return array Fully formatted payment subtotal.
1351
 */
1352
function give_payment_subtotal( $payment_id = 0 ) {
1353
	$subtotal = give_get_payment_subtotal( $payment_id );
1354
1355
	return give_currency_filter( give_format_amount( $subtotal, array( 'sanitize' => false ) ), give_get_payment_currency_code( $payment_id ) );
1356
}
1357
1358
/**
1359
 * Get Payment Subtotal
1360
 *
1361
 * Retrieves subtotal for payment and then returns a non formatted amount.
1362
 *
1363
 * @since 1.5
1364
 *
1365
 * @param int $payment_id Payment ID.
1366
 *
1367
 * @return float $subtotal Subtotal for payment (non formatted).
1368
 */
1369
function give_get_payment_subtotal( $payment_id = 0 ) {
1370
	$payment = new Give_Payment( $payment_id );
1371
1372
	return $payment->subtotal;
1373
}
1374
1375
/**
1376
 * Retrieves the donation ID
1377
 *
1378
 * @since  1.0
1379
 *
1380
 * @param int $payment_id Payment ID.
1381
 *
1382
 * @return string The donation ID.
1383
 */
1384
function give_get_payment_transaction_id( $payment_id = 0 ) {
1385
	$payment = new Give_Payment( $payment_id );
1386
1387
	return $payment->transaction_id;
1388
}
1389
1390
/**
1391
 * Sets a Transaction ID in post meta for the given Payment ID.
1392
 *
1393
 * @since  1.0
1394
 *
1395
 * @param int $payment_id Payment ID.
1396
 * @param string $transaction_id The transaction ID from the gateway.
1397
 *
1398
 * @return bool|mixed
1399
 */
1400
function give_set_payment_transaction_id( $payment_id = 0, $transaction_id = '' ) {
1401
1402
	if ( empty( $payment_id ) || empty( $transaction_id ) ) {
1403
		return false;
1404
	}
1405
1406
	$transaction_id = apply_filters( 'give_set_payment_transaction_id', $transaction_id, $payment_id );
1407
1408
	return give_update_payment_meta( $payment_id, '_give_payment_transaction_id', $transaction_id );
1409
}
1410
1411
/**
1412
 * Retrieve the donation ID based on the key
1413
 *
1414
 * @since 1.0
1415
 * @global object $wpdb Used to query the database using the WordPress Database API.
1416
 *
1417
 * @param string $key the key to search for.
1418
 *
1419
 * @return int $purchase Donation ID.
1420
 */
1421 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...
1422
	global $wpdb;
1423
	$meta_table = __give_v20_bc_table_details( 'payment' );
1424
1425
	$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...
1426
1427
	if ( $purchase != null ) {
1428
		return $purchase;
1429
	}
1430
1431
	return 0;
1432
}
1433
1434
1435
/**
1436
 * Retrieve the donation ID based on the transaction ID
1437
 *
1438
 * @since 1.3
1439
 * @global object $wpdb Used to query the database using the WordPress Database API.
1440
 *
1441
 * @param string $key The transaction ID to search for.
1442
 *
1443
 * @return int $purchase Donation ID.
1444
 */
1445 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...
1446
	global $wpdb;
1447
	$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...
1448
1449
	$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...
1450
1451
	if ( $purchase != null ) {
1452
		return $purchase;
1453
	}
1454
1455
	return 0;
1456
}
1457
1458
/**
1459
 * Retrieve all notes attached to a donation
1460
 *
1461
 * @since 1.0
1462
 *
1463
 * @param int $payment_id The donation ID to retrieve notes for.
1464
 * @param string $search Search for notes that contain a search term.
1465
 *
1466
 * @return array $notes Donation Notes
1467
 */
1468
function give_get_payment_notes( $payment_id = 0, $search = '' ) {
1469
1470
	if ( empty( $payment_id ) && empty( $search ) ) {
1471
		return false;
1472
	}
1473
1474
	remove_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1475
	remove_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10 );
1476
1477
	$notes = get_comments( array(
1478
		'post_id' => $payment_id,
1479
		'order'   => 'ASC',
1480
		'search'  => $search,
1481
	) );
1482
1483
	add_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1484
	add_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10, 2 );
1485
1486
	return $notes;
1487
}
1488
1489
1490
/**
1491
 * Add a note to a payment
1492
 *
1493
 * @since 1.0
1494
 *
1495
 * @param int $payment_id The payment ID to store a note for.
1496
 * @param string $note The note to store.
1497
 *
1498
 * @return int The new note ID
1499
 */
1500
function give_insert_payment_note( $payment_id = 0, $note = '' ) {
1501
	if ( empty( $payment_id ) ) {
1502
		return false;
1503
	}
1504
1505
	/**
1506
	 * Fires before inserting payment note.
1507
	 *
1508
	 * @since 1.0
1509
	 *
1510
	 * @param int $payment_id Payment ID.
1511
	 * @param string $note The note.
1512
	 */
1513
	do_action( 'give_pre_insert_payment_note', $payment_id, $note );
1514
1515
	$note_id = wp_insert_comment( wp_filter_comment( array(
1516
		'comment_post_ID'      => $payment_id,
1517
		'comment_content'      => $note,
1518
		'user_id'              => is_admin() ? get_current_user_id() : 0,
1519
		'comment_date'         => current_time( 'mysql' ),
1520
		'comment_date_gmt'     => current_time( 'mysql', 1 ),
1521
		'comment_approved'     => 1,
1522
		'comment_parent'       => 0,
1523
		'comment_author'       => '',
1524
		'comment_author_IP'    => '',
1525
		'comment_author_url'   => '',
1526
		'comment_author_email' => '',
1527
		'comment_type'         => 'give_payment_note',
1528
1529
	) ) );
1530
1531
	/**
1532
	 * Fires after payment note inserted.
1533
	 *
1534
	 * @since 1.0
1535
	 *
1536
	 * @param int $note_id Note ID.
1537
	 * @param int $payment_id Payment ID.
1538
	 * @param string $note The note.
1539
	 */
1540
	do_action( 'give_insert_payment_note', $note_id, $payment_id, $note );
1541
1542
	return $note_id;
1543
}
1544
1545
/**
1546
 * Deletes a payment note
1547
 *
1548
 * @since 1.0
1549
 *
1550
 * @param int $comment_id The comment ID to delete.
1551
 * @param int $payment_id The payment ID the note is connected to.
1552
 *
1553
 * @return bool True on success, false otherwise.
1554
 */
1555
function give_delete_payment_note( $comment_id = 0, $payment_id = 0 ) {
1556
	if ( empty( $comment_id ) ) {
1557
		return false;
1558
	}
1559
1560
	/**
1561
	 * Fires before deleting donation note.
1562
	 *
1563
	 * @since 1.0
1564
	 *
1565
	 * @param int $comment_id Note ID.
1566
	 * @param int $payment_id Payment ID.
1567
	 */
1568
	do_action( 'give_pre_delete_payment_note', $comment_id, $payment_id );
1569
1570
	$ret = wp_delete_comment( $comment_id, true );
1571
1572
	/**
1573
	 * Fires after donation note deleted.
1574
	 *
1575
	 * @since 1.0
1576
	 *
1577
	 * @param int $comment_id Note ID.
1578
	 * @param int $payment_id Payment ID.
1579
	 */
1580
	do_action( 'give_post_delete_payment_note', $comment_id, $payment_id );
1581
1582
	return $ret;
1583
}
1584
1585
/**
1586
 * Gets the payment note HTML
1587
 *
1588
 * @since 1.0
1589
 *
1590
 * @param object|int $note The comment object or ID.
1591
 * @param int $payment_id The payment ID the note is connected to.
1592
 *
1593
 * @return string
1594
 */
1595
function give_get_payment_note_html( $note, $payment_id = 0 ) {
1596
1597
	if ( is_numeric( $note ) ) {
1598
		$note = get_comment( $note );
1599
	}
1600
1601
	if ( ! empty( $note->user_id ) ) {
1602
		$user = get_userdata( $note->user_id );
1603
		$user = $user->display_name;
1604
	} else {
1605
		$user = esc_html__( 'System', 'give' );
1606
	}
1607
1608
	$date_format = give_date_format() . ', ' . get_option( 'time_format' );
1609
1610
	$delete_note_url = wp_nonce_url( add_query_arg( array(
1611
		'give-action' => 'delete_payment_note',
1612
		'note_id'     => $note->comment_ID,
1613
		'payment_id'  => $payment_id,
1614
	) ), 'give_delete_payment_note_' . $note->comment_ID );
1615
1616
	$note_html = '<div class="give-payment-note" id="give-payment-note-' . $note->comment_ID . '">';
1617
	$note_html .= '<p>';
1618
	$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/>';
1619
	$note_html .= $note->comment_content;
1620
	$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="' . esc_attr__( 'Delete this donation note.', 'give' ) . '">' . esc_html__( 'Delete', 'give' ) . '</a>';
1621
	$note_html .= '</p>';
1622
	$note_html .= '</div>';
1623
1624
	return $note_html;
1625
1626
}
1627
1628
/**
1629
 * Exclude notes (comments) on give_payment post type from showing in Recent
1630
 * Comments widgets
1631
 *
1632
 * @since 1.0
1633
 *
1634
 * @param object $query WordPress Comment Query Object.
1635
 *
1636
 * @return void
1637
 */
1638
function give_hide_payment_notes( $query ) {
1639
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.1', '>=' ) ) {
1640
		$types = isset( $query->query_vars['type__not_in'] ) ? $query->query_vars['type__not_in'] : array();
1641
		if ( ! is_array( $types ) ) {
1642
			$types = array( $types );
1643
		}
1644
		$types[]                           = 'give_payment_note';
1645
		$query->query_vars['type__not_in'] = $types;
1646
	}
1647
}
1648
1649
add_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1650
1651
/**
1652
 * Exclude notes (comments) on give_payment post type from showing in Recent Comments widgets
1653
 *
1654
 * @since 1.0
1655
 *
1656
 * @param array $clauses Comment clauses for comment query.
1657
 * @param object $wp_comment_query WordPress Comment Query Object.
1658
 *
1659
 * @return array $clauses Updated comment clauses.
1660
 */
1661
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...
1662
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.1', '<' ) ) {
1663
		$clauses['where'] .= ' AND comment_type != "give_payment_note"';
1664
	}
1665
1666
	return $clauses;
1667
}
1668
1669
add_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10, 2 );
1670
1671
1672
/**
1673
 * Exclude notes (comments) on give_payment post type from showing in comment feeds
1674
 *
1675
 * @since 1.0
1676
 *
1677
 * @param string $where
1678
 * @param object $wp_comment_query WordPress Comment Query Object.
1679
 *
1680
 * @return string $where
1681
 */
1682
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...
1683
	global $wpdb;
1684
1685
	$where .= $wpdb->prepare( ' AND comment_type != %s', 'give_payment_note' );
1686
1687
	return $where;
1688
}
1689
1690
add_filter( 'comment_feed_where', 'give_hide_payment_notes_from_feeds', 10, 2 );
1691
1692
1693
/**
1694
 * Remove Give Comments from the wp_count_comments function
1695
 *
1696
 * @access public
1697
 * @since  1.0
1698
 *
1699
 * @param array $stats (empty from core filter).
1700
 * @param int $post_id Post ID.
1701
 *
1702
 * @return array Array of comment counts.
1703
 */
1704
function give_remove_payment_notes_in_comment_counts( $stats, $post_id ) {
1705
	global $wpdb, $pagenow;
1706
1707
	if ( 'index.php' != $pagenow ) {
1708
		return $stats;
1709
	}
1710
1711
	$post_id = (int) $post_id;
1712
1713
	if ( apply_filters( 'give_count_payment_notes_in_comments', false ) ) {
1714
		return $stats;
1715
	}
1716
1717
	$stats = wp_cache_get( "comments-{$post_id}", 'counts' );
1718
1719
	if ( false !== $stats ) {
1720
		return $stats;
1721
	}
1722
1723
	$where = 'WHERE comment_type != "give_payment_note"';
1724
1725
	if ( $post_id > 0 ) {
1726
		$where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id );
1727
	}
1728
1729
	$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...
1730
1731
	$total    = 0;
1732
	$approved = array(
1733
		'0'            => 'moderated',
0 ignored issues
show
introduced by
Detected usage of 0, possible slow query.
Loading history...
1734
		'1'            => 'approved',
1735
		'spam'         => 'spam',
1736
		'trash'        => 'trash',
1737
		'post-trashed' => 'post-trashed',
1738
	);
1739
	foreach ( (array) $count as $row ) {
1740
		// Don't count post-trashed toward totals.
1741
		if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
1742
			$total += $row['num_comments'];
1743
		}
1744
		if ( isset( $approved[ $row['comment_approved'] ] ) ) {
1745
			$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
1746
		}
1747
	}
1748
1749
	$stats['total_comments'] = $total;
1750
	foreach ( $approved as $key ) {
1751
		if ( empty( $stats[ $key ] ) ) {
1752
			$stats[ $key ] = 0;
1753
		}
1754
	}
1755
1756
	$stats = (object) $stats;
1757
	wp_cache_set( "comments-{$post_id}", $stats, 'counts' );
1758
1759
	return $stats;
1760
}
1761
1762
add_filter( 'wp_count_comments', 'give_remove_payment_notes_in_comment_counts', 10, 2 );
1763
1764
1765
/**
1766
 * Filter where older than one week
1767
 *
1768
 * @access public
1769
 * @since  1.0
1770
 *
1771
 * @param string $where Where clause.
1772
 *
1773
 * @return string $where Modified where clause.
1774
 */
1775
function give_filter_where_older_than_week( $where = '' ) {
1776
	// Payments older than one week.
1777
	$start = date( 'Y-m-d', strtotime( '-7 days' ) );
1778
	$where .= " AND post_date <= '{$start}'";
1779
1780
	return $where;
1781
}
1782
1783
1784
/**
1785
 * Get Payment Form ID.
1786
 *
1787
 * Retrieves the form title and appends the level name if present.
1788
 *
1789
 * @since 1.5
1790
 *
1791
 * @param array $payment_meta Payment meta data.
1792
 * @param bool $only_level If set to true will only return the level name if multi-level enabled.
1793
 * @param string $separator The separator between the .
1794
 *
1795
 * @return string $form_title Returns the full title if $only_level is false, otherwise returns the levels title.
1796
 */
1797
function give_get_payment_form_title( $payment_meta, $only_level = false, $separator = '' ) {
1798
1799
	$form_id    = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : 0;
1800
	$price_id   = isset( $payment_meta['price_id'] ) ? $payment_meta['price_id'] : null;
1801
	$form_title = isset( $payment_meta['form_title'] ) ? $payment_meta['form_title'] : '';
1802
1803
	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...
1804
		$form_title = '';
1805
	}
1806
1807
	// If multi-level, append to the form title.
1808
	if ( give_has_variable_prices( $form_id ) ) {
1809
1810
		// Only add separator if there is a form title.
1811
		if ( ! empty( $form_title ) ) {
1812
			$form_title .= ' ' . $separator . ' ';
1813
		}
1814
1815
		$form_title .= '<span class="donation-level-text-wrap">';
1816
1817
		if ( $price_id == 'custom' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
1818
			$custom_amount_text = give_get_meta( $form_id, '_give_custom_amount_text', true );
1819
			$form_title         .= ! empty( $custom_amount_text ) ? $custom_amount_text : __( 'Custom Amount', 'give' );
1820
		} else {
1821
			$form_title .= give_get_price_option_name( $form_id, $price_id );
1822
		}
1823
1824
		$form_title .= '</span>';
1825
1826
	}
1827
1828
	return apply_filters( 'give_get_payment_form_title', $form_title, $payment_meta );
1829
1830
}
1831
1832
/**
1833
 * Get Price ID
1834
 *
1835
 * Retrieves the Price ID when provided a proper form ID and price (donation) total
1836
 *
1837
 * @param int $form_id Form ID.
1838
 * @param string $price Price ID.
1839
 *
1840
 * @return string $price_id
1841
 */
1842
function give_get_price_id( $form_id, $price ) {
1843
	$price_id = null;
1844
1845
	if ( give_has_variable_prices( $form_id ) ) {
1846
1847
		$levels = give_get_meta( $form_id, '_give_donation_levels', true );
1848
1849
		foreach ( $levels as $level ) {
1850
1851
			$level_amount = give_maybe_sanitize_amount( $level['_give_amount'] );
1852
1853
			// Check that this indeed the recurring price.
1854
			if ( $level_amount == $price ) {
1855
1856
				$price_id = $level['_give_id']['level_id'];
1857
				break;
1858
1859
			}
1860
		}
1861
1862
		if( is_null( $price_id ) && give_is_custom_price_mode( $form_id ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1863
			$price_id = 'custom';
1864
		}
1865
	}
1866
1867
	// Price ID must be numeric or string.
1868
	$price_id = ! is_numeric( $price_id ) && ! is_string( $price_id ) ? 0 : $price_id;
1869
1870
	return $price_id;
1871
}
1872
1873
/**
1874
 * Get/Print give form dropdown html
1875
 *
1876
 * This function is wrapper to public method forms_dropdown of Give_HTML_Elements class to get/print form dropdown html.
1877
 * Give_HTML_Elements is defined in includes/class-give-html-elements.php.
1878
 *
1879
 * @since 1.6
1880
 *
1881
 * @param array $args Arguments for form dropdown.
1882
 * @param bool $echo This parameter decides if print form dropdown html output or not.
1883
 *
1884
 * @return string
1885
 */
1886
function give_get_form_dropdown( $args = array(), $echo = false ) {
1887
	$form_dropdown_html = Give()->html->forms_dropdown( $args );
1888
1889
	if ( ! $echo ) {
1890
		return $form_dropdown_html;
1891
	}
1892
1893
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1894
}
1895
1896
/**
1897
 * Get/Print give form variable price dropdown html
1898
 *
1899
 * @since 1.6
1900
 *
1901
 * @param array $args Arguments for form dropdown.
1902
 * @param bool $echo This parameter decide if print form dropdown html output or not.
1903
 *
1904
 * @return string|bool
1905
 */
1906
function give_get_form_variable_price_dropdown( $args = array(), $echo = false ) {
1907
1908
	// Check for give form id.
1909
	if ( empty( $args['id'] ) ) {
1910
		return false;
1911
	}
1912
1913
	$form = new Give_Donate_Form( $args['id'] );
1914
1915
	// Check if form has variable prices or not.
1916
	if ( ! $form->ID || ! $form->has_variable_prices() ) {
1917
		return false;
1918
	}
1919
1920
	$variable_prices        = $form->get_prices();
1921
	$variable_price_options = array();
1922
1923
	// Check if multi donation form support custom donation or not.
1924
	if ( $form->is_custom_price_mode() ) {
1925
		$variable_price_options['custom'] = _x( 'Custom', 'custom donation dropdown item', 'give' );
1926
	}
1927
1928
	// Get variable price and ID from variable price array.
1929
	foreach ( $variable_prices as $variable_price ) {
1930
		$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 ) ) );
1931
	}
1932
1933
	// Update options.
1934
	$args = array_merge( $args, array(
1935
		'options' => $variable_price_options,
1936
	) );
1937
1938
	// Generate select html.
1939
	$form_dropdown_html = Give()->html->select( $args );
1940
1941
	if ( ! $echo ) {
1942
		return $form_dropdown_html;
1943
	}
1944
1945
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1946
}
1947
1948
/**
1949
 * Get the price_id from the payment meta.
1950
 *
1951
 * Some gateways use `give_price_id` and others were using just `price_id`;
1952
 * This checks for the difference and falls back to retrieving it from the form as a last resort.
1953
 *
1954
 * @since 1.8.6
1955
 *
1956
 * @param $payment_meta
1957
 *
1958
 * @return string
1959
 */
1960
function give_get_payment_meta_price_id( $payment_meta ) {
1961
1962
	if ( isset( $payment_meta['give_price_id'] ) ) {
1963
		$price_id = $payment_meta['give_price_id'];
1964
	} elseif ( isset( $payment_meta['price_id'] ) ) {
1965
		$price_id = $payment_meta['price_id'];
1966
	} else {
1967
		$price_id = give_get_price_id( $payment_meta['give_form_id'], $payment_meta['price'] );
1968
	}
1969
1970
	return apply_filters( 'give_get_payment_meta_price_id', $price_id );
1971
1972
}
1973