Test Failed
Push — release/1.8.12 ( b58a2f...d255b1 )
by Ravinder
375:09 queued 372:17
created

includes/payments/class-give-payment.php (31 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

1
<?php
2
/**
3
 * Payments
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_Payment
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.5
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_Payment Class
19
 *
20
 * This class is for working with payments in Give.
21
 *
22
 * @property int $ID
23
 * @property bool $new
24
 * @property string $number
25
 * @property string $mode
26
 * @property string $key
27
 * @property string $form_title
28
 * @property string|int $form_id
29
 * @property string|int $price_id
30
 * @property string|int $total
31
 * @property string|int $subtotal
32
 * @property string $post_status
33
 * @property string $date
34
 * @property string $postdate
35
 * @property string $status
36
 * @property string $email
37
 * @property string $payment_meta
38
 * @property string $customer_id
39
 * @property string $completed_date
40
 * @property string $currency
41
 * @property string $ip
42
 * @property array $user_info
43
 * @property string $gateway
44
 * @property string $user_id
45
 * @property string $first_name
46
 * @property string $last_name
47
 * @property string $parent_payment
48
 * @property string $transaction_id
49
 * @property string $old_status
50
 *
51
 * @since 1.5
52
 */
53
final class Give_Payment {
54
55
	/**
56
	 * The Payment ID.
57
	 *
58
	 * @since  1.5
59
	 *
60
	 * @var    int
61
	 */
62
	public $ID = 0;
63
64
	/**
65
	 * Protected non-read $_ID.
66
	 *
67
	 * @var int
68
	 */
69
	protected $_ID = 0;
70
71
	/**
72
	 * Identify if the payment is a new one or existing.
73
	 *
74
	 * @since  1.5
75
	 * @access protected
76
	 *
77
	 * @var    boolean
78
	 */
79
	protected $new = false;
80
81
	/**
82
	 * The Payment number (for use with sequential payments).
83
	 *
84
	 * @since  1.5
85
	 * @access protected
86
	 *
87
	 * @var    string
88
	 */
89
	protected $number = '';
90
91
	/**
92
	 * The Gateway mode the payment was made in.
93
	 *
94
	 * @since  1.5
95
	 * @access protected
96
	 *
97
	 * @var    string
98
	 */
99
	protected $mode = 'live';
100
101
	/**
102
	 * The unique donation payment key.
103
	 *
104
	 * @since  1.5
105
	 * @access protected
106
	 *
107
	 * @var    string
108
	 */
109
	protected $key = '';
110
111
	/**
112
	 * The Donation Form Title
113
	 *
114
	 * @since  1.5
115
	 * @access protected
116
	 *
117
	 * @var    string
118
	 */
119
	protected $form_title = 0;
120
121
	/**
122
	 * The Donation Form ID
123
	 *
124
	 * @since  1.5
125
	 * @access protected
126
	 *
127
	 * @var    string
128
	 */
129
	protected $form_id = 0;
130
131
	/**
132
	 * The Donation Form Price ID
133
	 *
134
	 * @since  1.5
135
	 * @access protected
136
	 *
137
	 * @var    string|int
138
	 */
139
	protected $price_id = 0;
140
141
	/**
142
	 * The total amount of the donation payment.
143
	 *
144
	 * @since  1.5
145
	 * @access protected
146
	 *
147
	 * @var    float
148
	 */
149
	protected $total = 0.00;
150
151
	/**
152
	 * The Subtotal fo the payment.
153
	 *
154
	 * @since  1.5
155
	 * @access protected
156
	 *
157
	 * @var    float
158
	 */
159
	protected $subtotal = 0;
160
161
	/**
162
	 * The date the payment was created
163
	 *
164
	 * @since  1.5
165
	 * @access protected
166
	 *
167
	 * @var    string
168
	 */
169
	protected $date = '';
170
171
	/**
172
	 * The date the payment post was created.
173
	 *
174
	 * @var string
175
	 */
176
	protected $post_date = '';
177
178
	/**
179
	 * The date the payment was marked as 'complete'.
180
	 *
181
	 * @since  1.5
182
	 * @access protected
183
	 *
184
	 * @var    string
185
	 */
186
	protected $completed_date = '';
187
188
	/**
189
	 * The status of the donation payment.
190
	 *
191
	 * @since  1.5
192
	 * @access protected
193
	 *
194
	 * @var    string
195
	 */
196
	protected $status = 'pending';
197
198
	/**
199
	 * @var string
200
	 */
201
	protected $post_status = 'pending'; // Same as $status but here for backwards compat
202
203
	/**
204
	 * When updating, the old status prior to the change
205
	 *
206
	 * @since  1.5
207
	 * @access protected
208
	 *
209
	 * @var    string
210
	 */
211
	protected $old_status = '';
212
213
	/**
214
	 * The display name of the current payment status.
215
	 *
216
	 * @since  1.5
217
	 * @access protected
218
	 *
219
	 * @var    string
220
	 */
221
	protected $status_nicename = '';
222
223
	/**
224
	 * The donor ID that made the payment.
225
	 *
226
	 * @since  1.5
227
	 * @access protected
228
	 *
229
	 * @var    integer
230
	 */
231
	protected $customer_id = null;
232
233
	/**
234
	 * The User ID (if logged in) that made the payment
235
	 *
236
	 * @since  1.5
237
	 * @access protected
238
	 *
239
	 * @var    integer
240
	 */
241
	protected $user_id = 0;
242
243
	/**
244
	 * The first name of the payee
245
	 *
246
	 * @since  1.5
247
	 * @access protected
248
	 *
249
	 * @var    string
250
	 */
251
	protected $first_name = '';
252
253
	/**
254
	 * The last name of the payee
255
	 *
256
	 * @since  1.5
257
	 * @access protected
258
	 *
259
	 * @var    string
260
	 */
261
	protected $last_name = '';
262
263
	/**
264
	 * The email used for the payment
265
	 *
266
	 * @since  1.5
267
	 * @access protected
268
	 *
269
	 * @var    string
270
	 */
271
	protected $email = '';
272
273
	/**
274
	 * Legacy (not to be accessed) array of user information
275
	 *
276
	 * @since  1.5
277
	 * @access private
278
	 *
279
	 * @var    array
280
	 */
281
	private $user_info = array();
282
283
	/**
284
	 * Legacy (not to be accessed) payment meta array
285
	 *
286
	 * @since  1.5
287
	 * @access private
288
	 *
289
	 * @var    array
290
	 */
291
	private $payment_meta = array();
292
293
	/**
294
	 * The physical address used for the payment if provided
295
	 *
296
	 * @since  1.5
297
	 * @access protected
298 52
	 *
299
	 * @var    array
300 52
	 */
301 52
	protected $address = array();
302
303
	/**
304 52
	 * The transaction ID returned by the gateway
305 52
	 *
306
	 * @since  1.5
307
	 * @access protected
308
	 *
309
	 * @var    string
310
	 */
311
	protected $transaction_id = '';
312
313
	/**
314
	 * IP Address payment was made from
315
	 *
316 52
	 * @since  1.5
317
	 * @access protected
318 52
	 *
319
	 * @var    string
320 52
	 */
321
	protected $ip = '';
322 52
323
	/**
324 52
	 * The gateway used to process the payment
325
	 *
326
	 * @since  1.5
327
	 * @access protected
328 52
	 *
329
	 * @var    string
330
	 */
331
	protected $gateway = '';
332
333
	/**
334
	 * The the payment was made with
335
	 *
336
	 * @since  1.5
337
	 * @access protected
338
	 *
339
	 * @var    string
340
	 */
341 52
	protected $currency = '';
342 52
343
	/**
344 52
	 * Array of items that have changed since the last save() was run.
345 52
	 * This is for internal use, to allow fewer update_payment_meta calls to be run.
346 52
	 *
347
	 * @since  1.5
348 52
	 * @access private
349 52
	 *
350 52
	 * @var    array
351
	 */
352 52
	private $pending;
353 52
354 52
	/**
355 52
	 * The parent payment (if applicable)
356
	 *
357
	 * @since  1.5
358
	 * @access protected
359
	 *
360
	 * @var    integer
361
	 */
362
	protected $parent_payment = 0;
363
364
	/**
365
	 * Setup the Give Payments class
366 42
	 *
367 42
	 * @since  1.5
368 42
	 * @access public
369
	 *
370
	 * @param  int|bool $payment_id A given payment
371
	 *
372
	 * @return mixed void|false
373
	 */
374
	public function __construct( $payment_id = false ) {
375
376
		if ( empty( $payment_id ) ) {
377
			return false;
378
		}
379
380
		$this->setup_payment( $payment_id );
0 ignored issues
show
It seems like $payment_id defined by parameter $payment_id on line 374 can also be of type boolean; however, Give_Payment::setup_payment() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
381
	}
382
383 52
	/**
384 52
	 * Magic GET function.
385
	 *
386 52
	 * @since  1.5
387
	 * @access public
388
	 *
389
	 * @param  string $key The property.
390 52
	 *
391
	 * @return mixed        The value.
392 52
	 */
393 7
	public function __get( $key ) {
394
395
		if ( method_exists( $this, 'get_' . $key ) ) {
396 52
397
			$value = call_user_func( array( $this, 'get_' . $key ) );
398
399
		} else {
400
401 52
			$value = $this->$key;
402
403
		}
404 52
405
		return $value;
406
	}
407 52
408
	/**
409
	 * Magic SET function
410 52
	 *
411
	 * Sets up the pending array for the save method
412
	 *
413 52
	 * @since  1.5
414 52
	 * @access public
415 52
	 *
416 52
	 * @param  string $key The property name
417 52
	 * @param  mixed  $value The value of the property
418 52
	 */
419 52
	public function __set( $key, $value ) {
420
		$ignore = array( '_ID' );
421 52
422 52
		if ( $key === 'status' ) {
0 ignored issues
show
Found "=== '". Use Yoda Condition checks, you must
Loading history...
423
			$this->old_status = $this->status;
424
		}
425 52
426
		if ( ! in_array( $key, $ignore ) ) {
427
			$this->pending[ $key ] = $value;
428 52
		}
429 52
430 52
		if ( '_ID' !== $key ) {
431 52
			$this->$key = $value;
432
		}
433
	}
434 52
435 52
	/**
436
	 * Magic ISSET function, which allows empty checks on protected elements
437
	 *
438 52
	 * @since  1.5
439 52
	 * @access public
440 52
	 *
441 52
	 * @param  string $name The attribute to get
442 52
	 *
443 52
	 * @return boolean       If the item is set or not
444 52
	 */
445 52
	public function __isset( $name ) {
446
		if ( property_exists( $this, $name ) ) {
447
			return false === empty( $this->$name );
448 52
		} else {
449 52
			return null;
450 52
		}
451 52
	}
452 52
453
	/**
454
	 * Setup payment properties
455 52
	 *
456
	 * @since  1.5
457 52
	 * @access private
458
	 *
459
	 * @param  int $payment_id The payment ID
460
	 *
461
	 * @return bool            If the setup was successful or not
462
	 */
463
	private function setup_payment( $payment_id ) {
464
		$this->pending = array();
465
466 52
		if ( empty( $payment_id ) ) {
467
			return false;
468
		}
469 52
470 52
		$payment = get_post( $payment_id );
471 31
472 52
		if ( ! $payment || is_wp_error( $payment ) ) {
473
			return false;
474 22
		}
475 21
476 21
		if ( 'give_payment' !== $payment->post_type ) {
477
			return false;
478
		}
479 52
480
		/**
481 1
		 * Fires before payment setup.
482 1
		 *
483 1
		 * Allow extensions to perform actions before the payment is loaded.
484 1
		 *
485
		 * @since 1.5
486
		 *
487 52
		 * @param Give_Payment $this Payment object.
488
		 * @param int $payment_id The ID of the payment.
489 1
		 */
490 1
		do_action( 'give_pre_setup_payment', $this, $payment_id );
491
492 1
		// Primary Identifier.
493
		$this->ID = absint( $payment_id );
494
495 52
		// Protected ID that can never be changed.
496 52
		$this->_ID = absint( $payment_id );
497 52
498 52
		// We have a payment, get the generic payment_meta item to reduce calls to it.
499 52
		$this->payment_meta = $this->get_meta();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->get_meta() of type * is incompatible with the declared type array of property $payment_meta.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
500 52
501 52
		// Status and Dates.
502 52
		$this->date           = $payment->post_date;
503
		$this->post_date      = $payment->post_date;
504 52
		$this->completed_date = $this->setup_completed_date();
505 52
		$this->status         = $payment->post_status;
506 52
		$this->post_status    = $this->status;
507 52
		$this->mode           = $this->setup_mode();
508 52
		$this->parent_payment = $payment->post_parent;
509 52
510 52
		$all_payment_statuses  = give_get_payment_statuses();
511 52
		$this->status_nicename = array_key_exists( $this->status, $all_payment_statuses ) ? $all_payment_statuses[ $this->status ] : ucfirst( $this->status );
512 52
513
		// Currency Based.
514 52
		$this->total      = $this->setup_total();
515 52
		$this->subtotal   = $this->setup_subtotal();
516 52
		$this->currency   = $this->setup_currency();
517 52
518 52
		// Gateway based.
519 52
		$this->gateway        = $this->setup_gateway();
520 52
		$this->transaction_id = $this->setup_transaction_id();
521 52
522
		// User based.
523
		$this->ip          = $this->setup_ip();
524 52
		$this->customer_id = $this->setup_donor_id();
525
		$this->user_id     = $this->setup_user_id();
526 52
		$this->email       = $this->setup_email();
527
		$this->user_info   = $this->setup_user_info();
528 52
		$this->address     = $this->setup_address();
529 52
		$this->first_name  = $this->user_info['first_name'];
530
		$this->last_name   = $this->user_info['last_name'];
531 52
532
		// Other Identifiers.
533 52
		$this->form_title = $this->setup_form_title();
534
		$this->form_id    = $this->setup_form_id();
0 ignored issues
show
Documentation Bug introduced by
The property $form_id was declared of type string, but $this->setup_form_id() is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
535
		$this->price_id   = $this->setup_price_id();
536
		$this->key        = $this->setup_payment_key();
537 52
		$this->number     = $this->setup_payment_number();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->setup_payment_number() can also be of type integer. However, the property $number 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...
538 52
539 52
		/**
540
		 * Fires after payment setup.
541 52
		 *
542
		 * Allow extensions to add items to this object via hook.
543
		 *
544 52
		 * @since 1.5
545 52
		 *
546 52
		 * @param Give_Payment $this Payment object.
547 52
		 * @param int $payment_id The ID of the payment.
548
		 */
549 52
		do_action( 'give_setup_payment', $this, $payment_id );
550
551 52
		return true;
552
	}
553 52
554 52
	/**
555 52
	 * Payment class object is storing various meta value in object parameter.
556
	 * So if user is updating payment meta but not updating payment object, then payment meta values will not reflect/changes on payment meta automatically
557 52
	 * and you can still access payment meta old value in any old payment object ( previously created ) which can cause to show or save wrong payment data.
558 52
	 * To prevent that user can use this function after updating any payment meta value ( in bulk or single update ).
559
	 *
560
	 * @since  1.6
561
	 * @access public
562
	 *
563
	 * @param  int $payment_id Payment ID.
564
	 *
565 52
	 * @return void
566 52
	 */
567 52
	public function update_payment_setup( $payment_id ) {
568
		$this->setup_payment( $payment_id );
569 52
	}
570
571
	/**
572
	 * Create the base of a payment.
573
	 *
574
	 * @since  1.5
575
	 * @access private
576
	 *
577
	 * @return int|bool False on failure, the payment ID on success.
578
	 */
579
	private function insert_payment() {
580 52
581
		// Construct the payment title.
582 52
		$payment_title = '';
583
		if ( ! empty( $this->first_name ) && ! empty( $this->last_name ) ) {
584
			$payment_title = $this->first_name . ' ' . $this->last_name;
585 52
		} elseif ( ! empty( $this->first_name ) && empty( $this->last_name ) ) {
586
			$payment_title = $this->first_name;
587 52
		} elseif ( ! empty( $this->email ) && is_email( $this->email ) ) {
588
			$payment_title = $this->email;
589 52
		}
590
591
		// Set Key.
592 52
		if ( empty( $this->key ) ) {
593
594
			$auth_key             = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
595 52
			$this->key            = strtolower( md5( $this->email . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) );  // Unique key
596
			$this->pending['key'] = $this->key;
597
		}
598 52
599 1
		// Set IP.
600 1
		if ( empty( $this->ip ) ) {
601
602
			$this->ip            = give_get_ip();
603 52
			$this->pending['ip'] = $this->ip;
604
605 52
		}
606 52
607
		$payment_data = array(
608 52
			'price'        => $this->total,
609
			'date'         => $this->date,
610
			'user_email'   => $this->email,
611
			'purchase_key' => $this->key,
612 52
			'form_title'   => $this->form_title,
613
			'form_id'      => $this->form_id,
614 52
			'price_id'     => $this->price_id,
615
			'currency'     => $this->currency,
616 52
			'user_info'    => array(
617 52
				'id'         => $this->user_id,
618
				'email'      => $this->email,
619 52
				'first_name' => $this->first_name,
620
				'last_name'  => $this->last_name,
621 52
				'address'    => $this->address,
622
			),
623 52
			'status'       => $this->status,
624
		);
625 52
626
		$args = apply_filters( 'give_insert_payment_args', array(
627
			'post_title'    => $payment_title,
628 1
			'post_status'   => $this->status,
629
			'post_type'     => 'give_payment',
630 1
			'post_date'     => ! empty( $this->date ) ? $this->date : null,
631 1
			'post_date_gmt' => ! empty( $this->date ) ? get_gmt_from_date( $this->date ) : null,
632
			'post_parent'   => $this->parent_payment,
633 1
		), $payment_data );
634 1
635 1
		// Create a blank payment
636
		$payment_id = wp_insert_post( $args );
637 1
638 1
		if ( ! empty( $payment_id ) ) {
639 1
640
			$this->ID  = $payment_id;
641 1
			$this->_ID = $payment_id;
642 1
643 52
			$donor = new stdClass;
644
645 2
			if ( did_action( 'give_pre_process_donation' ) && is_user_logged_in() ) {
646
				$donor = new Give_Donor( get_current_user_id(), true );
647 2
648 2
				// Donor is logged in but used a different email to purchase with so assign to their donor record.
649 2
				if ( ! empty( $donor->id ) && $this->email != $donor->email ) {
650
					$donor->add_email( $this->email );
651
				}
652 2
			}
653 2
654 2
			if ( empty( $donor->id ) ) {
655 2
				$donor = new Give_Donor( $this->email );
0 ignored issues
show
$this->email 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...
656
			}
657 2
658 2
			if ( empty( $donor->id ) ) {
659
660 2
				$donor_data = array(
661 2
					'name'    => ! is_email( $payment_title ) ? $this->first_name . ' ' . $this->last_name : '',
662 2
					'email'   => $this->email,
663
					'user_id' => $this->user_id,
664 2
				);
665 2
666 1
				$donor->create( $donor_data );
667 2
668
			}
669 2
670 1
			$this->customer_id            = $donor->id;
671 1
			$this->pending['customer_id'] = $this->customer_id;
672 1
			$donor->attach_payment( $this->ID, false );
673
674 1
			$this->payment_meta = apply_filters( 'give_payment_meta', $this->payment_meta, $payment_data );
675 1
676 2
			$this->update_meta( '_give_payment_meta', $this->payment_meta );
677
			$this->new = true;
678 52
		}// End if().
679
680 52
		return $this->ID;
681 52
682
	}
683 52
684
	/**
685
	 * Save
686
	 *
687
	 * Once items have been set, an update is needed to save them to the database.
688
	 *
689
	 * @access public
690
	 *
691
	 * @return bool  True of the save occurred, false if it failed or wasn't needed
692
	 */
693
	public function save() {
694
695
		$saved = false;
696
697
		// Must have an ID.
698
		if ( empty( $this->ID ) ) {
699
700
			$payment_id = $this->insert_payment();
701
702
			if ( false === $payment_id ) {
703
				$saved = false;
704
			} else {
705
				$this->ID = $payment_id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $payment_id can also be of type boolean. However, the property $ID is declared as type integer. 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...
706
			}
707
		}
708
709
		// Set ID if not matching.
710
		if ( $this->ID !== $this->_ID ) {
711 52
			$this->ID = $this->_ID;
712 52
		}
713 52
714
		// If we have something pending, let's save it.
715 52
		if ( ! empty( $this->pending ) ) {
716 52
717 52
			$total_increase = 0;
718
			$total_decrease = 0;
719 52
720 52
			foreach ( $this->pending as $key => $value ) {
721 52
722
				switch ( $key ) {
723 52
724 20
					case 'donations':
725 20
						// Update totals for pending donations.
726
						foreach ( $this->pending[ $key ] as $item ) {
727 52
728 52
							$quantity = isset( $item['quantity'] ) ? $item['quantity'] : 1;
729 52
							$price_id = isset( $item['price_id'] ) ? $item['price_id'] : 0;
730
731 52
							switch ( $item['action'] ) {
732 52
733 52
								case 'add':
734
735 52
									$price = $item['price'];
736 52
737 52
									if ( 'publish' === $this->status || 'complete' === $this->status ) {
738
739 52
										// Add sales logs.
740 52
										$log_date = date_i18n( 'Y-m-d G:i:s', current_time( 'timestamp' ) );
741 52
742
										$y = 0;
743 52
										while ( $y < $quantity ) {
744 52
745 52
											give_record_donation_in_log( $item['id'], $this->ID, $price_id, $log_date );
746
											$y ++;
747 52
										}
748 52
749 52
										$form = new Give_Donate_Form( $item['id'] );
750
										$form->increase_sales( $quantity );
751 52
										$form->increase_earnings( $price );
752 52
753 52
										$total_increase += $price;
754
									}
755 52
									break;
756 52
757 52
								case 'remove':
758
									$log_args = array(
759 52
										'post_type'   => 'give_log',
760
										'post_parent' => $item['id'],
761
										'numberposts' => $quantity,
762
										'meta_query'  => array(
0 ignored issues
show
Detected usage of meta_query, possible slow query.
Loading history...
763 52
											array(
764 52
												'key'     => '_give_log_payment_id',
765 52
												'value'   => $this->ID,
766
												'compare' => '=',
767 52
											),
768 52
											array(
769 52
												'key'     => '_give_log_price_id',
770
												'value'   => $price_id,
771 52
												'compare' => '=',
772 20
											),
773 20
										),
774
									);
775 52
776
									$found_logs = get_posts( $log_args );
777 2
									foreach ( $found_logs as $log ) {
778 2
										wp_delete_post( $log->ID, true );
779 2
									}
780 2
781
									if ( 'publish' === $this->status || 'complete' === $this->status ) {
782 2
										$form = new Give_Donate_Form( $item['id'] );
783 2
										$form->decrease_sales( $quantity );
784
										$form->decrease_earnings( $item['amount'] );
785 52
786 42
										$total_decrease += $item['amount'];
787 42
									}
788
									break;
789 52
790
							}// End switch().
791 52
						}// End foreach().
792 52
						break;
793 52
794
					case 'status':
795 52
						$this->update_status( $this->status );
796 52
						break;
797
798 52
					case 'gateway':
799 52
						$this->update_meta( '_give_payment_gateway', $this->gateway );
800 52
						break;
801 52
802 52
					case 'mode':
803
						$this->update_meta( '_give_payment_mode', $this->mode );
804 52
						break;
805
806 42
					case 'transaction_id':
807
						$this->update_meta( '_give_payment_transaction_id', $this->transaction_id );
808 42
						break;
809 42
810
					case 'ip':
811 1
						$this->update_meta( '_give_payment_user_ip', $this->ip );
812
						break;
813 1
814 1
					case 'customer_id':
815
						$this->update_meta( '_give_payment_customer_id', $this->customer_id );
816 42
						break;
817
818
					case 'user_id':
819 1
						$this->update_meta( '_give_payment_user_id', $this->user_id );
820 1
						break;
821
822 1
					case 'form_title':
823
						$this->update_meta( '_give_payment_form_title', $this->form_title );
824 42
						break;
825
826 52
					case 'form_id':
827
						$this->update_meta( '_give_payment_form_id', $this->form_id );
828
						break;
829 52
830 52
					case 'price_id':
831 52
						$this->update_meta( '_give_payment_price_id', $this->price_id );
832 52
						break;
833 52
834 52
					case 'first_name':
835 52
						$this->user_info['first_name'] = $this->first_name;
836
						break;
837 52
838 52
					case 'last_name':
839
						$this->user_info['last_name'] = $this->last_name;
840
						break;
841 52
842 52
					case 'address':
843 52
						$this->user_info['address'] = $this->address;
844 52
						break;
845 52
846 52
					case 'email':
847
						$this->update_meta( '_give_payment_user_email', $this->email );
848 52
						break;
849 52
850 52
					case 'key':
851
						$this->update_meta( '_give_payment_purchase_key', $this->key );
852 52
						break;
853 52
854 52
					case 'number':
855
						$this->update_meta( '_give_payment_number', $this->number );
856 52
						break;
857
858
					case 'date':
859
						$args = array(
860
							'ID'        => $this->ID,
861
							'post_date' => $this->date,
862
							'edit_date' => true,
863
						);
864
865
						wp_update_post( $args );
866
						break;
867
868
					case 'completed_date':
869
						$this->update_meta( '_give_completed_date', $this->completed_date );
870 52
						break;
871
872 52
					case 'parent_payment':
873
						$args = array(
874
							'ID'          => $this->ID,
875 52
							'post_parent' => $this->parent_payment,
876
						);
877
878
						wp_update_post( $args );
879
						break;
880
881 52
					default:
882 52
						/**
883 52
						 * Fires while saving payment.
884 52
						 *
885
						 * @since 1.7
886 52
						 *
887
						 * @param Give_Payment $this Payment object.
888
						 */
889 52
						do_action( 'give_payment_save', $this, $key );
890 52
						break;
891 52
				}// End switch().
892
			}// End foreach().
893
894 2
			if ( 'pending' !== $this->status ) {
895 1
896 1
				$donor = new Give_Donor( $this->customer_id );
0 ignored issues
show
$this->customer_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
897
898 1
				$total_change = $total_increase - $total_decrease;
899
				if ( $total_change < 0 ) {
900
901 1
					$total_change = - ( $total_change );
902 1
					// Decrease the donor's donation stats.
903 1
					$donor->decrease_value( $total_change );
904 1
					give_decrease_total_earnings( $total_change );
905 1
906 1
				} elseif ( $total_change > 0 ) {
907
908 1
					// Increase the donor's donation stats.
909
					$donor->increase_value( $total_change );
910
					give_increase_total_earnings( $total_change );
911
912 1
				}
913
			}
914 1
915
			$this->update_meta( '_give_payment_total', give_sanitize_amount_for_db( $this->total ) );
916
917
			$new_meta = array(
918
				'form_title' => $this->form_title,
919
				'form_id'    => $this->form_id,
920 52
				'price_id'   => $this->price_id,
921 52
				'currency'   => $this->currency,
922
				'user_info'  => $this->user_info,
923
			);
924 52
925 52
			$meta        = $this->get_meta();
926 52
			$merged_meta = array_merge( $meta, $new_meta );
927 52
928 52
			// Only save the payment meta if it's changed.
929
			if ( md5( serialize( $meta ) ) !== md5( serialize( $merged_meta ) ) ) {
930
				$updated = $this->update_meta( '_give_payment_meta', $merged_meta );
0 ignored issues
show
$merged_meta is of type array<string,string|integer|array>, but the function expects a string.

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...
931 52
				if ( false !== $updated ) {
932
					$saved = true;
0 ignored issues
show
$saved 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...
933
				}
934
			}
935
936 52
			$this->pending = array();
937 52
			$saved         = true;
938 52
		}// End if().
939 52
940 52
		if ( true === $saved ) {
941 52
			$this->setup_payment( $this->ID );
942 52
		}
943
944 52
		return $saved;
945
	}
946 52
947
	/**
948 52
	 * Add a donation to a given payment
949
	 *
950 52
	 * @since  1.5
951
	 * @access public
952
	 *
953
	 * @param  int   $form_id The donation form to add
954
	 * @param  array $args Other arguments to pass to the function
955
	 * @param  array $options List of donation options
956
	 *
957
	 * @return bool           True when successful, false otherwise
958
	 */
959
	public function add_donation( $form_id = 0, $args = array(), $options = array() ) {
960
961
		$donation = new Give_Donate_Form( $form_id );
0 ignored issues
show
$form_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
962
963
		// Bail if this post isn't a give donation form.
964 2
		if ( ! $donation || $donation->post_type !== 'give_forms' ) {
0 ignored issues
show
Found "!== '". Use Yoda Condition checks, you must
Loading history...
965
			return false;
966
		}
967
968 2
		// Set some defaults.
969 2
		$defaults = array(
970 2
			'price'    => false,
971 2
			'price_id' => false,
972 2
		);
973
974 2
		$args = wp_parse_args( apply_filters( 'give_payment_add_donation_args', $args, $donation->ID ), $defaults );
975
976
		// Allow overriding the price.
977 2
		if ( false !== $args['price'] ) {
978
			$item_price = $args['price'];
979
		} else {
980
981 2
			// Deal with variable pricing.
982 2
			if ( give_has_variable_prices( $donation->ID ) ) {
983 2
				$prices     = maybe_unserialize( give_get_meta( $form_id, '_give_donation_levels', true ) );
984 2
				$item_price = '';
985 2
				// Loop through prices.
986 2 View Code Duplication
				foreach ( $prices as $price ) {
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...
987
					// Find a match between price_id and level_id.
988 2
					// First verify array keys exists THEN make the match.
989
					if ( ( isset( $args['price_id'] ) && isset( $price['_give_id']['level_id'] ) )
990 2
					     && $args['price_id'] == $price['_give_id']['level_id']
991
					) {
992 2
						$item_price = $price['_give_amount'];
993
					}
994
				}
995
				// Fallback to the lowest price point.
996
				if ( $item_price == '' ) {
997
					$item_price       = give_get_lowest_price_option( $donation->ID );
998
					$args['price_id'] = give_get_lowest_price_id( $donation->ID );
999
				}
1000
			} else {
1001
				// Simple form price.
1002
				$item_price = give_get_form_price( $donation->ID );
1003
			}
1004
		}
1005
1006
		// Sanitizing the price here so we don't have a dozen calls later.
1007
		$item_price = give_maybe_sanitize_amount( $item_price );
1008
		$total      = round( $item_price, give_currency_decimal_filter() );
1009
1010
		// Add Options.
1011
		$default_options = array();
1012
		if ( false !== $args['price_id'] ) {
1013
			$default_options['price_id'] = (int) $args['price_id'];
1014
		}
1015
		$options = wp_parse_args( $options, $default_options );
1016
1017
		// Do not allow totals to go negative.
1018
		if ( $total < 0 ) {
1019
			$total = 0;
1020
		}
1021
1022
		$donation = array(
1023
			'name'     => $donation->post_title,
1024
			'id'       => $donation->ID,
1025
			'price'    => round( $total, give_currency_decimal_filter() ),
1026
			'subtotal' => round( $total, give_currency_decimal_filter() ),
1027
			'price_id' => $args['price_id'],
1028
			'action'   => 'add',
1029
			'options'  => $options,
1030
		);
1031
1032
		$this->pending['donations'][] = $donation;
1033
1034
		$this->increase_subtotal( $total );
1035
1036
		return true;
1037
1038
	}
1039
1040
	/**
1041
	 * Remove a donation from the payment
1042
	 *
1043
	 * @since  1.5
1044
	 * @access public
1045
	 *
1046
	 * @param  int   $form_id The form ID to remove
1047
	 * @param  array $args Arguments to pass to identify (quantity, amount, price_id)
1048
	 *
1049
	 * @return bool           If the item was removed or not
1050
	 */
1051
	public function remove_donation( $form_id, $args = array() ) {
1052
1053
		// Set some defaults.
1054
		$defaults = array(
1055
			'quantity' => 1,
1056
			'price'    => false,
1057
			'price_id' => false,
1058
		);
1059
		$args     = wp_parse_args( $args, $defaults );
1060
1061
		$form = new Give_Donate_Form( $form_id );
0 ignored issues
show
$form_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1062
1063
		// Bail if this post isn't a valid give donation form.
1064
		if ( ! $form || $form->post_type !== 'give_forms' ) {
0 ignored issues
show
Found "!== '". Use Yoda Condition checks, you must
Loading history...
1065
			return false;
1066
		}
1067
1068
		$pending_args             = $args;
1069
		$pending_args['id']       = $form_id;
1070
		$pending_args['amount']   = $this->total;
1071
		$pending_args['price_id'] = false !== $args['price_id'] ? (int) $args['price_id'] : false;
1072
		$pending_args['quantity'] = $args['quantity'];
1073
		$pending_args['action']   = 'remove';
1074
1075
		$this->pending['donations'][] = $pending_args;
1076
1077
		$this->decrease_subtotal( $this->total );
1078
1079
		return true;
1080
	}
1081
1082
1083
	/**
1084
	 * Add a note to a payment
1085
	 *
1086
	 * @since  1.5
1087
	 * @access public
1088
	 *
1089
	 * @param  string $note The note to add
1090
	 *
1091
	 * @return void
1092
	 */
1093
	public function add_note( $note = false ) {
1094
		// Bail if no note specified.
1095
		if ( ! $note ) {
1096
			return false;
1097
		}
1098
1099
		give_insert_payment_note( $this->ID, $note );
1100
	}
1101
1102
	/**
1103
	 * Increase the payment's subtotal
1104
	 *
1105
	 * @since  1.5
1106
	 * @access private
1107
	 *
1108
	 * @param  float $amount The amount to increase the payment subtotal by.
1109
	 *
1110
	 * @return void
1111
	 */
1112
	private function increase_subtotal( $amount = 0.00 ) {
1113
		$amount         = (float) $amount;
1114
		$this->subtotal += $amount;
1115
1116
		$this->recalculate_total();
1117
	}
1118
1119
	/**
1120
	 * Decrease the payment's subtotal.
1121
	 *
1122
	 * @since  1.5
1123
	 * @access private
1124
	 *
1125
	 * @param  float $amount The amount to decrease the payment subtotal by.
1126
	 *
1127
	 * @return void
1128
	 */
1129
	private function decrease_subtotal( $amount = 0.00 ) {
1130
		$amount         = (float) $amount;
1131
		$this->subtotal -= $amount;
1132
1133
		if ( $this->subtotal < 0 ) {
1134
			$this->subtotal = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $subtotal was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1135
		}
1136
1137
		$this->recalculate_total();
1138
	}
1139
1140
	/**
1141
	 * Set or update the total for a payment.
1142
	 *
1143
	 * @since  1.5
1144
	 * @access private
1145
	 *
1146
	 * @return void
1147
	 */
1148
	private function recalculate_total() {
1149
		$this->total = $this->subtotal;
1150
	}
1151
1152
	/**
1153
	 * Set the payment status and run any status specific changes necessary.
1154
	 *
1155
	 * @since  1.5
1156
	 * @access public
1157
	 *
1158
	 * @param  string|bool $status The status to set the payment to.
1159
	 *
1160
	 * @return bool   $updated Returns if the status was successfully updated.
1161
	 */
1162
	public function update_status( $status = false ) {
1163
1164
		// standardize the 'complete(d)' status.
1165
		if ( $status == 'completed' || $status == 'complete' ) {
0 ignored issues
show
Found "== '". Use Yoda Condition checks, you must
Loading history...
1166
			$status = 'publish';
1167
		}
1168
1169
		$old_status = ! empty( $this->old_status ) ? $this->old_status : false;
1170
1171
		if ( $old_status === $status ) {
1172 52
			return false; // Don't permit status changes that aren't changes.
1173 52
		}
1174 52
1175
		$do_change = apply_filters( 'give_should_update_payment_status', true, $this->ID, $status, $old_status );
1176 52
1177 52
		$updated = false;
1178
1179
		if ( $do_change ) {
1180
1181
			/**
1182
			 * Fires before changing payment status.
1183
			 *
1184
			 * @since 1.5
1185
			 *
1186
			 * @param int $payment_id Payments ID.
1187
			 * @param string $status The new status.
1188 2
			 * @param string $old_status The old status.
1189 2
			 */
1190 2
			do_action( 'give_before_payment_status_change', $this->ID, $status, $old_status );
1191
1192 2
			$update_fields = array(
1193
				'ID'          => $this->ID,
1194
				'post_status' => $status,
1195
				'edit_date'   => current_time( 'mysql' ),
1196 2
			);
1197 2
1198
			$updated = wp_update_post( apply_filters( 'give_update_payment_status_fields', $update_fields ) );
1199
1200
			$all_payment_statuses  = give_get_payment_statuses();
1201
			$this->status_nicename = array_key_exists( $status, $all_payment_statuses ) ? $all_payment_statuses[ $status ] : ucfirst( $status );
1202
1203
			// Process any specific status functions.
1204
			switch ( $status ) {
1205
				case 'refunded':
1206
					$this->process_refund();
1207
					break;
1208
				case 'failed':
1209
					$this->process_failure();
1210
					break;
1211
				case 'pending':
1212
					$this->process_pending();
1213
					break;
1214
				case 'cancelled':
1215
					$this->process_cancelled();
1216
					break;
1217
				case 'revoked':
1218
					$this->process_revoked();
1219
					break;
1220
			}
1221
1222
			/**
1223
			 * Fires after changing payment status.
1224
			 *
1225
			 * @since 1.5
1226
			 *
1227
			 * @param int $payment_id Payment ID.
1228
			 * @param string $status The new status.
1229
			 * @param string $old_status The old status.
1230
			 */
1231
			do_action( 'give_update_payment_status', $this->ID, $status, $old_status );
1232
1233
		}// End if().
1234
1235
		return $updated;
1236
1237
	}
1238
1239
	/**
1240
	 * Change the status of the payment to refunded, and run the necessary changes
1241 52
	 *
1242 52
	 * @since  1.5
1243 52
	 * @access public
1244
	 *
1245
	 * @return void
1246
	 */
1247
	public function refund() {
1248
		$this->old_status        = $this->status;
1249
		$this->status            = 'refunded';
1250
		$this->pending['status'] = $this->status;
1251
1252
		$this->save();
1253
	}
1254 52
1255
	/**
1256
	 * Get a post meta item for the payment
1257 52
	 *
1258 39
	 * @since  1.5
1259 39
	 * @access public
1260
	 *
1261 52
	 * @param  string  $meta_key The Meta Key
1262
	 * @param  boolean $single Return single item or array
1263 52
	 *
1264 52
	 * @return mixed             The value from the post meta
1265
	 */
1266
	public function get_meta( $meta_key = '_give_payment_meta', $single = true ) {
1267 42
1268
		$meta = give_get_meta( $this->ID, $meta_key, $single );
1269 42
1270
		if ( $meta_key === '_give_payment_meta' ) {
0 ignored issues
show
Found "=== '". Use Yoda Condition checks, you must
Loading history...
1271
			$meta = (array) $meta;
1272 42
1273
			if ( empty( $meta['key'] ) ) {
1274 42
				$meta['key'] = $this->setup_payment_key();
1275
			}
1276
1277 42
			if ( empty( $meta['form_title'] ) ) {
1278 42
				$meta['form_title'] = $this->setup_form_title();
1279 42
			}
1280 42
1281
			if ( empty( $meta['email'] ) ) {
1282 42
				$meta['email'] = $this->setup_email();
1283
			}
1284 42
1285 42
			if ( empty( $meta['date'] ) ) {
1286
				$meta['date'] = get_post_field( 'post_date', $this->ID );
1287
			}
1288
		}
1289 42
1290 4
		$meta = apply_filters( "give_get_payment_meta_{$meta_key}", $meta, $this->ID );
1291 4
1292 42
		return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1293
	}
1294
1295 42
	/**
1296 3
	 * Update the post meta
1297 3
	 *
1298
	 * @since  1.5
1299
	 * @access public
1300 42
	 *
1301
	 * @param  string $meta_key The meta key to update
1302 42
	 * @param  string $meta_value The meta value
1303
	 * @param  string $prev_value Previous meta value
1304 42
	 *
1305
	 * @return int|bool           Meta ID if the key didn't exist, true on successful update, false on failure
1306
	 */
1307
	public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1308
		if ( empty( $meta_key ) ) {
1309
			return false;
1310
		}
1311
1312
		if ( $meta_key == 'key' || $meta_key == 'date' ) {
0 ignored issues
show
Found "== '". Use Yoda Condition checks, you must
Loading history...
1313
1314 4
			$current_meta              = $this->get_meta();
1315 4
			$current_meta[ $meta_key ] = $meta_value;
1316 4
1317 4
			$meta_key   = '_give_payment_meta';
1318
			$meta_value = $current_meta;
1319 4
1320 4
		} elseif ( $meta_key == 'email' || $meta_key == '_give_payment_user_email' ) {
0 ignored issues
show
Found "== '". Use Yoda Condition checks, you must
Loading history...
1321
1322
			$meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1323
			give_update_meta( $this->ID, '_give_payment_user_email', $meta_value );
1324
1325
			$current_meta                       = $this->get_meta();
1326
			$current_meta['user_info']['email'] = $meta_value;
1327
1328
			$meta_key   = '_give_payment_meta';
1329
			$meta_value = $current_meta;
1330
1331
		}
1332 52
1333
		$meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1334 52
1335
		return give_update_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1336 52
	}
1337
1338 52
	/**
1339 52
	 * When a payment is set to a status of 'refunded' process the necessary actions to reduce stats
1340 52
	 *
1341
	 * @since  1.5
1342 52
	 * @access private
1343 52
	 *
1344 52
	 * @return void
1345
	 */
1346 52 View Code Duplication
	private function process_refund() {
0 ignored issues
show
This method 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...
1347 52
		$process_refund = true;
1348 52
1349
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1350 52
		if ( 'publish' != $this->old_status || 'refunded' != $this->status ) {
1351 52
			$process_refund = false;
1352 52
		}
1353 52
1354
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1355 52
		$process_refund = apply_filters( 'give_should_process_refund', $process_refund, $this );
1356
1357 52
		if ( false === $process_refund ) {
1358
			return;
1359
		}
1360
1361
		/**
1362
		 * Fires before refunding payment.
1363
		 *
1364
		 * @since 1.5
1365
		 *
1366
		 * @param Give_Payment $this Payment object.
1367
		 */
1368
		do_action( 'give_pre_refund_payment', $this );
1369
1370
		$decrease_earnings       = apply_filters( 'give_decrease_store_earnings_on_refund', true, $this );
1371 52
		$decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_refund', true, $this );
1372 52
		$decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_refund', true, $this );
1373
1374
		$this->maybe_alter_stats( $decrease_earnings, $decrease_customer_value, $decrease_purchase_count );
1375
		$this->delete_sales_logs();
1376 52
1377
		// @todo: Refresh only range related stat cache
1378
		give_delete_donation_stats();
1379
1380
		/**
1381
		 * Fires after refunding payment.
1382
		 *
1383
		 * @since 1.5
1384 52
		 *
1385
		 * @param Give_Payment $this Payment object.
1386 52
		 */
1387 52
		do_action( 'give_post_refund_payment', $this );
1388
	}
1389 52
1390 52
	/**
1391
	 * Process when a payment is set to failed
1392 52
	 *
1393 52
	 * @since  1.5
1394
	 * @access private
1395 52
	 *
1396
	 * @return void
1397 52
	 */
1398
	private function process_failure() {
1399 52
1400
	}
1401
1402
	/**
1403
	 * Process when a payment moves to pending
1404
	 *
1405
	 * @since  1.5
1406
	 * @access private
1407
	 *
1408
	 * @return void
1409 4
	 */
1410 4 View Code Duplication
	private function process_pending() {
0 ignored issues
show
This method 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...
1411
		$process_pending = true;
1412
1413 4
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1414
		if ( 'publish' != $this->old_status || 'pending' != $this->status ) {
1415
			$process_pending = false;
1416
		}
1417
1418 4
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1419
		$process_pending = apply_filters( 'give_should_process_pending', $process_pending, $this );
1420 4
1421
		if ( false === $process_pending ) {
1422
			return;
1423
		}
1424 4
1425
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_pending', true, $this );
1426 4
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_pending', true, $this );
1427 4
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_pending', true, $this );
1428 4
1429
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1430 4
		$this->delete_sales_logs();
1431 4
1432
		$this->completed_date = false;
0 ignored issues
show
Documentation Bug introduced by
The property $completed_date was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1433
		$this->update_meta( '_give_completed_date', '' );
1434 4
1435
		// @todo: Refresh only range related stat cache
1436 4
		give_delete_donation_stats();
1437 4
	}
1438
1439
	/**
1440
	 * Process when a payment moves to cancelled.
1441
	 *
1442
	 * @since  1.5
1443
	 * @access private
1444
	 *
1445
	 * @return void
1446
	 */
1447 View Code Duplication
	private function process_cancelled() {
0 ignored issues
show
This method 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...
1448
		$process_cancelled = true;
1449
1450
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1451
		if ( 'publish' != $this->old_status || 'cancelled' != $this->status ) {
1452
			$process_cancelled = false;
1453
		}
1454
1455
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1456 3
		$process_cancelled = apply_filters( 'give_should_process_cancelled', $process_cancelled, $this );
1457 3
1458
		if ( false === $process_cancelled ) {
1459
			return;
1460 3
		}
1461 1
1462 1
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_cancelled', true, $this );
1463
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_cancelled', true, $this );
1464
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_cancelled', true, $this );
1465 3
1466
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1467 3
		$this->delete_sales_logs();
1468 1
1469
		$this->completed_date = false;
0 ignored issues
show
Documentation Bug introduced by
The property $completed_date was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1470
		$this->update_meta( '_give_completed_date', '' );
1471 2
1472 2
		// @todo: Refresh only range related stat cache
1473 2
		give_delete_donation_stats();
1474
	}
1475 2
1476 2
	/**
1477
	 * Process when a payment moves to revoked.
1478 2
	 *
1479 2
	 * @since  1.5
1480
	 * @return void
1481
	 */
1482 2 View Code Duplication
	private function process_revoked() {
0 ignored issues
show
This method 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...
1483 2
		$process_revoked = true;
1484
1485
		// If the payment was not in publish, don't decrement stats as they were never incremented.
1486
		if ( 'publish' != $this->old_status || 'revoked' != $this->status ) {
1487
			$process_revoked = false;
1488
		}
1489
1490
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1491
		$process_revoked = apply_filters( 'give_should_process_revoked', $process_revoked, $this );
1492
1493
		if ( false === $process_revoked ) {
1494
			return;
1495
		}
1496 6
1497
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_revoked', true, $this );
1498 6
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_revoked', true, $this );
1499
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_revoked', true, $this );
1500
1501 6
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1502 4
		$this->delete_sales_logs();
1503 4
1504
		$this->completed_date = false;
0 ignored issues
show
Documentation Bug introduced by
The property $completed_date was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1505
		$this->update_meta( '_give_completed_date', '' );
1506 6
1507
		// @todo: Refresh only range related stat cache
1508 6
		give_delete_donation_stats();
1509
	}
1510 6
1511 4
	/**
1512 4
	 * Used during the process of moving to refunded or pending, to decrement stats
1513
	 *
1514 6
	 * @since  1.5
1515 4
	 * @access private
1516 4
	 *
1517
	 * @param  bool $alter_store_earnings If the method should alter the store earnings
1518 6
	 * @param  bool $alter_customer_value If the method should reduce the donor value
1519
	 * @param  bool $alter_customer_purchase_count If the method should reduce the donor's purchase count
1520 6
	 *
1521
	 * @return void
1522
	 */
1523
	private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1524
1525
		give_undo_donation( $this->ID );
1526
1527
		// Decrease store earnings.
1528 6
		if ( true === $alter_store_earnings ) {
1529 6
			give_decrease_total_earnings( $this->total );
1530
		}
1531
1532 6
		// Decrement the stats for the donor.
1533 6
		if ( ! empty( $this->customer_id ) ) {
1534 6
1535
			$donor = new Give_Donor( $this->customer_id );
0 ignored issues
show
$this->customer_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1536
1537 6
			if ( true === $alter_customer_value ) {
1538 6
				$donor->decrease_value( $this->total );
1539 6
			}
1540
1541 6
			if ( true === $alter_customer_purchase_count ) {
1542 6
				$donor->decrease_donation_count();
1543
			}
1544
		}
1545
1546
	}
