Test Failed
Pull Request — master (#1972)
by Ravinder
05:01
created

functions.php ➔ give_get_payment_status()   C

Complexity

Conditions 11
Paths 21

Size

Total Lines 40
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
cc 11
eloc 18
nc 21
nop 2
dl 0
loc 40
ccs 0
cts 20
cp 0
crap 132
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

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