Test Failed
Push — issue/2900 ( f2122b )
by Ravinder
07:32
created

functions.php ➔ give_delete_payment_note()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 3
rs 10
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();
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...
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
	// Save payment.
193
	$payment->save();
194
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
195
196
	// Setup donor id.
197
	if( empty( $payment_data['user_info']['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...
198
		$payment_data['user_info']['id'] = $payment->donor_id;
199
	}
200
201
	/**
202
	 * Fires while inserting payments.
203
	 *
204
	 * @since 1.0
205
	 *
206
	 * @param int   $payment_id   The payment ID.
207
	 * @param array $payment_data Arguments passed.
208
	 */
209
	do_action( 'give_insert_payment', $payment->ID, $payment_data );
210
211
	// Return payment ID upon success.
212
	if ( ! empty( $payment->ID ) ) {
213
		return $payment->ID;
214
	}
215
216
	// Return false if no payment was inserted.
217
	return false;
218
219
}
220
221
/**
222
 * Create payment.
223
 *
224
 * @param $payment_data
225
 *
226
 * @return bool|int
227
 */
228
function give_create_payment( $payment_data ) {
229
230
	$form_id  = intval( $payment_data['post_data']['give-form-id'] );
231
	$price_id = isset( $payment_data['post_data']['give-price-id'] ) ? $payment_data['post_data']['give-price-id'] : '';
232
233
	// Collect payment data.
234
	$insert_payment_data = array(
235
		'price'           => $payment_data['price'],
236
		'give_form_title' => $payment_data['post_data']['give-form-title'],
237
		'give_form_id'    => $form_id,
238
		'give_price_id'   => $price_id,
239
		'date'            => $payment_data['date'],
240
		'user_email'      => $payment_data['user_email'],
241
		'purchase_key'    => $payment_data['purchase_key'],
242
		'currency'        => give_get_currency( $form_id, $payment_data ),
243
		'user_info'       => $payment_data['user_info'],
244
		'status'          => 'pending',
245
		'gateway'         => 'paypal',
246
	);
247
248
	/**
249
	 * Filter the payment params.
250
	 *
251
	 * @since 1.8
252
	 *
253
	 * @param array $insert_payment_data
254
	 */
255
	$insert_payment_data = apply_filters( 'give_create_payment', $insert_payment_data );
256
257
	// Record the pending payment.
258
	return give_insert_payment( $insert_payment_data );
259
}
260
261
/**
262
 * Updates a payment status.
263
 *
264
 * @param  int    $payment_id Payment ID.
265
 * @param  string $new_status New Payment Status. Default is 'publish'.
266
 *
267
 * @since  1.0
268
 *
269
 * @return bool
270
 */
271
function give_update_payment_status( $payment_id, $new_status = 'publish' ) {
272
273
	$updated = false;
274
	$payment = new Give_Payment( $payment_id );
275
276
	if ( $payment && $payment->ID > 0 ) {
277
278
		$payment->status = $new_status;
279
		$updated         = $payment->save();
280
281
	}
282
283
	return $updated;
284
}
285
286
287
/**
288
 * Deletes a Donation
289
 *
290
 * @since  1.0
291
 *
292
 * @param  int  $payment_id   Payment ID (default: 0).
293
 * @param  bool $update_donor If we should update the donor stats (default:true).
294
 *
295
 * @return void
296
 */
297
function give_delete_donation( $payment_id = 0, $update_donor = true ) {
298
	$payment = new Give_Payment( $payment_id );
299
300
	// Bailout.
301
	if ( ! $payment->ID ) {
302
		return;
303
	}
304
305
	$amount   = give_donation_amount( $payment_id );
306
	$status   = $payment->post_status;
307
	$donor_id = give_get_payment_donor_id( $payment_id );
308
	$donor    = new Give_Donor( $donor_id );
309
310
	// Only undo donations that aren't these statuses.
311
	$dont_undo_statuses = apply_filters( 'give_undo_donation_statuses', array(
312
		'pending',
313
		'cancelled',
314
	) );
315
316
	if ( ! in_array( $status, $dont_undo_statuses ) ) {
317
		give_undo_donation( $payment_id );
318
	}
319
320
	// Only undo donations that aren't these statuses.
321
	$status_to_decrease_stats = apply_filters( 'give_decrease_donor_statuses', array( 'publish' ) );
322
323
	if ( in_array( $status, $status_to_decrease_stats ) ) {
324
325
		// Only decrease earnings if they haven't already been decreased (or were never increased for this payment).
326
		give_decrease_total_earnings( $amount );
327
328
		// @todo: Refresh only range related stat cache
329
		give_delete_donation_stats();
330
331
		if ( $donor->id && $update_donor ) {
332
333
			// Decrement the stats for the donor.
334
			$donor->decrease_donation_count();
335
			$donor->decrease_value( $amount );
336
337
		}
338
	}
339
340
	/**
341
	 * Fires before deleting payment.
342
	 *
343
	 * @param int $payment_id Payment ID.
344
	 *
345
	 * @since 1.0
346
	 */
347
	do_action( 'give_payment_delete', $payment_id );
348
349
	if ( $donor->id && $update_donor ) {
350
		// Remove the payment ID from the donor.
351
		$donor->remove_payment( $payment_id );
352
	}
353
354
	// Remove the payment.
355
	wp_delete_post( $payment_id, true );
356
357
	// Remove related sale log entries.
358
	Give()->logs->delete_logs( $payment_id );
359
360
	/**
361
	 * Fires after payment deleted.
362
	 *
363
	 * @param int $payment_id Payment ID.
364
	 *
365
	 * @since 1.0
366
	 */
367
	do_action( 'give_payment_deleted', $payment_id );
368
}
369
370
/**
371
 * Undo Donation
372
 *
373
 * Undoes a donation, including the decrease of donations and earning stats.
374
 * Used for when refunding or deleting a donation.
375
 *
376
 * @param  int $payment_id Payment ID.
377
 *
378
 * @since  1.0
379
 *
380
 * @return void
381
 */
382
function give_undo_donation( $payment_id ) {
383
384
	$payment = new Give_Payment( $payment_id );
385
386
	$maybe_decrease_earnings = apply_filters( 'give_decrease_earnings_on_undo', true, $payment, $payment->form_id );
387
	if ( true === $maybe_decrease_earnings ) {
388
		// Decrease earnings.
389
		give_decrease_form_earnings( $payment->form_id, $payment->total );
390
	}
391
392
	$maybe_decrease_donations = apply_filters( 'give_decrease_donations_on_undo', true, $payment, $payment->form_id );
393
	if ( true === $maybe_decrease_donations ) {
394
		// Decrease donation count.
395
		give_decrease_donation_count( $payment->form_id );
396
	}
397
398
}
399
400
401
/**
402
 * Count Payments
403
 *
404
 * Returns the total number of payments recorded.
405
 *
406
 * @param  array $args Arguments passed.
407
 *
408
 * @since  1.0
409
 *
410
 * @return object $stats Contains the number of payments per payment status.
411
 */
412
function give_count_payments( $args = array() ) {
413
	// Backward compatibility.
414
	if ( ! empty( $args['start-date'] ) ) {
415
		$args['start_date'] = $args['start-date'];
416
		unset( $args['start-date'] );
417
	}
418
419
	if ( ! empty( $args['end-date'] ) ) {
420
		$args['end_date'] = $args['end-date'];
421
		unset( $args['end-date'] );
422
	}
423
424
	if ( ! empty( $args['form_id'] ) ) {
425
		$args['give_forms'] = $args['form_id'];
426
		unset( $args['form_id'] );
427
	}
428
429
	// Extract all donations
430
	$args['number']   = - 1;
431
	$args['group_by'] = 'post_status';
432
	$args['count']    = 'true';
433
434
	$donations_obj   = new Give_Payments_Query( $args );
435
	$donations_count = $donations_obj->get_payment_by_group();
436
437
	/**
438
	 * Filter the payment counts group by status
439
	 *
440
	 * @since 1.0
441
	 */
442
	return (object) apply_filters( 'give_count_payments', $donations_count, $args, $donations_obj );
443
}
444
445
446
/**
447
 * Check For Existing Payment
448
 *
449
 * @param  int $payment_id Payment ID.
450
 *
451
 * @since  1.0
452
 *
453
 * @return bool $exists True if payment exists, false otherwise.
454
 */
455
function give_check_for_existing_payment( $payment_id ) {
456
	$exists  = false;
457
	$payment = new Give_Payment( $payment_id );
458
459
	if ( $payment_id === $payment->ID && 'publish' === $payment->status ) {
460
		$exists = true;
461
	}
462
463
	return $exists;
464
}
465
466
/**
467
 * Get Payment Status
468
 *
469
 * @param WP_Post|Give_Payment|int $payment      Payment object or payment ID.
470
 * @param bool                     $return_label Whether to return the translated status label instead of status value.
471
 *                                               Default false.
472
 *
473
 * @since 1.0
474
 *
475
 * @return bool|mixed True if payment status exists, false otherwise.
476
 */
477
function give_get_payment_status( $payment, $return_label = false ) {
478
479
	if ( is_numeric( $payment ) ) {
480
481
		$payment = new Give_Payment( $payment );
482
483
		if ( ! $payment->ID > 0 ) {
484
			return false;
485
		}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
486
487
	}
488
489
	if ( ! is_object( $payment ) || ! isset( $payment->post_status ) ) {
490
		return false;
491
	}
492
493
	$statuses = give_get_payment_statuses();
494
495
	if ( ! is_array( $statuses ) || empty( $statuses ) ) {
496
		return false;
497
	}
498
499
	// Get payment object if not already given.
500
	$payment = $payment instanceof Give_Payment ? $payment : new Give_Payment( $payment->ID );
501
502
	if ( array_key_exists( $payment->status, $statuses ) ) {
503
		if ( true === $return_label ) {
504
			// Return translated status label.
505
			return $statuses[ $payment->status ];
506
		} else {
507
			// Account that our 'publish' status is labeled 'Complete'
508
			$post_status = 'publish' === $payment->status ? 'Complete' : $payment->post_status;
509
510
			// Make sure we're matching cases, since they matter
511
			return array_search( strtolower( $post_status ), array_map( 'strtolower', $statuses ) );
512
		}
513
	}
514
515
	return false;
516
}
517
518
/**
519
 * Retrieves all available statuses for payments.
520
 *
521
 * @since  1.0
522
 *
523
 * @return array $payment_status All the available payment statuses.
524
 */
525
function give_get_payment_statuses() {
526
	$payment_statuses = array(
527
		'pending'     => __( 'Pending', 'give' ),
528
		'publish'     => __( 'Complete', 'give' ),
529
		'refunded'    => __( 'Refunded', 'give' ),
530
		'failed'      => __( 'Failed', 'give' ),
531
		'cancelled'   => __( 'Cancelled', 'give' ),
532
		'abandoned'   => __( 'Abandoned', 'give' ),
533
		'preapproval' => __( 'Pre-Approved', 'give' ),
534
		'processing'  => __( 'Processing', 'give' ),
535
		'revoked'     => __( 'Revoked', 'give' ),
536
	);
537
538
	return apply_filters( 'give_payment_statuses', $payment_statuses );
539
}
540
541
/**
542
 * Get Payment Status Keys
543
 *
544
 * Retrieves keys for all available statuses for payments
545
 *
546
 * @since 1.0
547
 *
548
 * @return array $payment_status All the available payment statuses.
549
 */
550
function give_get_payment_status_keys() {
551
	$statuses = array_keys( give_get_payment_statuses() );
552
	asort( $statuses );
553
554
	return array_values( $statuses );
555
}
556
557
/**
558
 * Get Earnings By Date
559
 *
560
 * @param int $day       Day number. Default is null.
561
 * @param int $month_num Month number. Default is null.
562
 * @param int $year      Year number. Default is null.
563
 * @param int $hour      Hour number. Default is null.
564
 *
565
 * @since 1.0
566
 *
567
 * @return int $earnings Earnings
568
 */
569
function give_get_earnings_by_date( $day = null, $month_num, $year = null, $hour = null ) {
570
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_earnings() method instead.
571
572
	global $wpdb;
573
	$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...
574
575
	$args = array(
576
		'post_type'              => 'give_payment',
577
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
578
		'year'                   => $year,
579
		'monthnum'               => $month_num,
580
		'post_status'            => array( 'publish' ),
581
		'fields'                 => 'ids',
582
		'update_post_term_cache' => false,
583
	);
584
	if ( ! empty( $day ) ) {
585
		$args['day'] = $day;
586
	}
587
588
	if ( isset( $hour ) ) {
589
		$args['hour'] = $hour;
590
	}
591
592
	$args = apply_filters( 'give_get_earnings_by_date_args', $args );
593
	$key  = Give_Cache::get_key( 'give_stats', $args );
594
595 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...
596
		$earnings = false;
597
	} else {
598
		$earnings = Give_Cache::get( $key );
599
	}
600
601
	if ( false === $earnings ) {
602
		$donations = get_posts( $args );
603
		$earnings  = 0;
604
		if ( $donations ) {
605
			$donations      = implode( ',', $donations );
606
			$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...
607
608
			/**
609
			 * Filter The earnings by dates.
610
			 *
611
			 * @since 1.8.17
612
			 *
613
			 * @param float $earning_totals Total earnings between the dates.
614
			 * @param array $donations      Donations lists.
615
			 * @param array $args           Donation query args.
616
			 */
617
			$earnings = apply_filters( 'give_get_earnings_by_date', $earning_totals, $donations, $args );
618
		}
619
		// Cache the results for one hour.
620
		Give_Cache::set( $key, $earnings, HOUR_IN_SECONDS );
621
	}
622
623
	return round( $earnings, 2 );
624
}
625
626
/**
627
 * Get Donations (sales) By Date
628
 *
629
 * @param int $day       Day number. Default is null.
630
 * @param int $month_num Month number. Default is null.
631
 * @param int $year      Year number. Default is null.
632
 * @param int $hour      Hour number. Default is null.
633
 *
634
 * @since 1.0
635
 *
636
 * @return int $count Sales
637
 */
