Test Failed
Push — issues/1944 ( 5c19d0...2ded50 )
by Ravinder
04:30
created

functions.php ➔ give_count_payments()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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

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

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

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

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

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

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

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

Loading history...
111
				$payment = new Give_Payment( $payment[0] );
112
			}
113
114
			break;
115
116
		default:
117
			return false;
118
	}// End switch().
119
120
	if ( $payment ) {
121
		return $payment;
122
	}
123
124
	return false;
125
}
126
127
/**
128
 * Insert Payment
129
 *
130
 * @since  1.0
131
 *
132
 * @param  array $payment_data Arguments passed.
133
 *
134
 * @return int|bool Payment ID if payment is inserted, false otherwise.
135
 */
136
function give_insert_payment( $payment_data = array() ) {
137
138
	if ( empty( $payment_data ) ) {
139
		return false;
140
	}
141
142
	/**
143
	 * Fire the filter on donation data before insert.
144
	 *
145
	 * @since 1.8.15
146
	 *
147
	 * @param array $payment_data Arguments passed.
148
	 */
149
	$payment_data = apply_filters( 'give_pre_insert_payment', $payment_data );
150
151
	$payment    = new Give_Payment();
152
	$gateway    = ! empty( $payment_data['gateway'] ) ? $payment_data['gateway'] : '';
153
	$gateway    = empty( $gateway ) && isset( $_POST['give-gateway'] ) ? $_POST['give-gateway'] : $gateway;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
154
	$form_id    = isset( $payment_data['give_form_id'] ) ? $payment_data['give_form_id'] : 0;
155
	$price_id   = give_get_payment_meta_price_id( $payment_data );
156
	$form_title = isset( $payment_data['give_form_title'] ) ? $payment_data['give_form_title'] : get_the_title( $form_id );
157
158
	// Set properties.
159
	$payment->total          = $payment_data['price'];
160
	$payment->status         = ! empty( $payment_data['status'] ) ? $payment_data['status'] : 'pending';
161
	$payment->currency       = ! empty( $payment_data['currency'] ) ? $payment_data['currency'] : give_get_currency( $payment_data['give_form_id'], $payment_data );
162
	$payment->user_info      = $payment_data['user_info'];
163
	$payment->gateway        = $gateway;
164
	$payment->form_title     = $form_title;
165
	$payment->form_id        = $form_id;
166
	$payment->price_id       = $price_id;
167
	$payment->donor_id       = ( ! empty( $payment_data['donor_id'] ) ? $payment_data['donor_id'] : '' );
168
	$payment->user_id        = $payment_data['user_info']['id'];
169
	$payment->email          = $payment_data['user_email'];
170
	$payment->first_name     = $payment_data['user_info']['first_name'];
171
	$payment->last_name      = $payment_data['user_info']['last_name'];
172
	$payment->email          = $payment_data['user_info']['email'];
173
	$payment->ip             = give_get_ip();
174
	$payment->key            = $payment_data['purchase_key'];
175
	$payment->mode           = ( ! empty( $payment_data['mode'] ) ? (string) $payment_data['mode'] : ( give_is_test_mode() ? 'test' : 'live' ) );
176
	$payment->parent_payment = ! empty( $payment_data['parent'] ) ? absint( $payment_data['parent'] ) : '';
177
178
	// Add the donation.
179
	$args = array(
180
		'price'    => $payment->total,
181
		'price_id' => $payment->price_id,
182
	);
183
184
	$payment->add_donation( $payment->form_id, $args );
185
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
186
187
	// Set date if present.
188
	if ( isset( $payment_data['post_date'] ) ) {
189
		$payment->date = $payment_data['post_date'];
190
	}
191
192
	// Handle sequential payments.
193
	if ( give_get_option( 'enable_sequential' ) ) {
194
		$number          = give_get_next_payment_number();
195
		$payment->number = give_format_payment_number( $number );
196
		update_option( 'give_last_payment_number', $number );
197
	}
198
199
	// Save payment.
200
	$payment->save();
201
202
	/**
203
	 * Fires while inserting payments.
204
	 *
205
	 * @since 1.0
206
	 *
207
	 * @param int   $payment_id   The payment ID.
208
	 * @param array $payment_data Arguments passed.
209
	 */
210
	do_action( 'give_insert_payment', $payment->ID, $payment_data );
211
212
	// Return payment ID upon success.
213
	if ( ! empty( $payment->ID ) ) {
214
		return $payment->ID;
215
	}
216
217
	// Return false if no payment was inserted.
218
	return false;
219
220
}
221
222
/**
223
 * Create payment.
224
 *
225
 * @param $payment_data
226
 *
227
 * @return bool|int
228
 */
229
function give_create_payment( $payment_data ) {
230
231
	$form_id  = intval( $payment_data['post_data']['give-form-id'] );
232
	$price_id = isset( $payment_data['post_data']['give-price-id'] ) ? $payment_data['post_data']['give-price-id'] : '';
233
234
	// Collect payment data.
235
	$insert_payment_data = array(
236
		'price'           => $payment_data['price'],
237
		'give_form_title' => $payment_data['post_data']['give-form-title'],
238
		'give_form_id'    => $form_id,
239
		'give_price_id'   => $price_id,
240
		'date'            => $payment_data['date'],
241
		'user_email'      => $payment_data['user_email'],
242
		'purchase_key'    => $payment_data['purchase_key'],
243
		'currency'        => give_get_currency( $form_id, $payment_data ),
244
		'user_info'       => $payment_data['user_info'],
245
		'status'          => 'pending',
246
		'gateway'         => 'paypal',
247
	);
248
249
	/**
250
	 * Filter the payment params.
251
	 *
252
	 * @since 1.8
253
	 *
254
	 * @param array $insert_payment_data
255
	 */
256
	$insert_payment_data = apply_filters( 'give_create_payment', $insert_payment_data );
257
258
	// Record the pending payment.
259
	return give_insert_payment( $insert_payment_data );
260
}
261
262
/**
263
 * Updates a payment status.
264
 *
265
 * @param  int    $payment_id Payment ID.
266
 * @param  string $new_status New Payment Status. Default is 'publish'.
267
 *
268
 * @since  1.0
269
 *
270
 * @return bool
271
 */
272
function give_update_payment_status( $payment_id, $new_status = 'publish' ) {
273
274
	$updated = false;
275
	$payment = new Give_Payment( $payment_id );
276
277
	if ( $payment && $payment->ID > 0 ) {
278
279
		$payment->status = $new_status;
280
		$updated         = $payment->save();
281
282
	}
283
284
	return $updated;
285
}
286
287
288
/**
289
 * Deletes a Donation
290
 *
291
 * @since  1.0
292
 *
293
 * @param  int  $payment_id   Payment ID (default: 0).
294
 * @param  bool $update_donor If we should update the donor stats (default:true).
295
 *
296
 * @return void
297
 */
