Test Failed
Push — release/2.1 ( d820cd...c669cb )
by Ravinder
05:21
created

functions.php ➔ give_insert_payment_note()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 48
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 21
nc 2
nop 2
dl 0
loc 48
rs 9.125
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(
90
				array(
91
					'meta_key'       => '_give_payment_purchase_key',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
92
					'meta_value'     => $value,
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
93
					'posts_per_page' => 1,
94
					'fields'         => 'ids',
95
				)
96
			);
97
98
			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...
99
				$payment = new Give_Payment( $payment[0] );
100
			}
101
102
			break;
103
104 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...
105
			$payment = give_get_payments(
106
				array(
107
					'meta_key'       => '_give_payment_number',
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
108
					'meta_value'     => $value,
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
109
					'posts_per_page' => 1,
110
					'fields'         => 'ids',
111
				)
112
			);
113
114
			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...
115
				$payment = new Give_Payment( $payment[0] );
116
			}
117
118
			break;
119
120
		default:
121
			return false;
122
	}// End switch().
123
124
	if ( $payment ) {
125
		return $payment;
126
	}
127
128
	return false;
129
}
130
131
/**
132
 * Insert Payment
133
 *
134
 * @since  1.0
135
 *
136
 * @param  array $payment_data Arguments passed.
137
 *
138
 * @return int|bool Payment ID if payment is inserted, false otherwise.
139
 */
140
function give_insert_payment( $payment_data = array() ) {
141
142
	if ( empty( $payment_data ) ) {
143
		return false;
144
	}
145
146
	/**
147
	 * Fire the filter on donation data before insert.
148
	 *
149
	 * @since 1.8.15
150
	 *
151
	 * @param array $payment_data Arguments passed.
152
	 */
153
	$payment_data = apply_filters( 'give_pre_insert_payment', $payment_data );
154
155
	$payment    = new Give_Payment();
156
	$gateway    = ! empty( $payment_data['gateway'] ) ? $payment_data['gateway'] : '';
157
	$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...
158
	$form_id    = isset( $payment_data['give_form_id'] ) ? $payment_data['give_form_id'] : 0;
159
	$price_id   = give_get_payment_meta_price_id( $payment_data );
160
	$form_title = isset( $payment_data['give_form_title'] ) ? $payment_data['give_form_title'] : get_the_title( $form_id );
161
162
	// Set properties.
163
	$payment->total          = $payment_data['price'];
164
	$payment->status         = ! empty( $payment_data['status'] ) ? $payment_data['status'] : 'pending';
165
	$payment->currency       = ! empty( $payment_data['currency'] ) ? $payment_data['currency'] : give_get_currency( $payment_data['give_form_id'], $payment_data );
166
	$payment->user_info      = $payment_data['user_info'];
167
	$payment->gateway        = $gateway;
168
	$payment->form_title     = $form_title;
169
	$payment->form_id        = $form_id;
170
	$payment->price_id       = $price_id;
171
	$payment->donor_id       = ( ! empty( $payment_data['donor_id'] ) ? $payment_data['donor_id'] : '' );
172
	$payment->user_id        = $payment_data['user_info']['id'];
173
	$payment->email          = $payment_data['user_email'];
174
	$payment->first_name     = $payment_data['user_info']['first_name'];
175
	$payment->last_name      = $payment_data['user_info']['last_name'];
176
	$payment->email          = $payment_data['user_info']['email'];
177
	$payment->ip             = give_get_ip();
0 ignored issues
show
Documentation Bug introduced by
It seems like give_get_ip() can also be of type array. However, the property $ip is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
178
	$payment->key            = $payment_data['purchase_key'];
179
	$payment->mode           = ( ! empty( $payment_data['mode'] ) ? (string) $payment_data['mode'] : ( give_is_test_mode() ? 'test' : 'live' ) );
180
	$payment->parent_payment = ! empty( $payment_data['parent'] ) ? absint( $payment_data['parent'] ) : '';
181
182
	// Add the donation.
183
	$args = array(
184
		'price'    => $payment->total,
185
		'price_id' => $payment->price_id,
186
	);
187
188
	$payment->add_donation( $payment->form_id, $args );
189
190
	// Set date if present.
191
	if ( isset( $payment_data['post_date'] ) ) {
192
		$payment->date = $payment_data['post_date'];
193
	}
194
195
	// Save payment.
196
	$payment->save();
197
198
	// Setup donor id.
199
	if ( empty( $payment_data['user_info']['id'] ) ) {
200
		$payment_data['user_info']['id'] = $payment->donor_id;
201
	}
202
203
	/**
204
	 * Fires while inserting payments.
205
	 *
206
	 * @since 1.0
207
	 *
208
	 * @param int   $payment_id   The payment ID.
209
	 * @param array $payment_data Arguments passed.
210
	 */
211
	do_action( 'give_insert_payment', $payment->ID, $payment_data );
212
213
	// Return payment ID upon success.
214
	if ( ! empty( $payment->ID ) ) {
215
		return $payment->ID;
216
	}
217
218
	// Return false if no payment was inserted.
219
	return false;
220
221
}
222
223
/**
224
 * Create payment.
225
 *
226
 * @param $payment_data
227
 *
228
 * @return bool|int
229
 */