638
function give_get_sales_by_date( $day = null, $month_num = null, $year = null, $hour = null ) {
639
640
	// This is getting deprecated soon. Use Give_Payment_Stats with the get_sales() method instead.
641
	$args = array(
642
		'post_type'              => 'give_payment',
643
		'nopaging'               => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
644
		'year'                   => $year,
645
		'fields'                 => 'ids',
646
		'post_status'            => array( 'publish' ),
647
		'update_post_meta_cache' => false,
648
		'update_post_term_cache' => false,
649
	);
650
651
	$show_free = apply_filters( 'give_sales_by_date_show_free', true, $args );
652
653
	if ( false === $show_free ) {
654
		$args['meta_query'] = array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
655
			array(
656
				'key'     => '_give_payment_total',
657
				'value'   => 0,
658
				'compare' => '>',
659
				'type'    => 'NUMERIC',
660
			),
661
		);
662
	}
663
664
	if ( ! empty( $month_num ) ) {
665
		$args['monthnum'] = $month_num;
666
	}
667
668
	if ( ! empty( $day ) ) {
669
		$args['day'] = $day;
670
	}
671
672
	if ( isset( $hour ) ) {
673
		$args['hour'] = $hour;
674
	}
675
676
	$args = apply_filters( 'give_get_sales_by_date_args', $args );