298
function give_delete_donation( $payment_id = 0, $update_donor = true ) {
299
	$payment = new Give_Payment( $payment_id );
300
301
	// Bailout.
302
	if( ! $payment->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...
303
		return;
304
	}
305
306
	$amount   = give_get_payment_amount( $payment_id );
307
	$status   = $payment->post_status;
308
	$donor_id = give_get_payment_donor_id( $payment_id );
309
	$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...
310
311
	// Only undo donations that aren't these statuses.
312
	$dont_undo_statuses = apply_filters( 'give_undo_donation_statuses', array(
313
		'pending',
314
		'cancelled',
315
	) );
316
317
	if ( ! in_array( $status, $dont_undo_statuses ) ) {
318
		give_undo_donation( $payment_id );
319
	}
320
321
	// Only undo donations that aren't these statuses.
322
	$status_to_decrease_stats = apply_filters( 'give_decrease_donor_statuses', array( 'publish' ) );
323
324
	if ( in_array( $status, $status_to_decrease_stats ) ) {
325
326
		// Only decrease earnings if they haven't already been decreased (or were never increased for this payment).
327
		give_decrease_total_earnings( $amount );
328
329
		// @todo: Refresh only range related stat cache
330
		give_delete_donation_stats();
331
332
		if ( $donor->id && $update_donor ) {
333
334
			// Decrement the stats for the donor.
335
			$donor->decrease_donation_count();
336
			$donor->decrease_value( $amount );
337
338
		}
339
	}
340
341
	/**
342
	 * Fires before deleting payment.
343
	 *
344
	 * @param int $payment_id Payment ID.
345
	 *
346
	 * @since 1.0
347
	 */
348
	do_action( 'give_payment_delete', $payment_id );
349
350
	if ( $donor->id && $update_donor ) {
351
		// Remove the payment ID from the donor.
352
		$donor->remove_payment( $payment_id );
353
	}
354
355
	// Remove the payment.
356
	wp_delete_post( $payment_id, true );
357
358
	// Remove related sale log entries.
359
	Give()->logs->delete_logs( $payment_id );
360
361
	/**
362
	 * Fires after payment deleted.
363
	 *
364
	 * @param int $payment_id Payment ID.
365
	 *
366
	 * @since 1.0
367
	 */
368
	do_action( 'give_payment_deleted', $payment_id );
369
}
370
371
/**
372
 * Undo Donation
373
 *
374
 * Undoes a donation, including the decrease of donations and earning stats.
375
 * Used for when refunding or deleting a donation.
376
 *
377
 * @param  int $payment_id Payment ID.
378
 *
379
 * @since  1.0
380
 *
381
 * @return void
382
 */
383
function give_undo_donation( $payment_id ) {
384
385
	$payment = new Give_Payment( $payment_id );
386
387
	$maybe_decrease_earnings = apply_filters( 'give_decrease_earnings_on_undo', true, $payment, $payment->form_id );
388
	if ( true === $maybe_decrease_earnings ) {
389
		// Decrease earnings.
390
		give_decrease_form_earnings( $payment->form_id, $payment->total );
391
	}
392
393
	$maybe_decrease_donations = apply_filters( 'give_decrease_donations_on_undo', true, $payment, $payment->form_id );
394
	if ( true === $maybe_decrease_donations ) {
395
		// Decrease donation count.
396
		give_decrease_donation_count( $payment->form_id );
397
	}
398
399
}
400
401
402
/**
403
 * Count Payments
404
 *
405
 * Returns the total number of payments recorded.
406
 *
407
 * @param  array $args Arguments passed.
408
 *
409
 * @since  1.0
410
 *
411
 * @return object $stats Contains the number of payments per payment status.
412
 */