1547
1548
	/**
1549
	 * Delete sales logs for this donation
1550
	 *
1551
	 * @since  1.5
1552
	 * @access private
1553
	 *
1554
	 * @return void
1555
	 */
1556
	private function delete_sales_logs() {
1557
		global $give_logs;
1558
1559 52
		// Remove related sale log entries.
1560 52
		$give_logs->delete_logs(
1561
			null,
1562 52
			'sale',
1563 52
			array(
1564
				array(
1565
					'key'   => '_give_log_payment_id',
1566 42
					'value' => $this->ID,
1567
				),
1568 42
			)
1569
		);
1570
	}
1571
1572
	/**
1573
	 * Setup functions only, these are not to be used by developers.
1574
	 * These functions exist only to allow the setup routine to be backwards compatible with our old
1575
	 * helper functions.
1576
	 *
1577 52
	 * These will run whenever setup_payment is called, which should only be called once.
1578 52
	 * To update an attribute, update it directly instead of re-running the setup routine
1579
	 */
1580
1581
	/**
1582
	 * Setup the payment completed date
1583
	 *
1584
	 * @since  1.5
1585
	 * @access private
1586
	 *
1587 52
	 * @return string The date the payment was completed
1588 52
	 */
1589
	private function setup_completed_date() {
1590 52
		$payment = get_post( $this->ID );
1591 2
1592 2
		if ( 'pending' == $payment->post_status || 'preapproved' == $payment->post_status ) {
1593
			return false; // This payment was never completed.
1594 2
		}
1595
1596
		$date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1597 2
1598
		return $date;
1599 52
	}