677
678
	$key = Give_Cache::get_key( 'give_stats', $args );
679
680 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...
681
		$count = false;
682
	} else {
683
		$count = Give_Cache::get( $key );
684
	}
685
686
	if ( false === $count ) {
687
		$donations = new WP_Query( $args );
688
		$count     = (int) $donations->post_count;
689
		// Cache the results for one hour.
690
		Give_Cache::set( $key, $count, HOUR_IN_SECONDS );
691
	}
692
693
	return $count;
694
}
695
696
/**
697
 * Checks whether a payment has been marked as complete.
698
 *
699
 * @param int $payment_id Payment ID to check against.
700
 *
701
 * @since 1.0
702
 *
703
 * @return bool $ret True if complete, false otherwise.
704
 */
705
function give_is_payment_complete( $payment_id ) {
706
	$payment = new Give_Payment( $payment_id );
707
708
	$ret = false;
709
710
	if ( $payment->ID > 0 ) {
711
712
		if ( (int) $payment_id === (int) $payment->ID && 'publish' == $payment->status ) {
713
			$ret = true;
714
		}
715
	}
716
717
	return apply_filters( 'give_is_payment_complete', $ret, $payment_id, $payment->post_status );
718
}
719
720
/**
721
 * Get Total Donations.
722
 *
723
 * @since 1.0
724
 *
725
 * @return int $count Total number of donations.
726
 */
727
function give_get_total_donations() {
728
729
	$payments = give_count_payments();
730
731
	return $payments->publish;
732
}
733
734
/**
735
 * Get Total Earnings
736
 *
737
 * @param bool $recalculate Recalculate earnings forcefully.
738
 *
739
 * @since 1.0
740
 *
741
 * @return float $total Total earnings.
742
 */