413
function give_count_payments( $args = array() ) {
414
	// Backward compatibility.
415
	if( ! empty( $args['start-date'] ) ) {
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...
416
		$args['start_date'] = $args['start-date'];
417
		unset( $args['start-date'] );
418
	}
419
420
	if( ! empty( $args['end-date'] ) ) {
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...
421
		$args['end_date'] = $args['end-date'];
422
		unset( $args['end-date'] );
423
	}
424
425
	if( ! empty( $args['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...
426
		$args['give_forms'] = $args['form_id'];
427
		unset( $args['form_id'] );
428
	}
429
430
	// Extract all donations
431
	$args['number'] = -1;
432
	
433
	$donations_obj = new Give_Payments_Query( $args );
434
	$donations_count = $donations_obj->get_payment_by_group('post_status', true );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
435
436
	return (object) apply_filters( 'give_count_payments', $donations_count, $args, $donations_obj );
437
}
438
439
440
/**
441
 * Check For Existing Payment
442
 *
443
 * @param  int $payment_id Payment ID.
444
 *
445
 * @since  1.0
446
 *
447
 * @return bool $exists True if payment exists, false otherwise.
448
 */
449
function give_check_for_existing_payment( $payment_id ) {
450
	$exists  = false;
451
	$payment = new Give_Payment( $payment_id );
452
453
	if ( $payment_id === $payment->ID && 'publish' === $payment->status ) {
454
		$exists = true;
455
	}
456
457
	return $exists;
458
}
459
460
/**
461
 * Get Payment Status
462
 *
463
 * @param WP_Post|Give_Payment|int $payment      Payment object or payment ID.
464
 * @param bool                     $return_label Whether to return the translated status label instead of status value.
465
 *                                               Default false.
466
 *
467
 * @since 1.0
468
 *
469
 * @return bool|mixed True if payment status exists, false otherwise.
470
 */
471
function give_get_payment_status( $payment, $return_label = false ) {
472
473
	if ( is_numeric( $payment ) ) {
474
475
		$payment = new Give_Payment( $payment );
476
477
		if ( ! $payment->ID > 0 ) {
478
			return false;
479
		}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
480
481
	}
482
483
	if ( ! is_object( $payment ) || ! isset( $payment->post_status ) ) {
484
		return false;
485
	}
486
487
	$statuses = give_get_payment_statuses();
488
489
	if ( ! is_array( $statuses ) || empty( $statuses ) ) {
490
		return false;
491
	}
492
493
	// Get payment object if not already given.
494
	$payment = $payment instanceof Give_Payment ? $payment : new Give_Payment( $payment->ID );
495
496
	if ( array_key_exists( $payment->status, $statuses ) ) {
497
		if ( true === $return_label ) {
498
			// Return translated status label.
499
			return $statuses[ $payment->status ];
500
		} else {
501
			// Account that our 'publish' status is labeled 'Complete'
502
			$post_status = 'publish' === $payment->status ? 'Complete' : $payment->post_status;
503
504
			// Make sure we're matching cases, since they matter
505
			return array_search( strtolower( $post_status ), array_map( 'strtolower', $statuses ) );
506
		}
507
	}
508
509
	return false;
510
}
511
512
/**
513
 * Retrieves all available statuses for payments.
514
 *
515
 * @since  1.0
516
 *
517
 * @return array $payment_status All the available payment statuses.
518
 */
519
function give_get_payment_statuses() {
520
	$payment_statuses = array(
521
		'pending'     => __( 'Pending', 'give' ),
522
		'publish'     => __( 'Complete', 'give' ),
523
		'refunded'    => __( 'Refunded', 'give' ),
524
		'failed'      => __( 'Failed', 'give' ),
525
		'cancelled'   => __( 'Cancelled', 'give' ),
526
		'abandoned'   => __( 'Abandoned', 'give' ),
527
		'preapproval' => __( 'Pre-Approved', 'give' ),
528
		'processing'  => __( 'Processing', 'give' ),
529
		'revoked'     => __( 'Revoked', 'give' ),
530
	);
531
532
	return apply_filters( 'give_payment_statuses', $payment_statuses );
533
}
534
535
/**
536
 * Get Payment Status Keys
537
 *
538
 * Retrieves keys for all available statuses for payments
539
 *
540
 * @since 1.0
541
 *
542
 * @return array $payment_status All the available payment statuses.
543
 */
544
function give_get_payment_status_keys() {
545
	$statuses = array_keys( give_get_payment_statuses() );
546
	asort( $statuses );
547
548
	return array_values( $statuses );
549
}
550
551
/**
552
 * Get Earnings By Date
553
 *
554
 * @param int $day       Day number. Default is null.
555
 * @param int $month_num Month number. Default is null.
556
 * @param int $year      Year number. Default is null.
557
 * @param int $hour      Hour number. Default is null.
558
 *
559
 * @since 1.0
560
 *
561
 * @return int $earnings Earnings
562
 */
563
function give_get_earnings_by_date( $day = null, $month_num, $year = null, $hour = null ) {
564
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_earnings() method instead.
565
566
	global $wpdb;
567
	$meta_table = __give_v20_bc_table_details( 'payment' );
0 ignored issues
show
Unused Code introduced by
$meta_table is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
568
569
	$args = array(
570
		'post_type'              => 'give_payment',
571
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
572
		'year'                   => $year,
573
		'monthnum'               => $month_num,
574
		'post_status'            => array( 'publish' ),
575
		'fields'                 => 'ids',
576
		'update_post_term_cache' => false,
577
	);
578
	if ( ! empty( $day ) ) {
579
		$args['day'] = $day;
580
	}
581
582
	if ( isset( $hour ) ) {
583
		$args['hour'] = $hour;
584
	}
585
586
	$args = apply_filters( 'give_get_earnings_by_date_args', $args );
587
	$key  = Give_Cache::get_key( 'give_stats', $args );
588
589 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...
590
		$earnings = false;
591
	} else {
592
		$earnings = Give_Cache::get( $key );
593
	}
594
595
	if ( false === $earnings ) {
596
		$donations = get_posts( $args );
597
		$earnings  = 0;
598
		if ( $donations ) {
599
			$donations      = implode( ',', $donations );
600
			$earning_totals = $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...
601
602
			/**
603
			 * Filter The earnings by dates.
604
			 *
605
			 * @since 1.8.17
606
			 *
607
			 * @param float $earning_totals Total earnings between the dates.
608
			 * @param array $donations      Donations lists.
609
			 * @param array $args           Donation query args.
610
			 */
611
			$earnings = apply_filters( 'give_earnings_by_date', $earning_totals, $donations, $args );
612
		}
613
		// Cache the results for one hour.
614
		Give_Cache::set( $key, $earnings, HOUR_IN_SECONDS );
615
	}
616
617
	return round( $earnings, 2 );
618
}
619
620
/**
621
 * Get Donations (sales) By Date
622
 *
623
 * @param int $day       Day number. Default is null.
624
 * @param int $month_num Month number. Default is null.
625
 * @param int $year      Year number. Default is null.
626
 * @param int $hour      Hour number. Default is null.
627
 *
628
 * @since 1.0
629
 *
630
 * @return int $count Sales
631
 */
632
function give_get_sales_by_date( $day = null, $month_num = null, $year = null, $hour = null ) {
633
634
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_sales() method instead.
635
	$args = array(
636
		'post_type'              => 'give_payment',
637
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
638
		'year'                   => $year,
639
		'fields'                 => 'ids',
640
		'post_status'            => array( 'publish' ),
641
		'update_post_meta_cache' => false,
642
		'update_post_term_cache' => false,
643
	);
644
645
	$show_free = apply_filters( 'give_sales_by_date_show_free', true, $args );
646
647
	if ( false === $show_free ) {
648
		$args['meta_query'] = array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
649
			array(
650
				'key'     => '_give_payment_total',
651
				'value'   => 0,
652
				'compare' => '>',
653
				'type'    => 'NUMERIC',
654
			),
655
		);
656
	}
657
658
	if ( ! empty( $month_num ) ) {
659
		$args['monthnum'] = $month_num;
660
	}
661
662
	if ( ! empty( $day ) ) {
663
		$args['day'] = $day;
664
	}
665
666
	if ( isset( $hour ) ) {
667
		$args['hour'] = $hour;
668
	}
669
670
	$args = apply_filters( 'give_get_sales_by_date_args', $args );
671
672
	$key = Give_Cache::get_key( 'give_stats', $args );
673
674 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...
675
		$count = false;
676
	} else {
677
		$count = Give_Cache::get( $key );
678
	}
679
680
	if ( false === $count ) {
681
		$donations = new WP_Query( $args );
682
		$count     = (int) $donations->post_count;
683
		// Cache the results for one hour.
684
		Give_Cache::set( $key, $count, HOUR_IN_SECONDS );
685
	}
686
687
	return $count;
688
}
689
690
/**
691
 * Checks whether a payment has been marked as complete.
692
 *
693
 * @param int $payment_id Payment ID to check against.
694
 *
695
 * @since 1.0
696
 *
697
 * @return bool $ret True if complete, false otherwise.
698
 */
699
function give_is_payment_complete( $payment_id ) {
700
	$payment = new Give_Payment( $payment_id );
701
702
	$ret = false;
703
704
	if ( $payment->ID > 0 ) {
705
706
		if ( (int) $payment_id === (int) $payment->ID && 'publish' == $payment->status ) {
707
			$ret = true;
708
		}
709
	}
710
711
	return apply_filters( 'give_is_payment_complete', $ret, $payment_id, $payment->post_status );
712
}
713
714
/**
715
 * Get Total Donations.
716
 *
717
 * @since 1.0
718
 *
719
 * @return int $count Total number of donations.
720
 */
721
function give_get_total_donations() {
722
723
	$payments = give_count_payments();
724
725
	return $payments->publish;
726
}
727
728
/**
729
 * Get Total Earnings
730
 *
731
 * @param bool $recalculate Recalculate earnings forcefully.
732
 *
733
 * @since 1.0
734
 *
735
 * @return float $total Total earnings.
736
 */
737
function give_get_total_earnings( $recalculate = false ) {
738
739
	$total      = get_option( 'give_earnings_total', 0 );
740
	$meta_table = __give_v20_bc_table_details( 'payment' );
741
742
	// Calculate total earnings.
743
	if ( ! $total || $recalculate ) {
744
		global $wpdb;
745
746
		$total = (float) 0;
747
748
		$args = apply_filters( 'give_get_total_earnings_args', array(
749
			'offset' => 0,
750
			'number' => - 1,
751
			'status' => array( 'publish' ),
752
			'fields' => 'ids',
753
		) );
754
755
		$payments = give_get_payments( $args );
756
		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...
757
758
			/**
759
			 * If performing a donation, we need to skip the very last payment in the database,
760
			 * since it calls give_increase_total_earnings() on completion,
761
			 * which results in duplicated earnings for the very first donation.
762
			 */
763
			if ( did_action( 'give_update_payment_status' ) ) {
764
				array_pop( $payments );
765
			}
766
767
			if ( ! empty( $payments ) ) {
768
				$payments = implode( ',', $payments );
769
				$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...
770
			}
771
		}
772
773
		update_option( 'give_earnings_total', $total, 'no' );
774
	}
775
776
	if ( $total < 0 ) {
777
		$total = 0; // Don't ever show negative earnings.
778
	}