1600
1601
	/**
1602
	 * Setup the payment mode
1603
	 *
1604
	 * @since  1.5
1605
	 * @access private
1606
	 *
1607
	 * @return string The payment mode
1608 52
	 */
1609 52
	private function setup_mode() {
1610
		return $this->get_meta( '_give_payment_mode' );
1611 52
	}
1612
1613
	/**
1614
	 * Setup the payment total
1615
	 *
1616
	 * @since  1.5
1617
	 * @access private
1618
	 *
1619
	 * @return float The payment total
1620 52
	 */
1621 52
	private function setup_total() {
1622
		$amount = $this->get_meta( '_give_payment_total', true );
1623 52
1624 52
		if ( empty( $amount ) && '0.00' != $amount ) {
1625
			$meta = $this->get_meta( '_give_payment_meta', true );
1626
			$meta = maybe_unserialize( $meta );
1627
1628
			if ( isset( $meta['amount'] ) ) {
1629
				$amount = $meta['amount'];
1630 52
			}
1631
		}
1632
1633
		return round( floatval( $amount ), give_currency_decimal_filter() );
1634
	}
1635
1636
	/**
1637
	 * Setup the payment subtotal
1638
	 *
1639
	 * @since  1.5
1640 52
	 * @access private
1641 52
	 *
1642
	 * @return float The subtotal of the payment
1643 52
	 */