743
function give_get_total_earnings( $recalculate = false ) {
744
745
	$total      = get_option( 'give_earnings_total', 0 );
746
	$meta_table = __give_v20_bc_table_details( 'payment' );
747
748
	// Calculate total earnings.
749
	if ( ! $total || $recalculate ) {
750
		global $wpdb;
751
752
		$total = (float) 0;
753
754
		$args = apply_filters( 'give_get_total_earnings_args', array(
755
			'offset' => 0,
756
			'number' => - 1,
757
			'status' => array( 'publish' ),
758
			'fields' => 'ids',
759
		) );
760
761
		$payments = give_get_payments( $args );
762
		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...
763
764
			/**
765
			 * If performing a donation, we need to skip the very last payment in the database,
766
			 * since it calls give_increase_total_earnings() on completion,
767
			 * which results in duplicated earnings for the very first donation.
768
			 */
769
			if ( did_action( 'give_update_payment_status' ) ) {
770
				array_pop( $payments );
771
			}
772
773
			if ( ! empty( $payments ) ) {
774
				$payments = implode( ',', $payments );
775
				$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...
776
			}
777
		}
778
779
		update_option( 'give_earnings_total', $total, 'no' );
780
	}
781
782
	if ( $total < 0 ) {
783
		$total = 0; // Don't ever show negative earnings.
784
	}
785
786
	return apply_filters( 'give_total_earnings', round( $total, give_get_price_decimals() ), $total );
787
}
788
789
/**
790
 * Increase the Total Earnings
791
 *
792
 * @param int $amount The amount you would like to increase the total earnings by. Default is 0.
793
 *
794
 * @since 1.0
795
 *
796
 * @return float $total Total earnings.
797
 */
798
function give_increase_total_earnings( $amount = 0 ) {
799
	$total = give_get_total_earnings();
800
	$total += $amount;
801
	update_option( 'give_earnings_total', $total );
802
803
	return $total;
804
}
805
806
/**
807
 * Decrease the Total Earnings
808
 *
809
 * @param int $amount The amount you would like to decrease the total earnings by.
810
 *
811
 * @since 1.0
812
 *
813
 * @return float $total Total earnings.
814
 */
815
function give_decrease_total_earnings( $amount = 0 ) {
816
	$total = give_get_total_earnings();
817
	$total -= $amount;
818
	if ( $total < 0 ) {
819
		$total = 0;
820
	}
821
	update_option( 'give_earnings_total', $total );
822
823
	return $total;
824
}
825
826
/**
827
 * Get Payment Meta for a specific Payment
828
 *
829
 * @param int    $payment_id Payment ID.
830
 * @param string $meta_key   The meta key to pull.
831
 * @param bool   $single     Pull single meta entry or as an object.
832
 *
833
 * @since 1.0
834
 *
835
 * @return mixed $meta Payment Meta.
836
 */
837
function give_get_payment_meta( $payment_id = 0, $meta_key = '_give_payment_meta', $single = true ) {
838
	$payment = new Give_Payment( $payment_id );
839
840
	return $payment->get_meta( $meta_key, $single );
841
}
842
843
/**
844
 * Update the meta for a payment
845
 *
846
 * @param  int    $payment_id Payment ID.
847
 * @param  string $meta_key   Meta key to update.
848
 * @param  string $meta_value Value to update to.
849
 * @param  string $prev_value Previous value.
850
 *
851
 * @return mixed Meta ID if successful, false if unsuccessful.
852
 */
853
function give_update_payment_meta( $payment_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
854
	$payment = new Give_Payment( $payment_id );
855
856
	return $payment->update_meta( $meta_key, $meta_value, $prev_value );
857
}
858
859
/**
860
 * Get the user_info Key from Payment Meta
861
 *
862
 * @param int $payment_id Payment ID.
863
 *
864
 * @since 1.0
865
 *
866
 * @return array $user_info User Info Meta Values.
867
 */
868
function give_get_payment_meta_user_info( $payment_id ) {
869
	$payment = new Give_Payment( $payment_id );
870
871
	return $payment->user_info;
872
}
873
874
/**
875
 * Get the donations Key from Payment Meta
876
 *
877
 * Retrieves the form_id from a (Previously titled give_get_payment_meta_donations)
878
 *
879
 * @param int $payment_id Payment ID.
880
 *
881
 * @since 1.0
882
 *
883
 * @return int $form_id Form ID.
884
 */
885
function give_get_payment_form_id( $payment_id ) {
886
	$payment = new Give_Payment( $payment_id );
887
888
	return $payment->form_id;
889
}
890
891
/**
892
 * Get the user email associated with a payment
893
 *
894
 * @param int $payment_id Payment ID.
895
 *
896
 * @since 1.0
897
 *
898
 * @return string $email User email.
899
 */
900
function give_get_payment_user_email( $payment_id ) {
901
	$payment = new Give_Payment( $payment_id );
902
903
	return $payment->email;
904
}
905
906
/**
907
 * Is the payment provided associated with a user account
908
 *
909
 * @param int $payment_id The payment ID.
910
 *
911
 * @since 1.3
912
 *
913
 * @return bool $is_guest_payment If the payment is associated with a user (false) or not (true)
914
 */
915
function give_is_guest_payment( $payment_id ) {
916
	$payment_user_id  = give_get_payment_user_id( $payment_id );
917
	$is_guest_payment = ! empty( $payment_user_id ) && $payment_user_id > 0 ? false : true;
918
919
	return (bool) apply_filters( 'give_is_guest_payment', $is_guest_payment, $payment_id );
920
}
921
922
/**
923
 * Get the user ID associated with a payment
924
 *
925
 * @param int $payment_id Payment ID.
926
 *
927
 * @since 1.3
928
 *
929
 * @return int $user_id User ID.
930
 */