779
780
	return apply_filters( 'give_total_earnings', round( $total, give_get_price_decimals() ), $total );
781
}
782
783
/**
784
 * Increase the Total Earnings
785
 *
786
 * @param int $amount The amount you would like to increase the total earnings by. Default is 0.
787
 *
788
 * @since 1.0
789
 *
790
 * @return float $total Total earnings.
791
 */
792
function give_increase_total_earnings( $amount = 0 ) {
793
	$total = give_get_total_earnings();
794
	$total += $amount;
795
	update_option( 'give_earnings_total', $total );
796
797
	return $total;
798
}
799
800
/**
801
 * Decrease the Total Earnings
802
 *
803
 * @param int $amount The amount you would like to decrease the total earnings by.
804
 *
805
 * @since 1.0
806
 *
807
 * @return float $total Total earnings.
808
 */
809
function give_decrease_total_earnings( $amount = 0 ) {
810
	$total = give_get_total_earnings();
811
	$total -= $amount;
812
	if ( $total < 0 ) {
813
		$total = 0;
814
	}
815
	update_option( 'give_earnings_total', $total );
816
817
	return $total;
818
}
819
820
/**
821
 * Get Payment Meta for a specific Payment
822
 *
823
 * @param int    $payment_id Payment ID.
824
 * @param string $meta_key   The meta key to pull.
825
 * @param bool   $single     Pull single meta entry or as an object.
826
 *
827
 * @since 1.0
828
 *
829
 * @return mixed $meta Payment Meta.
830
 */
831
function give_get_payment_meta( $payment_id = 0, $meta_key = '_give_payment_meta', $single = true ) {
832
	$payment = new Give_Payment( $payment_id );
833
834
	return $payment->get_meta( $meta_key, $single );
835
}
836
837
/**
838
 * Update the meta for a payment
839
 *
840
 * @param  int    $payment_id Payment ID.
841
 * @param  string $meta_key   Meta key to update.
842
 * @param  string $meta_value Value to update to.
843
 * @param  string $prev_value Previous value.
844
 *
845
 * @return mixed Meta ID if successful, false if unsuccessful.
846
 */
847
function give_update_payment_meta( $payment_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
848
	$payment = new Give_Payment( $payment_id );
849
850
	return $payment->update_meta( $meta_key, $meta_value, $prev_value );
851
}
852
853
/**
854
 * Get the user_info Key from Payment Meta
855
 *
856
 * @param int $payment_id Payment ID.
857
 *
858
 * @since 1.0
859
 *
860
 * @return array $user_info User Info Meta Values.
861
 */
862
function give_get_payment_meta_user_info( $payment_id ) {
863
	$payment = new Give_Payment( $payment_id );
864
865
	return $payment->user_info;
866
}
867
868
/**
869
 * Get the donations Key from Payment Meta
870
 *
871
 * Retrieves the form_id from a (Previously titled give_get_payment_meta_donations)
872
 *
873
 * @param int $payment_id Payment ID.
874
 *
875
 * @since 1.0
876
 *
877
 * @return int $form_id Form ID.
878
 */
879
function give_get_payment_form_id( $payment_id ) {
880
	$payment = new Give_Payment( $payment_id );
881
882
	return $payment->form_id;
883
}
884
885
/**
886
 * Get the user email associated with a payment
887
 *
888
 * @param int $payment_id Payment ID.
889
 *
890
 * @since 1.0
891
 *
892
 * @return string $email User email.
893
 */
894
function give_get_payment_user_email( $payment_id ) {
895
	$payment = new Give_Payment( $payment_id );
896
897
	return $payment->email;
898
}
899
900
/**
901
 * Is the payment provided associated with a user account
902
 *
903
 * @param int $payment_id The payment ID.
904
 *
905
 * @since 1.3
906
 *
907
 * @return bool $is_guest_payment If the payment is associated with a user (false) or not (true)
908
 */
909
function give_is_guest_payment( $payment_id ) {
910
	$payment_user_id  = give_get_payment_user_id( $payment_id );
911
	$is_guest_payment = ! empty( $payment_user_id ) && $payment_user_id > 0 ? false : true;
912
913
	return (bool) apply_filters( 'give_is_guest_payment', $is_guest_payment, $payment_id );
914
}
915
916
/**
917
 * Get the user ID associated with a payment
918
 *
919
 * @param int $payment_id Payment ID.
920
 *
921
 * @since 1.3
922
 *
923
 * @return int $user_id User ID.
924
 */
925
function give_get_payment_user_id( $payment_id ) {
926
	$payment = new Give_Payment( $payment_id );
927
928
	return $payment->user_id;
929
}
930
931
/**
932
 * Get the donor ID associated with a payment.
933
 *
934
 * @param int $payment_id Payment ID.
935
 *
936
 * @since 1.0
937
 *
938
 * @return int $payment->customer_id Donor ID.
939
 */
940
function give_get_payment_donor_id( $payment_id ) {
941
	$payment = new Give_Payment( $payment_id );
942
943
	return $payment->customer_id;
944
}
945
946
/**
947
 * Get the IP address used to make a donation
948
 *
949
 * @param int $payment_id Payment ID.
950
 *
951
 * @since 1.0
952
 *
953
 * @return string $ip User IP.
954
 */
955
function give_get_payment_user_ip( $payment_id ) {
956
	$payment = new Give_Payment( $payment_id );
957
958
	return $payment->ip;
959
}
960
961
/**
962
 * Get the date a payment was completed
963
 *
964
 * @param int $payment_id Payment ID.
965
 *
966
 * @since 1.0
967
 *
968
 * @return string $date The date the payment was completed.
969
 */
970
function give_get_payment_completed_date( $payment_id = 0 ) {
971
	$payment = new Give_Payment( $payment_id );
972
973
	return $payment->completed_date;
974
}
975
976
/**
977
 * Get the gateway associated with a payment
978
 *
979
 * @param int $payment_id Payment ID.
980
 *
981
 * @since 1.0
982
 *
983
 * @return string $gateway Gateway.
984
 */
985
function give_get_payment_gateway( $payment_id ) {
986
	$payment = new Give_Payment( $payment_id );
987
988
	return $payment->gateway;
989
}
990
991
/**
992
 * Get the currency code a payment was made in
993
 *
994
 * @param int $payment_id Payment ID.
995
 *
996
 * @since 1.0
997
 *
998
 * @return string $currency The currency code.
999
 */
1000
function give_get_payment_currency_code( $payment_id = 0 ) {
1001
	$payment = new Give_Payment( $payment_id );
1002
1003
	return $payment->currency;
1004
}
1005
1006
/**
1007
 * Get the currency name a payment was made in
1008
 *
1009
 * @param int $payment_id Payment ID.
1010
 *
1011
 * @since 1.0
1012
 *
1013
 * @return string $currency The currency name.
1014
 */
1015
function give_get_payment_currency( $payment_id = 0 ) {
1016
	$currency = give_get_payment_currency_code( $payment_id );
1017
1018
	return apply_filters( 'give_payment_currency', give_get_currency_name( $currency ), $payment_id );
1019
}
1020
1021
/**
1022
 * Get the key for a donation
1023
 *
1024
 * @param int $payment_id Payment ID.
1025
 *
1026
 * @since 1.0
1027
 *
1028
 * @return string $key Donation key.
1029
 */