1644
	private function setup_subtotal() {
1645
		$subtotal = $this->total;
1646
1647
		return $subtotal;
1648
	}
1649
1650
	/**
1651
	 * Setup the currency code
1652 52
	 *
1653 52
	 * @since  1.5
1654
	 * @access private
1655 52
	 *
1656
	 * @return string The currency for the payment
1657
	 */
1658
	private function setup_currency() {
1659
		$currency = isset( $this->payment_meta['currency'] ) ? $this->payment_meta['currency'] : apply_filters( 'give_payment_currency_default', give_get_currency(), $this );
1660
1661
		return $currency;
1662
	}
1663
1664 52
	/**
1665 52
	 * Setup the gateway used for the payment
1666
	 *
1667 52
	 * @since  1.5
1668
	 * @access private
1669
	 *
1670
	 * @return string The gateway
1671
	 */
1672
	private function setup_gateway() {
1673
		$gateway = $this->get_meta( '_give_payment_gateway', true );
1674
1675
		return $gateway;
1676 52
	}
1677 52
1678
	/**
1679 52
	 * Setup the donation ID
1680
	 *
1681 52
	 * @since  1.5
1682 52
	 * @access private
1683
	 *
1684 52
	 * @return string The donation ID
1685
	 */
1686 52
	private function setup_transaction_id() {
1687
		$transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1688
1689
		if ( empty( $transaction_id ) ) {
1690
			$gateway        = $this->gateway;
1691
			$transaction_id = apply_filters( "give_get_payment_transaction_id-{$gateway}", $this->ID );
1692
		}
1693
1694
		return $transaction_id;
1695 52
	}
