Issues (4296)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/payments/functions.php (49 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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