1030
function give_get_payment_key( $payment_id = 0 ) {
1031
	$payment = new Give_Payment( $payment_id );
1032
1033
	return $payment->key;
1034
}
1035
1036
/**
1037
 * Get the payment order number
1038
 *
1039
 * This will return the payment ID if sequential order numbers are not enabled or the order number does not exist
1040
 *
1041
 * @param int $payment_id Payment ID.
1042
 *
1043
 * @since 1.0
1044
 *
1045
 * @return string $number Payment order number.
1046
 */
1047
function give_get_payment_number( $payment_id = 0 ) {
1048
	$payment = new Give_Payment( $payment_id );
1049
1050
	return $payment->number;
1051
}
1052
1053
/**
1054
 * Formats the payment number with the prefix and postfix
1055
 *
1056
 * @param int $number The payment number to format.
1057
 *
1058
 * @since 1.3
1059
 *
1060
 * @return string      The formatted payment number.
1061
 */
1062
function give_format_payment_number( $number ) {
1063
1064
	if ( ! give_get_option( 'enable_sequential' ) ) {
1065
		return $number;
1066
	}
1067
1068
	if ( ! is_numeric( $number ) ) {
1069
		return $number;
1070
	}
1071
1072
	$prefix  = give_get_option( 'sequential_prefix' );
1073
	$number  = absint( $number );
1074
	$postfix = give_get_option( 'sequential_postfix' );
1075
1076
	$formatted_number = $prefix . $number . $postfix;
1077
1078
	return apply_filters( 'give_format_payment_number', $formatted_number, $prefix, $number, $postfix );
1079
}
1080
1081
/**
1082
 * Gets the next available order number
1083
 *
1084
 * This is used when inserting a new payment
1085
 *
1086
 * @since 1.0
1087
 *
1088
 * @return string $number The next available payment number.
1089
 */
1090
function give_get_next_payment_number() {
1091
1092
	if ( ! give_get_option( 'enable_sequential' ) ) {
1093
		return false;
1094
	}
1095
1096
	$number           = get_option( 'give_last_payment_number' );
1097
	$start            = give_get_option( 'sequential_start', 1 );
1098
	$increment_number = true;
1099
1100
	if ( false !== $number ) {
1101
1102
		if ( empty( $number ) ) {
1103
1104
			$number           = $start;
1105
			$increment_number = false;
1106
1107
		}
1108
	} else {
1109
1110
		// This case handles the first addition of the new option, as well as if it get's deleted for any reason.
1111
		$payments     = new Give_Payments_Query( array(
1112
			'number'  => 1,
1113
			'order'   => 'DESC',
1114
			'orderby' => 'ID',
1115
			'output'  => 'posts',
1116
			'fields'  => 'ids',
1117
		) );
1118
		$last_payment = $payments->get_payments();
1119
1120
		if ( ! empty( $last_payment ) ) {
1121
1122
			$number = give_get_payment_number( $last_payment[0] );
1123
1124
		}
1125
1126
		if ( ! empty( $number ) && $number !== (int) $last_payment[0] ) {
1127
1128
			$number = give_remove_payment_prefix_postfix( $number );
1129
1130
		} else {
1131
1132
			$number           = $start;
1133
			$increment_number = false;
1134
		}
1135
	}// End if().
1136
1137
	$increment_number = apply_filters( 'give_increment_payment_number', $increment_number, $number );
1138
1139
	if ( $increment_number ) {
1140
		$number ++;
1141
	}
1142
1143
	return apply_filters( 'give_get_next_payment_number', $number );
1144
}
1145
1146
/**
1147
 * Given a given a number, remove the pre/postfix
1148
 *
1149
 * @param string $number The formatted Current Number to increment.
1150
 *
1151
 * @since 1.3
1152
 *
1153
 * @return string The new Payment number without prefix and postfix.
1154
 */
1155
function give_remove_payment_prefix_postfix( $number ) {
1156
1157
	$prefix  = give_get_option( 'sequential_prefix' );
1158
	$postfix = give_get_option( 'sequential_postfix' );
1159
1160
	// Remove prefix.
1161
	$number = preg_replace( '/' . $prefix . '/', '', $number, 1 );
1162
1163
	// Remove the postfix.
1164
	$length      = strlen( $number );
1165
	$postfix_pos = strrpos( $number, $postfix );
1166
	if ( false !== $postfix_pos ) {
1167
		$number = substr_replace( $number, '', $postfix_pos, $length );
1168
	}
1169
1170
	// Ensure it's a whole number.
1171
	$number = intval( $number );
1172
1173
	return apply_filters( 'give_remove_payment_prefix_postfix', $number, $prefix, $postfix );
1174
1175
}
1176
1177
/**
1178
 * Get Payment Amount
1179
 *
1180
 * Get the fully formatted donation amount. The donation amount is retrieved using give_get_donation_amount() and is
1181
 * then sent through give_currency_filter() and  give_format_amount() to format the amount correctly.
1182
 *
1183
 * @param int    $donation_id Donation ID.
1184
 * @param string $type        String parameter which will define context of donation amount.
1185
 *
1186
 * @since 1.0
1187
 * @since 1.8.17 Added filter and internally use functions.
1188
 *
1189
 * @return string $amount Fully formatted donation amount.
1190
 */
1191
function give_donation_amount( $donation_id = 0, $type = '' ) {
1192
	$donation_currency = give_get_payment_currency_code( $donation_id );
1193
	$amount            = give_get_payment_amount( $donation_id );
1194
1195
	$formatted_amount = give_currency_filter(
1196
		give_format_amount(
1197
			$amount,
1198
			array(
1199
				'sanitize' => false,
1200
				'currency' => $donation_currency,
1201
			)
1202
		),
1203
		$donation_currency
1204
	);
1205
1206
	/**
1207
	 * Filter payment amount.
1208
	 *
1209
	 * @since 1.8.17
1210
	 *
1211
	 * @param string  $formatted_amount Formatted amount.
1212
	 * @param double  $amount           Donation amount.
1213
	 * @param integer $donation_id      Donation ID.
1214
	 * @param string  $type             String parameter which will define context of donation amount..
1215
	 */
1216
	return apply_filters( 'give_get_donation_amount', $formatted_amount, $amount, $donation_id, $type );
1217
}
1218
1219
/**
1220
 * Get the amount associated with a payment
1221
 *
1222
 * @param int $payment_id Payment ID.
1223
 *
1224
 * @access public
1225
 * @since  1.0
1226
 *
1227
 * @return mixed
1228
 */
1229
function give_get_payment_amount( $payment_id ) {
1230
1231
	$payment = new Give_Payment( $payment_id );
1232
1233
	return apply_filters( 'give_payment_amount', floatval( $payment->total ), $payment_id );
1234
}
1235
1236
/**
1237
 * Payment Subtotal
1238
 *
1239
 * Retrieves subtotal for payment and then returns a full formatted amount. This
1240
 * function essentially calls give_get_payment_subtotal()
1241
 *
1242
 * @param int $payment_id Payment ID.
1243
 *
1244
 * @since 1.5
1245
 *
1246
 * @see   give_get_payment_subtotal()
1247
 *
1248
 * @return array Fully formatted payment subtotal.
1249
 */