1696 52
1697
	/**
1698 52
	 * Setup the IP Address for the payment
1699
	 *
1700
	 * @since  1.5
1701
	 * @access private
1702
	 *
1703
	 * @return string The IP address for the payment
1704
	 */
1705
	private function setup_ip() {
1706
		$ip = $this->get_meta( '_give_payment_user_ip', true );
1707 52
1708 52
		return $ip;
1709
	}
1710 52
1711
	/**
1712
	 * Setup the donor ID.
1713
	 *
1714
	 * @since  1.5
1715
	 * @access private
1716
	 *
1717
	 * @return int The Donor ID.
1718
	 */
1719 52
	private function setup_donor_id() {
1720 52
		$customer_id = $this->get_meta( '_give_payment_customer_id', true );
1721
1722 52
		return $customer_id;
1723
	}
1724
1725
	/**
1726
	 * Setup the User ID associated with the donation
1727
	 *
1728
	 * @since  1.5
1729
	 * @access private
1730
	 *
1731 52
	 * @return int The User ID
1732 52
	 */
1733
	private function setup_user_id() {
1734 52
		$user_id = $this->get_meta( '_give_payment_user_id', true );
1735 2
1736 2
		return $user_id;
1737
	}
1738 52
1739
	/**
1740
	 * Setup the email address for the donation.
1741
	 *
1742
	 * @since  1.5
1743
	 * @access private
1744
	 *
1745
	 * @return string The email address for the payment.
1746
	 */