230
function give_create_payment( $payment_data ) {
231
232
	$form_id  = intval( $payment_data['post_data']['give-form-id'] );
233
	$price_id = isset( $payment_data['post_data']['give-price-id'] ) ? $payment_data['post_data']['give-price-id'] : '';
234
235
	// Collect payment data.
236
	$insert_payment_data = array(
237
		'price'           => $payment_data['price'],
238
		'give_form_title' => $payment_data['post_data']['give-form-title'],
239
		'give_form_id'    => $form_id,
240
		'give_price_id'   => $price_id,
241
		'date'            => $payment_data['date'],
242
		'user_email'      => $payment_data['user_email'],
243
		'purchase_key'    => $payment_data['purchase_key'],
244
		'currency'        => give_get_currency( $form_id, $payment_data ),
245
		'user_info'       => $payment_data['user_info'],
246
		'status'          => 'pending',
247
		'gateway'         => 'paypal',
248
	);
249
250
	/**
251
	 * Filter the payment params.
252
	 *
253
	 * @since 1.8
254
	 *
255
	 * @param array $insert_payment_data
256
	 */
257
	$insert_payment_data = apply_filters( 'give_create_payment', $insert_payment_data );
258
259
	// Record the pending payment.
260
	return give_insert_payment( $insert_payment_data );
261
}
262
263
/**
264
 * Updates a payment status.
265
 *
266
 * @param  int    $payment_id Payment ID.
267
 * @param  string $new_status New Payment Status. Default is 'publish'.
268
 *
269
 * @since  1.0
270
 *
271
 * @return bool
272
 */
273
function give_update_payment_status( $payment_id, $new_status = 'publish' ) {
274
275
	$updated = false;
276
	$payment = new Give_Payment( $payment_id );
277
278
	if ( $payment && $payment->ID > 0 ) {
279
280
		$payment->status = $new_status;
281
		$updated         = $payment->save();
282
283
	}
284
285
	return $updated;
286
}
287
288
289
/**
290
 * Deletes a Donation
291
 *
292
 * @since  1.0
293
 *
294
 * @param  int  $payment_id   Payment ID (default: 0).
295
 * @param  bool $update_donor If we should update the donor stats (default:true).
296
 *
297
 * @return void
298
 */
299
function give_delete_donation( $payment_id = 0, $update_donor = true ) {
300
	$payment = new Give_Payment( $payment_id );
301
302
	// Bailout.
303
	if ( ! $payment->ID ) {
304
		return;
305
	}
306
307
	$amount = give_donation_amount( $payment_id );
308
	$status = $payment->post_status;
309
	$donor  = new Give_Donor( $payment->donor_id );
310
311
	// Only undo donations that aren't these statuses.
312
	$dont_undo_statuses = apply_filters(
313
		'give_undo_donation_statuses', array(
314
			'pending',
315
			'cancelled',
316
		)
317
	);
318
319
	if ( ! in_array( $status, $dont_undo_statuses ) ) {
320
		give_undo_donation( $payment_id );
321
	}
322
323
	// Only undo donations that aren't these statuses.
324
	$status_to_decrease_stats = apply_filters( 'give_decrease_donor_statuses', array( 'publish' ) );
325
326
	if ( in_array( $status, $status_to_decrease_stats ) ) {
327
328
		// Only decrease earnings if they haven't already been decreased (or were never increased for this payment).
329
		give_decrease_total_earnings( $amount );
330
331
		// @todo: Refresh only range related stat cache
332
		give_delete_donation_stats();
333
334
		if ( $donor->id && $update_donor ) {
335
336
			// Decrement the stats for the donor.
337
			$donor->decrease_donation_count();
338
			$donor->decrease_value( $amount );
339
340
		}
341
	}
342
343
	/**
344
	 * Fires before deleting payment.
345
	 *
346
	 * @param int $payment_id Payment ID.
347
	 *
348
	 * @since 1.0
349
	 */
350
	do_action( 'give_payment_delete', $payment_id );
351
352
	if ( $donor->id && $update_donor ) {
353
		// Remove the payment ID from the donor.
354
		$donor->remove_payment( $payment_id );
355
	}
356
357
	// Remove the payment.
358
	wp_delete_post( $payment_id, true );
359
360
	// Remove related sale log entries.
361
	Give()->logs->delete_logs( $payment_id );
362
363
	/**
364
	 * Fires after payment deleted.
365
	 *
366
	 * @param int $payment_id Payment ID.
367
	 *
368
	 * @since 1.0
369
	 */
370
	do_action( 'give_payment_deleted', $payment_id );
371
}
372
373
/**
374
 * Undo Donation
375
 *
376
 * Undoes a donation, including the decrease of donations and earning stats.
377
 * Used for when refunding or deleting a donation.
378
 *
379
 * @param  int $payment_id Payment ID.
380
 *
381
 * @since  1.0
382
 *
383
 * @return void
384
 */