1250
function give_payment_subtotal( $payment_id = 0 ) {
1251
	$subtotal = give_get_payment_subtotal( $payment_id );
1252
1253
	return give_currency_filter( give_format_amount( $subtotal, array( 'sanitize' => false ) ), give_get_payment_currency_code( $payment_id ) );
1254
}
1255
1256
/**
1257
 * Get Payment Subtotal
1258
 *
1259
 * Retrieves subtotal for payment and then returns a non formatted amount.
1260
 *
1261
 * @param int $payment_id Payment ID.
1262
 *
1263
 * @since 1.5
1264
 *
1265
 * @return float $subtotal Subtotal for payment (non formatted).
1266
 */
1267
function give_get_payment_subtotal( $payment_id = 0 ) {
1268
	$payment = new Give_Payment( $payment_id );
1269
1270
	return $payment->subtotal;
1271
}
1272
1273
/**
1274
 * Retrieves the donation ID
1275
 *
1276
 * @param int $payment_id Payment ID.
1277
 *
1278
 * @since  1.0
1279
 *
1280
 * @return string The donation ID.
1281
 */
1282
function give_get_payment_transaction_id( $payment_id = 0 ) {
1283
	$payment = new Give_Payment( $payment_id );
1284
1285
	return $payment->transaction_id;
1286
}
1287
1288
/**
1289
 * Sets a Transaction ID in post meta for the given Payment ID.
1290
 *
1291
 * @param int    $payment_id     Payment ID.
1292
 * @param string $transaction_id The transaction ID from the gateway.
1293
 *
1294
 * @since  1.0
1295
 *
1296
 * @return bool|mixed
1297
 */
1298
function give_set_payment_transaction_id( $payment_id = 0, $transaction_id = '' ) {
1299
1300
	if ( empty( $payment_id ) || empty( $transaction_id ) ) {
1301
		return false;
1302
	}
1303
1304
	$transaction_id = apply_filters( 'give_set_payment_transaction_id', $transaction_id, $payment_id );
1305
1306
	return give_update_payment_meta( $payment_id, '_give_payment_transaction_id', $transaction_id );
1307
}
1308
1309
/**
1310
 * Retrieve the donation ID based on the key
1311
 *
1312
 * @param string  $key  the key to search for.
1313
 *
1314
 * @since 1.0
1315
 * @global object $wpdb Used to query the database using the WordPress Database API.
1316
 *
1317
 * @return int $purchase Donation ID.
1318
 */
1319 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...
1320
	global $wpdb;
1321
	$meta_table = __give_v20_bc_table_details( 'payment' );
1322
1323
	$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...
1324
1325
	if ( $purchase != null ) {
1326
		return $purchase;
1327
	}
1328
1329
	return 0;
1330
}
1331
1332
1333
/**
1334
 * Retrieve the donation ID based on the transaction ID
1335
 *
1336
 * @param string  $key  The transaction ID to search for.
1337
 *
1338
 * @since 1.3
1339
 * @global object $wpdb Used to query the database using the WordPress Database API.
1340
 *
1341
 * @return int $purchase Donation ID.
1342
 */
1343 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...
1344
	global $wpdb;
1345
	$meta_table = __give_v20_bc_table_details( 'payment' );
1346
1347
	$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...
1348
1349
	if ( $purchase != null ) {
1350
		return $purchase;
1351
	}
1352
1353
	return 0;
1354
}
1355
1356
/**
1357
 * Retrieve all notes attached to a donation
1358
 *
1359
 * @param int    $payment_id The donation ID to retrieve notes for.
1360
 * @param string $search     Search for notes that contain a search term.
1361
 *
1362
 * @since 1.0
1363
 *
1364
 * @return array $notes Donation Notes
1365
 */
1366
function give_get_payment_notes( $payment_id = 0, $search = '' ) {
1367
1368
	if ( empty( $payment_id ) && empty( $search ) ) {
1369
		return false;
1370
	}
1371
1372
	remove_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1373
	remove_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10 );
1374
1375
	$notes = get_comments( array(
1376
		'post_id' => $payment_id,
1377
		'order'   => 'ASC',
1378
		'search'  => $search,
1379
	) );
1380
1381
	add_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1382
	add_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10, 2 );
1383
1384
	return $notes;
1385
}
1386
1387
1388
/**
1389
 * Add a note to a payment
1390
 *
1391
 * @param int    $payment_id The payment ID to store a note for.
1392
 * @param string $note       The note to store.
1393
 *
1394
 * @since 1.0
1395
 *
1396
 * @return int The new note ID
1397
 */
1398
function give_insert_payment_note( $payment_id = 0, $note = '' ) {
1399
	if ( empty( $payment_id ) ) {
1400
		return false;
1401
	}
1402
1403
	/**
1404
	 * Fires before inserting payment note.
1405
	 *
1406
	 * @param int    $payment_id Payment ID.
1407
	 * @param string $note       The note.
1408
	 *
1409
	 * @since 1.0
1410
	 */
1411
	do_action( 'give_pre_insert_payment_note', $payment_id, $note );
1412
1413
	$note_id = wp_insert_comment( wp_filter_comment( array(
1414
		'comment_post_ID'      => $payment_id,
1415
		'comment_content'      => $note,
1416
		'user_id'              => is_admin() ? get_current_user_id() : 0,
1417
		'comment_date'         => current_time( 'mysql' ),
1418
		'comment_date_gmt'     => current_time( 'mysql', 1 ),
1419
		'comment_approved'     => 1,
1420
		'comment_parent'       => 0,
1421
		'comment_author'       => '',
1422
		'comment_author_IP'    => '',
1423
		'comment_author_url'   => '',
1424
		'comment_author_email' => '',
1425
		'comment_type'         => 'give_payment_note',
1426
1427
	) ) );
1428
1429
	/**
1430
	 * Fires after payment note inserted.
1431
	 *
1432
	 * @param int    $note_id    Note ID.
1433
	 * @param int    $payment_id Payment ID.
1434
	 * @param string $note       The note.
1435
	 *
1436
	 * @since 1.0
1437
	 */
1438
	do_action( 'give_insert_payment_note', $note_id, $payment_id, $note );
1439
1440
	return $note_id;
1441
}
1442
1443
/**
1444
 * Deletes a payment note
1445
 *
1446
 * @param int $comment_id The comment ID to delete.
1447
 * @param int $payment_id The payment ID the note is connected to.
1448
 *
1449
 * @since 1.0
1450
 *
1451
 * @return bool True on success, false otherwise.
1452
 */
1453
function give_delete_payment_note( $comment_id = 0, $payment_id = 0 ) {
1454
	if ( empty( $comment_id ) ) {
1455
		return false;
1456
	}
1457
1458
	/**
1459
	 * Fires before deleting donation note.
1460
	 *
1461
	 * @param int $comment_id Note ID.
1462
	 * @param int $payment_id Payment ID.
1463
	 *
1464
	 * @since 1.0
1465
	 */
1466
	do_action( 'give_pre_delete_payment_note', $comment_id, $payment_id );
1467
1468
	$ret = wp_delete_comment( $comment_id, true );
1469
1470
	/**
1471
	 * Fires after donation note deleted.
1472
	 *
1473
	 * @param int $comment_id Note ID.
1474
	 * @param int $payment_id Payment ID.
1475
	 *
1476
	 * @since 1.0
1477
	 */
1478
	do_action( 'give_post_delete_payment_note', $comment_id, $payment_id );
1479
1480
	return $ret;
1481
}
1482
1483
/**
1484
 * Gets the payment note HTML
1485
 *
1486
 * @param object|int $note       The comment object or ID.
1487
 * @param int        $payment_id The payment ID the note is connected to.
1488
 *
1489
 * @since 1.0
1490
 *
1491
 * @return string
1492
 */