931
function give_get_payment_user_id( $payment_id ) {
932
	$payment = new Give_Payment( $payment_id );
933
934
	return $payment->user_id;
935
}
936
937
/**
938
 * Get the donor ID associated with a payment.
939
 *
940
 * @param int $payment_id Payment ID.
941
 *
942
 * @since 1.0
943
 *
944
 * @return int $payment->customer_id Donor ID.
945
 */
946
function give_get_payment_donor_id( $payment_id ) {
947
	$payment = new Give_Payment( $payment_id );
948
949
	return $payment->customer_id;
950
}
951
952
/**
953
 * Get the IP address used to make a donation
954
 *
955
 * @param int $payment_id Payment ID.
956
 *
957
 * @since 1.0
958
 *
959
 * @return string $ip User IP.
960
 */
961
function give_get_payment_user_ip( $payment_id ) {
962
	$payment = new Give_Payment( $payment_id );
963
964
	return $payment->ip;
965
}
966
967
/**
968
 * Get the date a payment was completed
969
 *
970
 * @param int $payment_id Payment ID.
971
 *
972
 * @since 1.0
973
 *
974
 * @return string $date The date the payment was completed.
975
 */
976
function give_get_payment_completed_date( $payment_id = 0 ) {
977
	$payment = new Give_Payment( $payment_id );
978
979
	return $payment->completed_date;
980
}
981
982
/**
983
 * Get the gateway associated with a payment
984
 *
985
 * @param int $payment_id Payment ID.
986
 *
987
 * @since 1.0
988
 *
989
 * @return string $gateway Gateway.
990
 */
991
function give_get_payment_gateway( $payment_id ) {
992
	$payment = new Give_Payment( $payment_id );
993
994
	return $payment->gateway;
995
}
996
997
/**
998
 * Get the currency code a payment was made in
999
 *
1000
 * @param int $payment_id Payment ID.
1001
 *
1002
 * @since 1.0
1003
 *
1004
 * @return string $currency The currency code.
1005
 */
1006
function give_get_payment_currency_code( $payment_id = 0 ) {
1007
	$payment = new Give_Payment( $payment_id );
1008
1009
	return $payment->currency;
1010
}
1011
1012
/**
1013
 * Get the currency name a payment was made in
1014
 *
1015
 * @param int $payment_id Payment ID.
1016
 *
1017
 * @since 1.0
1018
 *
1019
 * @return string $currency The currency name.
1020
 */
1021
function give_get_payment_currency( $payment_id = 0 ) {
1022
	$currency = give_get_payment_currency_code( $payment_id );
1023
1024
	return apply_filters( 'give_payment_currency', give_get_currency_name( $currency ), $payment_id );
1025
}
1026
1027
/**
1028
 * Get the key for a donation
1029
 *
1030
 * @param int $payment_id Payment ID.
1031
 *
1032
 * @since 1.0
1033
 *
1034
 * @return string $key Donation key.
1035
 */
1036
function give_get_payment_key( $payment_id = 0 ) {
1037
	$payment = new Give_Payment( $payment_id );
1038
1039
	return $payment->key;
1040
}
1041
1042
/**
1043
 * Get the payment order number
1044
 *
1045
 * This will return the payment ID if sequential order numbers are not enabled or the order number does not exist
1046
 *
1047
 * @param int $payment_id Payment ID.
1048
 *
1049
 * @since 1.0
1050
 *
1051
 * @return string $number Payment order number.
1052
 */
1053
function give_get_payment_number( $payment_id = 0 ) {
1054
	$payment = new Give_Payment( $payment_id );
1055
1056
	return $payment->number;
1057
}
1058
1059
1060
/**
1061
 * Get Donation Amount
1062
 *
1063
 * Get the fully formatted or unformatted donation amount which is sent through give_currency_filter()
1064
 * and give_format_amount() to format the amount correctly in case of formatted amount.
1065
 *
1066
 * @param int|Give_Payment $donation    Donation ID or Donation Object.
1067
 * @param bool|array       $format_args Currency Formatting Arguments.
1068
 *
1069
 * @since 1.0
1070
 * @since 1.8.17 Added filter and internally use functions.
1071
 *
1072
 * @return string $amount Fully formatted donation amount.
1073
 */
1074
function give_donation_amount( $donation, $format_args = array() ) {
1075
	/* @var Give_Payment $donation */
1076
	if ( ! ( $donation instanceof Give_Payment ) ) {
1077
		$donation = new Give_Payment( absint( $donation ) );
1078
	}
1079
1080
	$amount           = $donation->total;
1081
	$formatted_amount = $amount;
1082
1083
	if ( is_bool( $format_args ) ) {
1084
		$format_args = array(
1085
			'currency' => (bool) $format_args,
1086
			'amount'   => (bool) $format_args,
1087
		);
1088
	}
1089
1090
	$format_args = wp_parse_args(
1091
		$format_args,
1092
		array(
1093
			'currency' => false,
1094
			'amount'   => false,
1095
1096
			// Define context of donation amount, by default keep $type as blank.
1097
			// Pass as 'stats' to calculate donation report on basis of base amount for the Currency-Switcher Add-on.
1098
			// For Eg. In Currency-Switcher add on when donation has been made through
1099
			// different currency other than base currency, in that case for correct
1100
			//report calculation based on base currency we will need to return donation
1101
			// base amount and not the converted amount .
1102
			'type'     => '',
1103
		)
1104
	);
1105
1106
	if ( $format_args['amount'] || $format_args['currency'] ) {
1107
1108
		if ( $format_args['amount'] ) {
1109
1110
			$formatted_amount = give_format_amount(
1111
				$amount,
1112
				! is_array( $format_args['amount'] ) ?
1113
					array(
1114
						'sanitize' => false,
1115
						'currency' => $donation->currency,
1116
					) :
1117
					$format_args['amount']
1118
			);
1119
		}
1120
1121
		if ( $format_args['currency'] ) {
1122
			$formatted_amount = give_currency_filter(
1123
				$formatted_amount,
1124
				! is_array( $format_args['currency'] ) ?
1125
					array( 'currency_code' => $donation->currency ) :
1126
					$format_args['currency']
1127
			);
1128
		}
1129
	}
1130
1131
	/**
1132
	 * Filter Donation amount.
1133
	 *
1134
	 * @since 1.8.17
1135
	 *
1136
	 * @param string $formatted_amount Formatted/Un-formatted amount.
1137
	 * @param float  $amount           Donation amount.
1138
	 * @param int    $donation_id      Donation ID.
1139
	 * @param string $type             Donation amount type.
1140
	 */
1141
	return apply_filters( 'give_donation_amount', (string) $formatted_amount, $amount, $donation, $format_args );
1142
}
1143
1144
/**
1145
 * Payment Subtotal
1146
 *
1147
 * Retrieves subtotal for payment and then returns a full formatted amount. This
1148
 * function essentially calls give_get_payment_subtotal()
1149
 *
1150
 * @param int $payment_id Payment ID.
1151
 *
1152
 * @since 1.5
1153
 *
1154
 * @see   give_get_payment_subtotal()
1155
 *
1156
 * @return array Fully formatted payment subtotal.
1157
 */