1747 52
	private function setup_email() {
1748
		$email = $this->get_meta( '_give_payment_user_email', true );
1749 52
1750 52
		if ( empty( $email ) && $this->customer_id ) {
1751 52
			$email = Give()->donors->get_column( 'email', $this->customer_id );
1752
		}
1753 52
1754 52
		return $email;
1755
	}
1756 52
1757
	/**
1758
	 * Setup the user info.
1759
	 *
1760
	 * @since  1.5
1761
	 * @access private
1762
	 *
1763
	 * @return array The user info associated with the payment.
1764
	 */
1765
	private function setup_user_info() {
1766
		$defaults = array(
1767
			'first_name' => $this->first_name,
1768
			'last_name'  => $this->last_name,
1769
		);
1770
1771 52
		$user_info = isset( $this->payment_meta['user_info'] ) ? maybe_unserialize( $this->payment_meta['user_info'] ) : array();
1772 52
		$user_info = wp_parse_args( $user_info, $defaults );
1773 52
1774 52
		if ( empty( $user_info ) ) {
1775 52
			// Get the donor, but only if it's been created.
1776
			$donor = new Give_Donor( $this->customer_id );
0 ignored issues
show
$this->customer_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1777
1778
			if ( $donor->id > 0 ) {
1779 21
				$name      = explode( ' ', $donor->name, 2 );
1780 21
				$user_info = array(
1781
					'first_name' => $name[0],
1782 21
					'last_name'  => $name[1],
1783 21
					'email'      => $donor->email,
1784
					'discount'   => 'none',
1785 21
				);
1786 21
			}
1787 21
		} else {
1788
			// Get the donor, but only if it's been created.
1789 21
			$donor = new Give_Donor( $this->customer_id );
0 ignored issues
show
$this->customer_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1790 21
			if ( $donor->id > 0 ) {
1791
				foreach ( $user_info as $key => $value ) {
1792
					if ( ! empty( $value ) ) {
1793
						continue;
1794
					}
1795
1796 52
					switch ( $key ) {
1797
						case 'first_name':
1798 52
							$name = explode( ' ', $donor->name, 2 );
1799
1800
							$user_info[ $key ] = $name[0];
1801 52
							break;
1802
1803
						case 'last_name':
1804
							$name      = explode( ' ', $donor->name, 2 );
1805
							$last_name = ! empty( $name[1] ) ? $name[1] : '';
1806
1807
							$user_info[ $key ] = $last_name;
1808
							break;
1809
1810
						case 'email':
1811 52
							$user_info[ $key ] = $donor->email;
1812
							break;
1813 52
					}
1814 52
				}
1815 52
			}
1816 52
		}// End if().
1817 52
1818 52
		return $user_info;
1819
1820 52
	}