1493
function give_get_payment_note_html( $note, $payment_id = 0 ) {
1494
1495
	if ( is_numeric( $note ) ) {
1496
		$note = get_comment( $note );
1497
	}
1498
1499
	if ( ! empty( $note->user_id ) ) {
1500
		$user = get_userdata( $note->user_id );
1501
		$user = $user->display_name;
1502
	} else {
1503
		$user = __( 'System', 'give' );
1504
	}
1505
1506
	$date_format = give_date_format() . ', ' . get_option( 'time_format' );
1507
1508
	$delete_note_url = wp_nonce_url( add_query_arg( array(
1509
		'give-action' => 'delete_payment_note',
1510
		'note_id'     => $note->comment_ID,
1511
		'payment_id'  => $payment_id,
1512
	) ), 'give_delete_payment_note_' . $note->comment_ID );
1513
1514
	$note_html = '<div class="give-payment-note" id="give-payment-note-' . $note->comment_ID . '">';
1515
	$note_html .= '<p>';
1516
	$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/>';
1517
	$note_html .= $note->comment_content;
1518
	$note_html .= '&nbsp;&ndash;&nbsp;<a href="' . esc_url( $delete_note_url ) . '" class="give-delete-payment-note" data-note-id="' . absint( $note->comment_ID ) . '" data-payment-id="' . absint( $payment_id ) . '" aria-label="' . __( 'Delete this donation note.', 'give' ) . '">' . __( 'Delete', 'give' ) . '</a>';
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw '__'
Loading history...
1519
	$note_html .= '</p>';
1520
	$note_html .= '</div>';
1521
1522
	return $note_html;
1523
1524
}
1525
1526
/**
1527
 * Exclude notes (comments) on give_payment post type from showing in Recent
1528
 * Comments widgets
1529
 *
1530
 * @param object $query WordPress Comment Query Object.
1531
 *
1532
 * @since 1.0
1533
 *
1534
 * @return void
1535
 */
1536
function give_hide_payment_notes( $query ) {
1537
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.1', '>=' ) ) {
1538
		$types = isset( $query->query_vars['type__not_in'] ) ? $query->query_vars['type__not_in'] : array();
1539
		if ( ! is_array( $types ) ) {
1540
			$types = array( $types );
1541
		}
1542
		$types[]                           = 'give_payment_note';
1543
		$query->query_vars['type__not_in'] = $types;
1544
	}
1545
}
1546
1547
add_action( 'pre_get_comments', 'give_hide_payment_notes', 10 );
1548
1549
/**
1550
 * Exclude notes (comments) on give_payment post type from showing in Recent Comments widgets
1551
 *
1552
 * @param array  $clauses          Comment clauses for comment query.
1553
 * @param object $wp_comment_query WordPress Comment Query Object.
1554
 *
1555
 * @since 1.0
1556
 *
1557
 * @return array $clauses Updated comment clauses.
1558
 */
1559
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...
1560
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.1', '<' ) ) {
1561
		$clauses['where'] .= ' AND comment_type != "give_payment_note"';
1562
	}
1563
1564
	return $clauses;
1565
}
1566
1567
add_filter( 'comments_clauses', 'give_hide_payment_notes_pre_41', 10, 2 );
1568
1569
1570
/**
1571
 * Exclude notes (comments) on give_payment post type from showing in comment feeds
1572
 *
1573
 * @param string $where
1574
 * @param object $wp_comment_query WordPress Comment Query Object.
1575
 *
1576
 * @since 1.0
1577
 *
1578
 * @return string $where
1579
 */
1580
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...
1581
	global $wpdb;
1582
1583
	$where .= $wpdb->prepare( ' AND comment_type != %s', 'give_payment_note' );
1584
1585
	return $where;
1586
}
1587
1588
add_filter( 'comment_feed_where', 'give_hide_payment_notes_from_feeds', 10, 2 );
1589
1590
1591
/**
1592
 * Remove Give Comments from the wp_count_comments function
1593
 *
1594
 * @param array $stats   (empty from core filter).
1595
 * @param int   $post_id Post ID.
1596
 *
1597
 * @access public
1598
 * @since  1.0
1599
 *
1600
 * @return array|object Array of comment counts.
1601
 */
1602
function give_remove_payment_notes_in_comment_counts( $stats, $post_id ) {
1603
	global $wpdb, $pagenow;
1604
1605
	if ( 'index.php' != $pagenow ) {
1606
		return $stats;
1607
	}
1608
1609
	$post_id = (int) $post_id;
1610
1611
	if ( apply_filters( 'give_count_payment_notes_in_comments', false ) ) {
1612
		return $stats;
1613
	}
1614
1615
	$stats = Give_Cache::get_group( "comments-{$post_id}", 'counts' );
1616
1617
	if ( false !== $stats ) {
1618
		return $stats;
1619
	}
1620
1621
	$where = 'WHERE comment_type != "give_payment_note"';
1622
1623
	if ( $post_id > 0 ) {
1624
		$where .= $wpdb->prepare( ' AND comment_post_ID = %d', $post_id );
1625
	}
1626
1627
	$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...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1628
1629
	$total    = 0;
1630
	$approved = array(
1631
		'0'            => 'moderated',
0 ignored issues
show
introduced by
Detected usage of 0, possible slow query.
Loading history...
1632
		'1'            => 'approved',
1633
		'spam'         => 'spam',
1634
		'trash'        => 'trash',
1635
		'post-trashed' => 'post-trashed',
1636
	);
1637
	foreach ( (array) $count as $row ) {
1638
		// Don't count post-trashed toward totals.
1639
		if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
1640
			$total += $row['num_comments'];
1641
		}
1642
		if ( isset( $approved[ $row['comment_approved'] ] ) ) {
1643
			$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
1644
		}
1645
	}
1646
1647
	$stats['total_comments'] = $total;
1648
	foreach ( $approved as $key ) {
1649
		if ( empty( $stats[ $key ] ) ) {
1650
			$stats[ $key ] = 0;
1651
		}
1652
	}
1653
1654
	$stats = (object) $stats;
1655
	Give_Cache::set_group( "comments-{$post_id}", $stats, 'counts' );
1656
1657
	return $stats;
1658
}
1659
1660
add_filter( 'wp_count_comments', 'give_remove_payment_notes_in_comment_counts', 10, 2 );
1661
1662
1663
/**
1664
 * Filter where older than one week
1665
 *
1666
 * @param string $where Where clause.
1667
 *
1668
 * @access public
1669
 * @since  1.0
1670
 *
1671
 * @return string $where Modified where clause.
1672
 */