1158
function give_payment_subtotal( $payment_id = 0 ) {
1159
	$subtotal = give_get_payment_subtotal( $payment_id );
1160
1161
	return give_currency_filter( give_format_amount( $subtotal, array( 'sanitize' => false ) ), array( 'currency_code' => give_get_payment_currency_code( $payment_id ) ) );
1162
}
1163
1164
/**
1165
 * Get Payment Subtotal
1166
 *
1167
 * Retrieves subtotal for payment and then returns a non formatted amount.
1168
 *
1169
 * @param int $payment_id Payment ID.
1170
 *
1171
 * @since 1.5
1172
 *
1173
 * @return float $subtotal Subtotal for payment (non formatted).
1174
 */
1175
function give_get_payment_subtotal( $payment_id = 0 ) {
1176
	$payment = new Give_Payment( $payment_id );
1177
1178
	return $payment->subtotal;
1179
}
1180
1181
/**
1182
 * Retrieves the donation ID
1183
 *
1184
 * @param int $payment_id Payment ID.
1185
 *
1186
 * @since  1.0
1187
 *
1188
 * @return string The donation ID.
1189
 */
1190
function give_get_payment_transaction_id( $payment_id = 0 ) {
1191
	$payment = new Give_Payment( $payment_id );
1192
1193
	return $payment->transaction_id;
1194
}
1195
1196
/**
1197
 * Sets a Transaction ID in post meta for the given Payment ID.
1198
 *
1199
 * @param int    $payment_id     Payment ID.
1200
 * @param string $transaction_id The transaction ID from the gateway.
1201
 *
1202
 * @since  1.0
1203
 *
1204
 * @return bool|mixed
1205
 */
1206
function give_set_payment_transaction_id( $payment_id = 0, $transaction_id = '' ) {
1207
1208
	if ( empty( $payment_id ) || empty( $transaction_id ) ) {
1209
		return false;
1210
	}
1211
1212
	$transaction_id = apply_filters( 'give_set_payment_transaction_id', $transaction_id, $payment_id );
1213
1214
	return give_update_payment_meta( $payment_id, '_give_payment_transaction_id', $transaction_id );
1215
}
1216
1217
/**
1218
 * Retrieve the donation ID based on the key
1219
 *
1220
 * @param string  $key  the key to search for.
1221
 *
1222
 * @since 1.0
1223
 * @global object $wpdb Used to query the database using the WordPress Database API.
1224
 *
1225
 * @return int $purchase Donation ID.
1226
 */
1227 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...
1228
	global $wpdb;
1229
1230
	$meta_table = __give_v20_bc_table_details( 'payment' );
1231
1232
	$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...
1233
		$wpdb->prepare(
1234
			"
1235
				SELECT {$meta_table['column']['id']}
1236
				FROM {$meta_table['name']}
1237
				WHERE meta_key = '_give_payment_purchase_key'
1238
				AND meta_value = %s
1239
				ORDER BY {$meta_table['column']['id']} DESC
1240
				LIMIT 1
1241
				",
1242
			$key
1243
		)
1244
	);
1245
1246
	if ( $purchase != null ) {
1247
		return $purchase;
1248
	}
1249
1250
	return 0;
1251
}
1252
1253
1254
/**
1255
 * Retrieve the donation ID based on the transaction ID
1256
 *
1257
 * @param string  $key  The transaction ID to search for.
1258
 *
1259
 * @since 1.3
1260
 * @global object $wpdb Used to query the database using the WordPress Database API.
1261
 *
1262
 * @return int $purchase Donation ID.
1263
 */
1264 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...
1265
	global $wpdb;
1266
	$meta_table = __give_v20_bc_table_details( 'payment' );
1267
1268
	$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...
1269
1270
	if ( $purchase != null ) {
1271
		return $purchase;
1272
	}
1273
1274
	return 0;
1275
}
1276
1277
/**
1278
 * Retrieve all notes attached to a donation
1279
 *
1280
 * @param int    $payment_id The donation ID to retrieve notes for.
1281
 * @param string $search     Search for notes that contain a search term.
1282
 *
1283
 * @since 1.0
1284
 *
1285
 * @return array $notes Donation Notes
1286
 */
1287
function give_get_payment_notes( $payment_id = 0, $search = '' ) {
1288
	return Give_Comment::get( $payment_id, $search, 'payment' );
1289
}
1290
1291
1292
/**
1293
 * Add a note to a payment
1294
 *
1295
 * @param int    $payment_id The payment ID to store a note for.
1296
 * @param string $note       The note to store.
1297
 *
1298
 * @since 1.0
1299
 *
1300
 * @return int The new note ID
1301
 */