1821
1822 52
	/**
1823
	 * Setup the Address for the payment.
1824
	 *
1825
	 * @since  1.5
1826
	 * @access private
1827
	 *
1828
	 * @return array The Address information for the payment.
1829
	 */
1830
	private function setup_address() {
1831 52
1832
		$address = ! empty( $this->payment_meta['user_info']['address'] ) ? $this->payment_meta['user_info']['address'] : array(
1833 52
			'line1'   => '',
1834
			'line2'   => '',
1835 52
			'city'    => '',
1836
			'country' => '',
1837
			'state'   => '',
1838
			'zip'     => '',
1839
		);
1840
1841
		return $address;
1842
	}
1843
1844 52
	/**
1845
	 * Setup the form title.
1846 52
	 *
1847
	 * @since  1.5
1848 52
	 * @access private
1849
	 *
1850
	 * @return string The Form Title.
1851
	 */
1852
	private function setup_form_title() {
1853
1854
		$form_id = $this->get_meta( '_give_payment_form_title', true );
1855
1856
		return $form_id;
1857 52
	}
1858 52
1859
	/**
1860 52
	 * Setup the form ID.
1861
	 *
1862
	 * @since  1.5
1863
	 * @access private
1864
	 *
1865
	 * @return int The Form ID
1866
	 */