385
function give_undo_donation( $payment_id ) {
386
387
	$payment = new Give_Payment( $payment_id );
388
389
	$maybe_decrease_earnings = apply_filters( 'give_decrease_earnings_on_undo', true, $payment, $payment->form_id );
390
	if ( true === $maybe_decrease_earnings ) {
391
		// Decrease earnings.
392
		give_decrease_form_earnings( $payment->form_id, $payment->total );
393
	}
394
395
	$maybe_decrease_donations = apply_filters( 'give_decrease_donations_on_undo', true, $payment, $payment->form_id );
396
	if ( true === $maybe_decrease_donations ) {
397
		// Decrease donation count.
398
		give_decrease_donation_count( $payment->form_id );
399
	}
400
401
}
402
403
404
/**
405
 * Count Payments
406
 *
407
 * Returns the total number of payments recorded.
408
 *
409
 * @param  array $args Arguments passed.
410
 *
411
 * @since  1.0
412
 *
413
 * @return object $stats Contains the number of payments per payment status.
414
 */
415
function give_count_payments( $args = array() ) {
416
	// Backward compatibility.
417
	if ( ! empty( $args['start-date'] ) ) {
418
		$args['start_date'] = $args['start-date'];
419
		unset( $args['start-date'] );
420
	}
421
422
	if ( ! empty( $args['end-date'] ) ) {
423
		$args['end_date'] = $args['end-date'];
424
		unset( $args['end-date'] );
425
	}
426
427
	if ( ! empty( $args['form_id'] ) ) {
428
		$args['give_forms'] = $args['form_id'];
429
		unset( $args['form_id'] );
430
	}
431
432
	// Extract all donations
433
	$args['number']   = - 1;
434
	$args['group_by'] = 'post_status';
435
	$args['count']    = 'true';
436
437
	$donations_obj   = new Give_Payments_Query( $args );
438
	$donations_count = $donations_obj->get_payment_by_group();
439
440
	/**
441
	 * Filter the payment counts group by status
442
	 *
443
	 * @since 1.0
444
	 */
445
	return (object) apply_filters( 'give_count_payments', $donations_count, $args, $donations_obj );
446
}
447
448
449
/**
450
 * Check For Existing Payment
451
 *
452
 * @param  int $payment_id Payment ID.
453
 *
454
 * @since  1.0
455
 *
456
 * @return bool $exists True if payment exists, false otherwise.
457
 */
458
function give_check_for_existing_payment( $payment_id ) {
459
	global $wpdb;
460
461
	return (bool) $wpdb->get_var(
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...
462
		$wpdb->prepare(
463
			"
464
			SELECT ID
465
			FROM {$wpdb->posts}
466
			WHERE ID=%s
467
			AND post_status=%s
468
			",
469
			$payment_id,
470
			'publish'
471
		)
472
	);
473
}
474
475
/**
476
 * Get Payment Status
477
 *
478
 * @param WP_Post|Give_Payment|int $payment_id      Payment object or payment ID.
479
 * @param bool                     $return_label Whether to return the translated status label instead of status value.
480
 *                                               Default false.
481
 *
482
 * @since 1.0
483
 *
484
 * @return bool|mixed True if payment status exists, false otherwise.
485
 */
486
function give_get_payment_status( $payment_id, $return_label = false ) {
487
488
	if ( ! is_numeric( $payment_id ) ) {
489
		if (
490
			$payment_id instanceof  Give_Payment
491
			|| $payment_id instanceof WP_Post
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

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