1302
function give_insert_payment_note( $payment_id = 0, $note = '' ) {
1303
	return Give_Comment::add( $payment_id, $note, 'payment' );
1304
}
1305
1306
/**
1307
 * Deletes a payment note
1308
 *
1309
 * @param int $comment_id The comment ID to delete.
1310
 * @param int $payment_id The payment ID the note is connected to.
1311
 *
1312
 * @since 1.0
1313
 *
1314
 * @return bool True on success, false otherwise.
1315
 */
1316
function give_delete_payment_note( $comment_id = 0, $payment_id = 0 ) {
1317
	return Give_Comment::delete( $comment_id, $payment_id, 'payment' );
1318
}
1319
1320
/**
1321
 * Gets the payment note HTML
1322
 *
1323
 * @param object|int $note       The comment object or ID.
1324
 * @param int        $payment_id The payment ID the note is connected to.
1325
 *
1326
 * @since 1.0
1327
 *
1328
 * @return string
1329
 */
1330
function give_get_payment_note_html( $note, $payment_id = 0 ) {
1331
1332
	if ( is_numeric( $note ) ) {
1333
		$note = get_comment( $note );
1334
	}
1335
1336
	if ( ! empty( $note->user_id ) ) {
1337
		$user = get_userdata( $note->user_id );
1338
		$user = $user->display_name;
1339
	} else {
1340
		$user = __( 'System', 'give' );
1341
	}
1342
1343
	$date_format = give_date_format() . ', ' . get_option( 'time_format' );
1344
1345
	$delete_note_url = wp_nonce_url( add_query_arg( array(
1346
		'give-action' => 'delete_payment_note',
1347
		'note_id'     => $note->comment_ID,
1348
		'payment_id'  => $payment_id,
1349
	) ), 'give_delete_payment_note_' . $note->comment_ID );
1350
1351
	$note_html = '<div class="give-payment-note" id="give-payment-note-' . $note->comment_ID . '">';
1352
	$note_html .= '<p>';
1353
	$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/>';
1354
	$note_html .= $note->comment_content;
1355
	$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...
1356
	$note_html .= '</p>';
1357
	$note_html .= '</div>';
1358
1359
	return $note_html;
1360
1361
}
1362
1363
1364
/**
1365
 * Filter where older than one week
1366
 *
1367
 * @param string $where Where clause.
1368
 *
1369
 * @access public
1370
 * @since  1.0
1371
 *
1372
 * @return string $where Modified where clause.
1373
 */
1374
function give_filter_where_older_than_week( $where = '' ) {
1375
	// Payments older than one week.
1376
	$start = date( 'Y-m-d', strtotime( '-7 days' ) );
1377
	$where .= " AND post_date <= '{$start}'";
1378
1379
	return $where;
1380
}
1381
1382
1383
/**
1384
 * Get Payment Form ID.
1385
 *
1386
 * Retrieves the form title and appends the level name if present.
1387
 *
1388
 * @param int|Give_Payment $donation Donation Data Object.
1389
 * @param array            $args     a. only_level = If set to true will only return the level name if multi-level
1390
 *                                   enabled. b. separator  = The separator between the Form Title and the Donation
1391
 *                                   Level.
1392
 *
1393
 * @since 1.5
1394
 *
1395
 * @return string $form_title Returns the full title if $only_level is false, otherwise returns the levels title.
1396
 */