1673
function give_filter_where_older_than_week( $where = '' ) {
1674
	// Payments older than one week.
1675
	$start = date( 'Y-m-d', strtotime( '-7 days' ) );
1676
	$where .= " AND post_date <= '{$start}'";
1677
1678
	return $where;
1679
}
1680
1681
1682
/**
1683
 * Get Payment Form ID.
1684
 *
1685
 * Retrieves the form title and appends the level name if present.
1686
 *
1687
 * @param array  $payment_meta Payment meta data.
1688
 * @param bool   $only_level   If set to true will only return the level name if multi-level enabled.
1689
 * @param string $separator    The separator between the .
1690
 *
1691
 * @since 1.5
1692
 *
1693
 * @return string $form_title Returns the full title if $only_level is false, otherwise returns the levels title.
1694
 */
1695
function give_get_payment_form_title( $payment_meta, $only_level = false, $separator = '' ) {
1696
	$form_id    = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : 0;
1697
	$price_id   = isset( $payment_meta['price_id'] ) ? $payment_meta['price_id'] : null;
1698
	$form_title = isset( $payment_meta['form_title'] ) ? $payment_meta['form_title'] : '';
1699
1700
	$cache_key = Give_Cache::get_key(
1701
		'give_forms',
1702
		array(
1703
			$form_id,
1704
			$price_id,
1705
			$form_title,
1706
			$only_level,
1707
			$separator
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1708
		)
1709
		, false
1710
	);
1711
	$cache_group = Give_Cache::get_key( 'give-db-queries' );
1712
1713
	if ( ! ( $form_title_html = Give_Cache::get_group( $cache_key, $cache_group ) ) ) {
1714
		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...
1715
			$form_title = '';
1716
		}
1717
1718
		$form_title_html = $form_title;
1719
1720
		// If multi-level, append to the form title.
1721
		if ( give_has_variable_prices( $form_id ) ) {
1722
1723
			// Only add separator if there is a form title.
1724
			if ( ! empty( $form_title ) ) {
1725
				$form_title_html = "{$form_title} {$separator} ";
1726
			}
1727
1728
			$form_title_html .= '<span class="donation-level-text-wrap">';
1729
1730
			if ( 'custom' === $price_id ) {
1731
				$custom_amount_text = give_get_meta( $form_id, '_give_custom_amount_text', true );
1732
				$form_title_html    .= ! empty( $custom_amount_text ) ? $custom_amount_text : __( 'Custom Amount', 'give' );
1733
			} else {
1734
				$form_title_html .= give_get_price_option_name( $form_id, $price_id );
1735
			}
1736
1737
			$form_title_html .= '</span>';
1738
1739
		}
1740
1741
		Give_Cache::set_group( $cache_key, $form_title_html, $cache_group );
1742
	}
1743
1744
	return apply_filters( 'give_get_payment_form_title', $form_title_html, $payment_meta );
1745
1746
}
1747
1748
/**
1749
 * Get Price ID
1750
 *
1751
 * Retrieves the Price ID when provided a proper form ID and price (donation) total
1752
 *
1753
 * @param int    $form_id Form ID.
1754
 * @param string $price   Price ID.
1755
 *
1756
 * @return string $price_id
1757
 */
1758
function give_get_price_id( $form_id, $price ) {
1759
	$price_id = null;
1760
1761
	if ( give_has_variable_prices( $form_id ) ) {
1762
1763
		$levels = give_get_meta( $form_id, '_give_donation_levels', true );
1764
1765
		foreach ( $levels as $level ) {
1766
1767
			$level_amount = give_maybe_sanitize_amount( $level['_give_amount'] );
1768
1769
			// Check that this indeed the recurring price.
1770
			if ( $level_amount == $price ) {
1771
1772
				$price_id = $level['_give_id']['level_id'];
1773
				break;
1774
1775
			}
1776
		}
1777
1778
		if ( is_null( $price_id ) && give_is_custom_price_mode( $form_id ) ) {
1779
			$price_id = 'custom';
1780
		}
1781
	}
1782
1783
	// Price ID must be numeric or string.
1784
	$price_id = ! is_numeric( $price_id ) && ! is_string( $price_id ) ? 0 : $price_id;
1785
1786
	return $price_id;
1787
}
1788
1789
/**
1790
 * Get/Print give form dropdown html
1791
 *
1792
 * This function is wrapper to public method forms_dropdown of Give_HTML_Elements class to get/print form dropdown html.
1793
 * Give_HTML_Elements is defined in includes/class-give-html-elements.php.
1794
 *
1795
 * @param array $args Arguments for form dropdown.
1796
 * @param bool  $echo This parameter decides if print form dropdown html output or not.
1797
 *
1798
 * @since 1.6
1799
 *
1800
 * @return string
1801
 */
1802
function give_get_form_dropdown( $args = array(), $echo = false ) {
1803
	$form_dropdown_html = Give()->html->forms_dropdown( $args );
1804
1805
	if ( ! $echo ) {
1806
		return $form_dropdown_html;
1807
	}
1808
1809
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1810
}
1811
1812
/**
1813
 * Get/Print give form variable price dropdown html
1814
 *
1815
 * @param array $args Arguments for form dropdown.
1816
 * @param bool  $echo This parameter decide if print form dropdown html output or not.
1817
 *
1818
 * @since 1.6
1819
 *
1820
 * @return string|bool
1821
 */
1822
function give_get_form_variable_price_dropdown( $args = array(), $echo = false ) {
1823
1824
	// Check for give form id.
1825
	if ( empty( $args['id'] ) ) {
1826
		return false;
1827
	}
1828
1829
	$form = new Give_Donate_Form( $args['id'] );
1830
1831
	// Check if form has variable prices or not.
1832
	if ( ! $form->ID || ! $form->has_variable_prices() ) {
1833
		return false;
1834
	}
1835
1836
	$variable_prices        = $form->get_prices();
1837
	$variable_price_options = array();
1838
1839
	// Check if multi donation form support custom donation or not.
1840
	if ( $form->is_custom_price_mode() ) {
1841
		$variable_price_options['custom'] = _x( 'Custom', 'custom donation dropdown item', 'give' );
1842
	}
1843
1844
	// Get variable price and ID from variable price array.
1845
	foreach ( $variable_prices as $variable_price ) {
1846
		$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 ) ) );
1847
	}
1848
1849
	// Update options.
1850
	$args = array_merge( $args, array(
1851
		'options' => $variable_price_options,
1852
	) );
1853
1854
	// Generate select html.
1855
	$form_dropdown_html = Give()->html->select( $args );
1856
1857
	if ( ! $echo ) {
1858
		return $form_dropdown_html;
1859
	}
1860
1861
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1862
}
1863
1864
/**
1865
 * Get the price_id from the payment meta.
1866
 *
1867
 * Some gateways use `give_price_id` and others were using just `price_id`;
1868
 * This checks for the difference and falls back to retrieving it from the form as a last resort.
1869
 *
1870
 * @param array $payment_meta Payment Meta.
1871
 *
1872
 * @since 1.8.6
1873
 *
1874
 * @return string
1875
 */
1876
function give_get_payment_meta_price_id( $payment_meta ) {
1877
1878
	if ( isset( $payment_meta['give_price_id'] ) ) {
1879
		$price_id = $payment_meta['give_price_id'];
1880
	} elseif ( isset( $payment_meta['price_id'] ) ) {
1881
		$price_id = $payment_meta['price_id'];
1882
	} else {
1883
		$price_id = give_get_price_id( $payment_meta['give_form_id'], $payment_meta['price'] );
1884
	}
1885
1886
	return apply_filters( 'give_get_payment_meta_price_id', $price_id );
1887
1888
}
1889