1867
	private function setup_form_id() {
1868
1869 52
		$form_id = $this->get_meta( '_give_payment_form_id', true );
1870 52
1871
		return $form_id;
1872 52
	}
1873
1874
	/**
1875
	 * Setup the price ID.
1876
	 *
1877
	 * @since  1.5
1878
	 * @access private
1879
	 *
1880
	 * @return int The Form Price ID.
1881 52
	 */
1882 52
	private function setup_price_id() {
1883
		$price_id = $this->get_meta( '_give_payment_price_id', true );
1884 52
1885
		return $price_id;
1886 20
	}
1887
1888 20
	/**
1889
	 * Setup the payment key.
1890 2
	 *
1891
	 * @since  1.5
1892 2
	 * @access private
1893
	 *
1894 20
	 * @return string The Payment Key.
1895
	 */
1896 52
	private function setup_payment_key() {
1897
		$key = $this->get_meta( '_give_payment_purchase_key', true );
1898
1899
		return $key;
1900
	}
1901
1902
	/**
1903
	 * Setup the payment number.
1904
	 *
1905
	 * @since  1.5
1906
	 * @access private
1907
	 *
1908
	 * @return int|string Integer by default, or string if sequential order numbers is enabled.
1909
	 */
1910
	private function setup_payment_number() {
1911
		$number = $this->ID;
1912
1913
		if ( give_get_option( 'enable_sequential' ) ) {
1914 42
1915 42
			$number = $this->get_meta( '_give_payment_number', true );
1916
1917
			if ( ! $number ) {
1918
1919
				$number = $this->ID;
1920
1921
			}
1922
		}
1923
1924
		return $number;
1925
	}
1926
1927
	/**
1928
	 * Converts this object into an array for special cases.
1929
	 *
1930
	 * @access public
1931
	 *
1932
	 * @return array The payment object as an array.
1933
	 */
1934 42
	public function array_convert() {
1935 42
		return get_object_vars( $this );
1936
	}
1937
1938
1939
	/**
1940
	 * Flag to check if donation is completed or not.
1941
	 *
1942
	 * @since  1.8
1943
	 * @access public
1944 42
	 *
1945 42
	 * @return bool
1946
	 */
1947
	public function is_completed() {
1948
		return ( 'publish' === $this->status && $this->completed_date );
1949
	}
1950
1951
	/**
1952
	 * Retrieve payment completion date.
1953
	 *
1954 11
	 * @since  1.5
1955 11
	 * @access private
1956
	 *
1957
	 * @return string Date payment was completed.
1958
	 */
1959
	private function get_completed_date() {
1960
		return apply_filters( 'give_payment_completed_date', $this->completed_date, $this->ID, $this );
1961
	}
1962
1963
	/**
1964
	 * Retrieve payment subtotal.
1965
	 *
1966
	 * @since  1.5
1967
	 * @access private
1968
	 *
1969
	 * @return float Payment subtotal.
1970
	 */
1971
	private function get_subtotal() {
1972
		return apply_filters( 'give_get_payment_subtotal', $this->subtotal, $this->ID, $this );
1973
	}
1974 52
1975 52
	/**
1976
	 * Retrieve payment currency.
1977
	 *
1978
	 * @since  1.5
1979
	 * @access private
1980
	 *
1981
	 * @return string Payment currency code.
1982
	 */
1983
	private function get_currency() {
1984 41
		return apply_filters( 'give_payment_currency_code', $this->currency, $this->ID, $this );
1985 41
	}
1986
1987
	/**
1988
	 * Retrieve payment gateway.
1989
	 *
1990
	 * @since  1.5
1991
	 * @access private
1992
	 *
1993
	 * @return string Gateway used.
1994 42
	 */
1995 42
	private function get_gateway() {
1996
		return apply_filters( 'give_payment_gateway', $this->gateway, $this->ID, $this );
1997
	}
1998
1999
	/**
2000
	 * Retrieve donation ID.
2001
	 *
2002
	 * @since  1.5
2003
	 * @access private
2004 43
	 *
2005 43
	 * @return string Donation ID from merchant processor.
2006
	 */
2007
	private function get_transaction_id() {
2008
		return apply_filters( 'give_get_payment_transaction_id', $this->transaction_id, $this->ID, $this );
2009
	}
2010
2011
	/**
2012
	 * Retrieve payment IP
2013
	 *
2014
	 * @since  1.5
2015
	 * @access private
2016
	 *
2017
	 * @return string Payment IP address
2018
	 */
2019
	private function get_ip() {
2020
		return apply_filters( 'give_payment_user_ip', $this->ip, $this->ID, $this );
2021
	}
2022
2023
	/**
2024 52
	 * Retrieve payment donor ID.
2025 52
	 *
2026
	 * @since  1.5
2027
	 * @access private
2028
	 *
2029
	 * @return int Payment donor ID.
2030
	 */
2031
	private function get_donor_id() {
2032
		return apply_filters( 'give_payment_customer_id', $this->customer_id, $this->ID, $this );
2033
	}
2034 52
2035 52
	/**
2036
	 * Retrieve payment user ID.
2037
	 *
2038
	 * @since  1.5
2039
	 * @access private
2040
	 *
2041
	 * @return int Payment user ID.
2042
	 */
2043
	private function get_user_id() {
2044 42
		return apply_filters( 'give_payment_user_id', $this->user_id, $this->ID, $this );
2045 42
	}
2046
2047
	/**
2048
	 * Retrieve payment email.
2049
	 *
2050
	 * @since  1.5
2051
	 * @access private
2052
	 *
2053
	 * @return string Payment donor email.
2054
	 */
2055
	private function get_email() {
2056
		return apply_filters( 'give_payment_user_email', $this->email, $this->ID, $this );
2057
	}
2058
2059
	/**
2060
	 * Retrieve payment user info.
2061
	 *
2062
	 * @since  1.5
2063
	 * @access private
2064
	 *
2065
	 * @return array Payment user info.
2066
	 */
2067
	private function get_user_info() {
2068
		return apply_filters( 'give_payment_meta_user_info', $this->user_info, $this->ID, $this );
2069
	}
2070
2071
	/**
2072
	 * Retrieve payment billing address.
2073
	 *
2074
	 * @since  1.5
2075
	 * @access private
2076
	 *
2077
	 * @return array Payment billing address.
2078
	 */
2079
	private function get_address() {
2080
		return apply_filters( 'give_payment_address', $this->address, $this->ID, $this );
2081
	}
2082
2083
	/**
2084
	 * Retrieve payment key.
2085
	 *
2086
	 * @since  1.5
2087
	 * @access private
2088
	 *
2089
	 * @return string Payment key.
2090
	 */
2091
	private function get_key() {
2092
		return apply_filters( 'give_payment_key', $this->key, $this->ID, $this );
2093
	}
2094
2095
	/**
2096
	 * Retrieve payment form id
2097
	 *
2098
	 * @since  1.5
2099
	 * @access private
2100
	 *
2101
	 * @return string Payment form id
2102
	 */
2103
	private function get_form_id() {
2104
		return apply_filters( 'give_payment_form_id', $this->form_id, $this->ID, $this );
2105
	}
2106
2107
	/**
2108
	 * Retrieve payment number
2109
	 *
2110
	 * @since  1.5
2111
	 * @access private
2112
	 *
2113
	 * @return int|string Payment number
2114
	 */
2115
	private function get_number() {
2116
		return apply_filters( 'give_payment_number', $this->number, $this->ID, $this );
2117
	}
2118
2119
}
2120