1397
function give_get_donation_form_title( $donation, $args = array() ) {
1398
1399
	if ( ! $donation instanceof Give_Payment ) {
1400
		$donation = new Give_Payment( $donation );
1401
	}
1402
1403
	if ( ! $donation->ID ) {
1404
		return '';
1405
	}
1406
1407
	$defaults = array(
1408
		'only_level' => false,
1409
		'separator'  => '',
1410
	);
1411
1412
	$args = wp_parse_args( $args, $defaults );
1413
1414
	$form_id     = $donation->form_id;
1415
	$price_id    = $donation->price_id;
1416
	$form_title  = $donation->form_title;
1417
	$only_level  = $args['only_level'];
1418
	$separator   = $args['separator'];
1419
	$level_label = '';
1420
1421
	$cache_key = Give_Cache::get_key(
1422
		'give_forms',
1423
		array(
1424
			$form_id,
1425
			$price_id,
1426
			$form_title,
1427
			$only_level,
1428
			$separator
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1429
		)
1430
		, false
1431
	);
1432
1433
	$form_title_html = Give_Cache::get_db_query( $cache_key );
1434
1435
	if ( is_null( $form_title_html ) ) {
1436
		if ( true === $only_level ) {
1437
			$form_title = '';
1438
		}
1439
1440
		$form_title_html = $form_title;
1441
1442
		if ( 'custom' === $price_id ) {
1443
1444
			$custom_amount_text = give_get_meta( $form_id, '_give_custom_amount_text', true );
1445
			$level_label        = ! empty( $custom_amount_text ) ? $custom_amount_text : __( 'Custom Amount', 'give' );
1446
1447
			// Show custom amount level only in backend otherwise hide it.
1448
			if ( 'set' === give_get_meta( $form_id, '_give_price_option', true ) && ! is_admin() ) {
1449
				$level_label = '';
1450
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
1451
1452
		} elseif ( give_has_variable_prices( $form_id ) ) {
1453
			$level_label = give_get_price_option_name( $form_id, $price_id, $donation->ID, false );
1454
		}
1455
1456
		// Only add separator if there is a form title.
1457
		if (
1458
			! empty( $form_title_html ) &&
1459
			! empty( $level_label )
1460
		) {
1461
			$form_title_html .= " {$separator} ";
1462
		}
1463
1464
		$form_title_html .= "<span class=\"donation-level-text-wrap\">{$level_label}</span>";
1465
		Give_Cache::set_db_query( $cache_key, $form_title_html );
1466
	}
1467
1468
	/**
1469
	 * Filter form title with level html
1470
	 *
1471
	 * @since 1.0
1472
	 */
1473
	return apply_filters( 'give_get_donation_form_title', $form_title_html, $donation->payment_meta, $donation );
1474
}
1475
1476
/**
1477
 * Get Price ID
1478
 *
1479
 * Retrieves the Price ID when provided a proper form ID and price (donation) total
1480
 *
1481
 * @param int    $form_id Form ID.
1482
 * @param string $price   Donation Amount.
1483
 *
1484
 * @return string $price_id
1485
 */
1486
function give_get_price_id( $form_id, $price ) {
1487
	$price_id = null;
1488
1489
	if ( give_has_variable_prices( $form_id ) ) {
1490
1491
		$levels = give_get_meta( $form_id, '_give_donation_levels', true );
1492
1493
		foreach ( $levels as $level ) {
1494
1495
			$level_amount = give_maybe_sanitize_amount( $level['_give_amount'] );
1496
1497
			// Check that this indeed the recurring price.
1498
			if ( $level_amount == $price ) {
1499
1500
				$price_id = $level['_give_id']['level_id'];
1501
				break;
1502
1503
			}
1504
		}
1505
1506
		if ( is_null( $price_id ) && give_is_custom_price_mode( $form_id ) ) {
1507
			$price_id = 'custom';
1508
		}
1509
	}
1510
1511
	// Price ID must be numeric or string.
1512
	$price_id = ! is_numeric( $price_id ) && ! is_string( $price_id ) ? 0 : $price_id;
1513
1514
	/**
1515
	 * Filter the price id
1516
	 *
1517
	 * @since 2.0
1518
	 *
1519
	 * @param string $price_id
1520
	 * @param int    $form_id
1521
	 */
1522
	return apply_filters( 'give_get_price_id', $price_id, $form_id );
1523
}
1524
1525
/**
1526
 * Get/Print give form dropdown html
1527
 *
1528
 * This function is wrapper to public method forms_dropdown of Give_HTML_Elements class to get/print form dropdown html.
1529
 * Give_HTML_Elements is defined in includes/class-give-html-elements.php.
1530
 *
1531
 * @param array $args Arguments for form dropdown.
1532
 * @param bool  $echo This parameter decides if print form dropdown html output or not.
1533
 *
1534
 * @since 1.6
1535
 *
1536
 * @return string
1537
 */
1538
function give_get_form_dropdown( $args = array(), $echo = false ) {
1539
	$form_dropdown_html = Give()->html->forms_dropdown( $args );
1540
1541
	if ( ! $echo ) {
1542
		return $form_dropdown_html;
1543
	}
1544
1545
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1546
}
1547
1548
/**
1549
 * Get/Print give form variable price dropdown html
1550
 *
1551
 * @param array $args Arguments for form dropdown.
1552
 * @param bool  $echo This parameter decide if print form dropdown html output or not.
1553
 *
1554
 * @since 1.6
1555
 *
1556
 * @return string|bool
1557
 */
1558
function give_get_form_variable_price_dropdown( $args = array(), $echo = false ) {
1559
1560
	// Check for give form id.
1561
	if ( empty( $args['id'] ) ) {
1562
		return false;
1563
	}
1564
1565
	$form = new Give_Donate_Form( $args['id'] );
1566
1567
	// Check if form has variable prices or not.
1568
	if ( ! $form->ID || ! $form->has_variable_prices() ) {
1569
		return false;
1570
	}
1571
1572
	$variable_prices        = $form->get_prices();
1573
	$variable_price_options = array();
1574
1575
	// Check if multi donation form support custom donation or not.
1576
	if ( $form->is_custom_price_mode() ) {
1577
		$variable_price_options['custom'] = _x( 'Custom', 'custom donation dropdown item', 'give' );
1578
	}
1579
1580
	// Get variable price and ID from variable price array.
1581
	foreach ( $variable_prices as $variable_price ) {
1582
		$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 ) ) );
1583
	}
1584
1585
	// Update options.
1586
	$args = array_merge( $args, array(
1587
		'options' => $variable_price_options,
1588
	) );
1589
1590
	// Generate select html.
1591
	$form_dropdown_html = Give()->html->select( $args );
1592
1593
	if ( ! $echo ) {
1594
		return $form_dropdown_html;
1595
	}
1596
1597
	echo $form_dropdown_html;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$form_dropdown_html'
Loading history...
1598
}
1599
1600
/**
1601
 * Get the price_id from the payment meta.
1602
 *
1603
 * Some gateways use `give_price_id` and others were using just `price_id`;
1604
 * This checks for the difference and falls back to retrieving it from the form as a last resort.
1605
 *
1606
 * @param array $payment_meta Payment Meta.
1607
 *
1608
 * @since 1.8.6
1609
 *
1610
 * @return string
1611
 */
1612
function give_get_payment_meta_price_id( $payment_meta ) {
1613
1614
	if ( isset( $payment_meta['give_price_id'] ) ) {
1615
		$price_id = $payment_meta['give_price_id'];
1616
	} elseif ( isset( $payment_meta['price_id'] ) ) {
1617
		$price_id = $payment_meta['price_id'];
1618
	} else {
1619
		$price_id = give_get_price_id( $payment_meta['give_form_id'], $payment_meta['price'] );
1620
	}
1621
1622
	/**
1623
	 * Filter the price id
1624
	 *
1625
	 * @since 1.8.6
1626
	 *
1627
	 * @param string $price_id
1628
	 * @param array  $payment_meta
1629
	 */
1630
	return apply_filters( 'give_get_payment_meta_price_id', $price_id, $payment_meta );
1631
1632
}
1633