Completed
Push — issues/1132 ( 88095e )
by Ravinder
18:14
created

Give_Payment::setup_address()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 19
nc 2
nop 0
dl 0
loc 28
rs 8.8571
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 55 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

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

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
375
	 */
376
	public function __construct( $payment_id = false ) {
377
378
		if ( empty( $payment_id ) ) {
379
			return false;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
380
		}
381
382
		$this->setup_payment( $payment_id );
383
	}
384
385
	/**
386
	 * Magic GET function.
387
	 *
388
	 * @since  1.5
389
	 * @access public
390
	 *
391
	 * @param  string $key The property.
392
	 *
393
	 * @return mixed        The value.
394
	 */
395
	public function __get( $key ) {
396
397
		if ( method_exists( $this, 'get_' . $key ) ) {
398
399
			$value = call_user_func( array( $this, 'get_' . $key ) );
400
401
		} else {
402
403
			$value = $this->$key;
404
405
		}
406
407
		return $value;
408
	}
409
410
	/**
411
	 * Magic SET function
412
	 *
413
	 * Sets up the pending array for the save method
414
	 *
415
	 * @since  1.5
416
	 * @access public
417
	 *
418
	 * @param  string $key   The property name
419
	 * @param  mixed  $value The value of the property
420
	 */
421
	public function __set( $key, $value ) {
422
		$ignore = array( '_ID' );
423
424
		if ( $key === 'status' ) {
425
			$this->old_status = $this->status;
426
		}
427
428
		if ( ! in_array( $key, $ignore ) ) {
429
			$this->pending[ $key ] = $value;
430
		}
431
432
		if ( '_ID' !== $key ) {
433
			$this->$key = $value;
434
		}
435
	}
436
437
	/**
438
	 * Magic ISSET function, which allows empty checks on protected elements
439
	 *
440
	 * @since  1.5
441
	 * @access public
442
	 *
443
	 * @param  string $name The attribute to get
444
	 *
445
	 * @return boolean       If the item is set or not
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
446
	 */
447
	public function __isset( $name ) {
448
		if ( property_exists( $this, $name ) ) {
449
			return false === empty( $this->$name );
450
		} else {
451
			return null;
452
		}
453
	}
454
455
	/**
456
	 * Setup payment properties
457
	 *
458
	 * @since  1.5
459
	 * @access private
460
	 *
461
	 * @param  int $payment_id The payment ID
462
	 *
463
	 * @return bool            If the setup was successful or not
464
	 */
465
	private function setup_payment( $payment_id ) {
466
		$this->pending = array();
467
468
		if ( empty( $payment_id ) ) {
469
			return false;
470
		}
471
472
		$payment = get_post( $payment_id );
473
474
		if ( ! $payment || is_wp_error( $payment ) ) {
475
			return false;
476
		}
477
478
		if ( 'give_payment' !== $payment->post_type ) {
479
			return false;
480
		}
481
482
		/**
483
		 * Fires before payment setup.
484
		 *
485
		 * Allow extensions to perform actions before the payment is loaded.
486
		 *
487
		 * @since 1.5
488
		 *
489
		 * @param Give_Payment $this       Payment object.
490
		 * @param int          $payment_id The ID of the payment.
491
		 */
492
		do_action( 'give_pre_setup_payment', $this, $payment_id );
493
494
		// Primary Identifier.
495
		$this->ID = absint( $payment_id );
496
497
		// Protected ID that can never be changed.
498
		$this->_ID = absint( $payment_id );
499
500
		// We have a payment, get the generic payment_meta item to reduce calls to it.
501
		$this->payment_meta = $this->get_meta();
502
503
		// Status and Dates.
504
		$this->date           = $payment->post_date;
505
		$this->post_date      = $payment->post_date;
506
		$this->completed_date = $this->setup_completed_date();
507
		$this->status         = $payment->post_status;
508
		$this->post_status    = $this->status;
509
		$this->mode           = $this->setup_mode();
510
		$this->parent_payment = $payment->post_parent;
511
512
		$all_payment_statuses  = give_get_payment_statuses();
513
		$this->status_nicename = array_key_exists( $this->status, $all_payment_statuses ) ? $all_payment_statuses[ $this->status ] : ucfirst( $this->status );
514
515
		// Currency Based.
516
		$this->total      = $this->setup_total();
517
		$this->subtotal   = $this->setup_subtotal();
518
		$this->currency   = $this->setup_currency();
519
520
		// Gateway based.
521
		$this->gateway        = $this->setup_gateway();
522
		$this->transaction_id = $this->setup_transaction_id();
523
524
		// User based.
525
		$this->ip          = $this->setup_ip();
526
		$this->customer_id = $this->setup_donor_id();
527
		$this->user_id     = $this->setup_user_id();
528
		$this->email       = $this->setup_email();
529
		$this->user_info   = $this->setup_user_info();
530
		$this->address     = $this->setup_address();
531
		$this->first_name  = $this->user_info['first_name'];
532
		$this->last_name   = $this->user_info['last_name'];
533
534
		// Other Identifiers.
535
		$this->form_title = $this->setup_form_title();
536
		$this->form_id    = $this->setup_form_id();
537
		$this->price_id   = $this->setup_price_id();
538
		$this->key        = $this->setup_payment_key();
539
		$this->number     = $this->setup_payment_number();
540
541
		/**
542
		 * Fires after payment setup.
543
		 *
544
		 * Allow extensions to add items to this object via hook.
545
		 *
546
		 * @since 1.5
547
		 *
548
		 * @param Give_Payment $this       Payment object.
549
		 * @param int          $payment_id The ID of the payment.
550
		 */
551
		do_action( 'give_setup_payment', $this, $payment_id );
552
553
		return true;
554
	}
555
556
	/**
557
	 * Payment class object is storing various meta value in object parameter.
558
	 * So if user is updating payment meta but not updating payment object, then payment meta values will not reflect/changes on payment meta automatically
559
	 * 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.
560
	 * To prevent that user can use this function after updating any payment meta value ( in bulk or single update ).
561
	 *
562
	 * @since  1.6
563
	 * @access public
564
	 *
565
	 * @param  int $payment_id Payment ID.
566
	 *
567
	 * @return void
568
	 */
569
	public function update_payment_setup( $payment_id ) {
570
		$this->setup_payment( $payment_id );
571
	}
572
573
	/**
574
	 * Create the base of a payment.
575
	 *
576
	 * @since  1.5
577
	 * @access private
578
	 *
579
	 * @return int|bool False on failure, the payment ID on success.
580
	 */
581
	private function insert_payment() {
582
583
		// Construct the payment title.
584
		$payment_title = '';
585
		if ( ! empty( $this->first_name ) && ! empty( $this->last_name ) ) {
586
			$payment_title = $this->first_name . ' ' . $this->last_name;
587
		} elseif ( ! empty( $this->first_name ) && empty( $this->last_name ) ) {
588
			$payment_title = $this->first_name;
589
		} elseif ( ! empty( $this->email ) && is_email( $this->email ) ) {
590
			$payment_title = $this->email;
591
		}
592
593
		// Set Key.
594
		if ( empty( $this->key ) ) {
595
596
			$auth_key             = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
597
			$this->key            = strtolower( md5( $this->email . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) );  // Unique key
598
			$this->pending['key'] = $this->key;
599
		}
600
601
		// Set IP.
602
		if ( empty( $this->ip ) ) {
603
604
			$this->ip            = give_get_ip();
605
			$this->pending['ip'] = $this->ip;
606
607
		}
608
609
		$payment_data = array(
610
			'price'        => $this->total,
611
			'date'         => $this->date,
612
			'user_email'   => $this->email,
613
			'purchase_key' => $this->key,
614
			'form_title'   => $this->form_title,
615
			'form_id'      => $this->form_id,
616
			'price_id'     => $this->price_id,
617
			'currency'     => $this->currency,
618
			'user_info'    => array(
619
				'id'         => $this->user_id,
620
				'email'      => $this->email,
621
				'first_name' => $this->first_name,
622
				'last_name'  => $this->last_name,
623
				'address'    => $this->address,
624
			),
625
			'status'       => $this->status,
626
		);
627
628
		$args = apply_filters( 'give_insert_payment_args', array(
629
			'post_title'    => $payment_title,
630
			'post_status'   => $this->status,
631
			'post_type'     => 'give_payment',
632
			'post_date'     => ! empty( $this->date ) ? $this->date : null,
633
			'post_date_gmt' => ! empty( $this->date ) ? get_gmt_from_date( $this->date ) : null,
634
			'post_parent'   => $this->parent_payment,
635
		), $payment_data );
636
637
		// Create a blank payment
638
		$payment_id = wp_insert_post( $args );
639
640
		if ( ! empty( $payment_id ) ) {
641
642
			$this->ID  = $payment_id;
643
			$this->_ID = $payment_id;
644
645
			$donor = new stdClass;
646
647
			if ( did_action( 'give_pre_process_donation' ) && is_user_logged_in() ) {
648
				$donor = new Give_Donor( get_current_user_id(), true );
649
650
				// Donor is logged in but used a different email to purchase with so assign to their donor record.
651
				if ( ! empty( $donor->id ) && $this->email != $donor->email ) {
652
					$donor->add_email( $this->email );
653
				}
654
			}
655
656
			if ( empty( $donor->id ) ) {
657
				$donor = new Give_Donor( $this->email );
658
			}
659
660
			if ( empty( $donor->id ) ) {
661
662
				$donor_data = array(
663
					'name'    => ! is_email( $payment_title ) ? $this->first_name . ' ' . $this->last_name : '',
664
					'email'   => $this->email,
665
					'user_id' => $this->user_id,
666
				);
667
668
				$donor->create( $donor_data );
0 ignored issues
show
Bug introduced by
The method create does only exist in Give_Donor, but not in stdClass.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
669
670
			}
671
672
			$this->customer_id            = $donor->id;
673
			$this->pending['customer_id'] = $this->customer_id;
674
			$donor->attach_payment( $this->ID, false );
0 ignored issues
show
Bug introduced by
The method attach_payment does only exist in Give_Donor, but not in stdClass.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
675
676
			$this->payment_meta = apply_filters( 'give_payment_meta', $this->payment_meta, $payment_data );
677
678
			$this->update_meta( '_give_payment_meta', $this->payment_meta );
679
			$this->new = true;
680
		}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
681
682
		return $this->ID;
683
684
	}
685
686
	/**
687
	 * Save
688
	 *
689
	 * Once items have been set, an update is needed to save them to the database.
690
	 *
691
	 * @access public
692
	 *
693
	 * @return bool  True of the save occurred, false if it failed or wasn't needed
694
	 */
695
	public function save() {
696
697
		$saved = false;
698
699
		// Must have an ID.
700
		if ( empty( $this->ID ) ) {
701
702
			$payment_id = $this->insert_payment();
703
704
			if ( false === $payment_id ) {
705
				$saved = false;
706
			} else {
707
				$this->ID = $payment_id;
708
			}
709
		}
710
711
		// Set ID if not matching.
712
		if ( $this->ID !== $this->_ID ) {
713
			$this->ID = $this->_ID;
714
		}
715
716
		// If we have something pending, let's save it.
717
		if ( ! empty( $this->pending ) ) {
718
719
			$total_increase = 0;
720
			$total_decrease = 0;
721
722
			foreach ( $this->pending as $key => $value ) {
723
724
				switch ( $key ) {
725
726
					case 'donations':
727
						// Update totals for pending donations.
728
						foreach ( $this->pending[ $key ] as $item ) {
729
730
							$quantity = isset( $item['quantity'] ) ? $item['quantity'] : 1;
731
							$price_id = isset( $item['price_id'] ) ? $item['price_id'] : 0;
732
733
							switch ( $item['action'] ) {
734
735
								case 'add':
736
737
									$price = $item['price'];
738
739
									if ( 'publish' === $this->status || 'complete' === $this->status ) {
740
741
										// Add sales logs.
742
										$log_date = date_i18n( 'Y-m-d G:i:s', current_time( 'timestamp' ) );
743
744
										$y = 0;
745
										while ( $y < $quantity ) {
746
747
											give_record_donation_in_log( $item['id'], $this->ID, $price_id, $log_date );
748
											$y ++;
749
										}
750
751
										$form = new Give_Donate_Form( $item['id'] );
752
										$form->increase_sales( $quantity );
753
										$form->increase_earnings( $price );
754
755
										$total_increase += $price;
756
									}
757
									break;
758
759
								case 'remove':
760
									$log_args = array(
761
										'post_type'   => 'give_log',
762
										'post_parent' => $item['id'],
763
										'numberposts' => $quantity,
764
										'meta_query'  => array(
765
											array(
766
												'key'     => '_give_log_payment_id',
767
												'value'   => $this->ID,
768
												'compare' => '=',
769
											),
770
											array(
771
												'key'     => '_give_log_price_id',
772
												'value'   => $price_id,
773
												'compare' => '=',
774
											),
775
										),
776
									);
777
778
									$found_logs = get_posts( $log_args );
779
									foreach ( $found_logs as $log ) {
780
										wp_delete_post( $log->ID, true );
781
									}
782
783
									if ( 'publish' === $this->status || 'complete' === $this->status ) {
784
										$form = new Give_Donate_Form( $item['id'] );
785
										$form->decrease_sales( $quantity );
786
										$form->decrease_earnings( $item['amount'] );
787
788
										$total_decrease += $item['amount'];
789
									}
790
									break;
791
792
							}// End switch().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
793
						}// End foreach().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
794
						break;
795
796
					case 'status':
797
						$this->update_status( $this->status );
798
						break;
799
800
					case 'gateway':
801
						$this->update_meta( '_give_payment_gateway', $this->gateway );
802
						break;
803
804
					case 'mode':
805
						$this->update_meta( '_give_payment_mode', $this->mode );
806
						break;
807
808
					case 'transaction_id':
809
						$this->update_meta( '_give_payment_transaction_id', $this->transaction_id );
810
						break;
811
812
					case 'ip':
813
						$this->update_meta( '_give_payment_donor_ip', $this->ip );
814
						break;
815
816
					case 'customer_id':
817
						$this->update_meta( '_give_payment_donor_id', $this->customer_id );
818
						break;
819
820
					// case 'user_id':
821
					// 	$this->update_meta( '_give_payment_user_id', $this->user_id );
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
822
					// 	break;
823
824
					case 'form_title':
825
						$this->update_meta( '_give_payment_form_title', $this->form_title );
826
						break;
827
828
					case 'form_id':
829
						$this->update_meta( '_give_payment_form_id', $this->form_id );
830
						break;
831
832
					case 'price_id':
833
						$this->update_meta( '_give_payment_price_id', $this->price_id );
834
						break;
835
836
					case 'first_name':
837
						$this->user_info['first_name'] = $this->first_name;
838
						break;
839
840
					case 'last_name':
841
						$this->user_info['last_name'] = $this->last_name;
842
						break;
843
844
					case 'address':
845
						$this->user_info['address'] = $this->address;
846
						break;
847
848
					case 'email':
849
						$this->update_meta( '_give_payment_donor_email', $this->email );
850
						break;
851
852
					case 'key':
853
						$this->update_meta( '_give_payment_purchase_key', $this->key );
854
						break;
855
856
					case 'number':
857
						$this->update_meta( '_give_payment_number', $this->number );
858
						break;
859
860
					case 'date':
861
						$args = array(
862
							'ID'        => $this->ID,
863
							'post_date' => $this->date,
864
							'edit_date' => true,
865
						);
866
867
						wp_update_post( $args );
868
						break;
869
870
					case 'completed_date':
871
						$this->update_meta( '_give_completed_date', $this->completed_date );
872
						break;
873
874
					case 'parent_payment':
875
						$args = array(
876
							'ID'          => $this->ID,
877
							'post_parent' => $this->parent_payment,
878
						);
879
880
						wp_update_post( $args );
881
						break;
882
883
					default:
884
						/**
885
						 * Fires while saving payment.
886
						 *
887
						 * @since 1.7
888
						 *
889
						 * @param Give_Payment $this Payment object.
890
						 */
891
						do_action( 'give_payment_save', $this, $key );
892
						break;
893
				}// End switch().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
894
			}// End foreach().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
895
896
			if ( 'pending' !== $this->status ) {
897
898
				$donor = new Give_Donor( $this->customer_id );
899
900
				$total_change = $total_increase - $total_decrease;
901
				if ( $total_change < 0 ) {
902
903
					$total_change = - ( $total_change );
904
					// Decrease the donor's donation stats.
905
					$donor->decrease_value( $total_change );
906
					give_decrease_total_earnings( $total_change );
907
908
				} elseif ( $total_change > 0 ) {
909
910
					// Increase the donor's donation stats.
911
					$donor->increase_value( $total_change );
912
					give_increase_total_earnings( $total_change );
913
914
				}
915
			}
916
917
			$this->update_meta( '_give_payment_total', $this->total );
918
919
			$new_meta = array(
920
				'form_title' => $this->form_title,
921
				'form_id'    => $this->form_id,
922
				'price_id'   => $this->price_id,
923
				'currency'   => $this->currency,
924
				'user_info'  => $this->user_info,
925
			);
926
927
			$meta        = $this->get_meta();
928
			$merged_meta = array_merge( $meta, $new_meta );
929
930
			// Only save the payment meta if it's changed.
931
			if ( md5( serialize( $meta ) ) !== md5( serialize( $merged_meta ) ) ) {
932
				$updated = $this->update_meta( '_give_payment_meta', $merged_meta );
933
				if ( false !== $updated ) {
934
					$saved = true;
935
				}
936
			}
937
938
			$this->pending = array();
939
			$saved         = true;
940
		}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
941
942
		if ( true === $saved ) {
943
			$this->setup_payment( $this->ID );
944
		}
945
946
		return $saved;
947
	}
948
949
	/**
950
	 * Add a donation to a given payment
951
	 *
952
	 * @since  1.5
953
	 * @access public
954
	 *
955
	 * @param  int   $form_id The donation form to add
956
	 * @param  array $args Other arguments to pass to the function
957
	 * @param  array $options List of donation options
958
	 *
959
	 * @return bool           True when successful, false otherwise
960
	 */
961
	public function add_donation( $form_id = 0, $args = array(), $options = array() ) {
962
963
		$donation = new Give_Donate_Form( $form_id );
964
965
		// Bail if this post isn't a give donation form.
966
		if ( ! $donation || $donation->post_type !== 'give_forms' ) {
0 ignored issues
show
Documentation introduced by
The property post_type does not exist on object<Give_Donate_Form>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

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

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1067
			return false;
1068
		}
1069
1070
		$pending_args             = $args;
1071
		$pending_args['id']       = $form_id;
1072
		$pending_args['amount']   = $this->total;
1073
		$pending_args['price_id'] = false !== $args['price_id'] ? (int) $args['price_id'] : false;
1074
		$pending_args['quantity'] = $args['quantity'];
1075
		$pending_args['action']   = 'remove';
1076
1077
		$this->pending['donations'][] = $pending_args;
1078
1079
		$this->decrease_subtotal( $this->total );
1080
1081
		return true;
1082
	}
1083
1084
1085
	/**
1086
	 * Add a note to a payment
1087
	 *
1088
	 * @since  1.5
1089
	 * @access public
1090
	 *
1091
	 * @param  string $note The note to add
1092
	 *
1093
	 * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be false|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1094
	 */
1095
	public function add_note( $note = false ) {
1096
		// Bail if no note specified.
1097
		if ( ! $note ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $note of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
1098
			return false;
1099
		}
1100
1101
		give_insert_payment_note( $this->ID, $note );
1102
	}
1103
1104
	/**
1105
	 * Increase the payment's subtotal
1106
	 *
1107
	 * @since  1.5
1108
	 * @access private
1109
	 *
1110
	 * @param  float $amount The amount to increase the payment subtotal by.
1111
	 *
1112
	 * @return void
1113
	 */
1114
	private function increase_subtotal( $amount = 0.00 ) {
1115
		$amount         = (float) $amount;
1116
		$this->subtotal += $amount;
1117
1118
		$this->recalculate_total();
1119
	}
1120
1121
	/**
1122
	 * Decrease the payment's subtotal.
1123
	 *
1124
	 * @since  1.5
1125
	 * @access private
1126
	 *
1127
	 * @param  float $amount The amount to decrease the payment subtotal by.
1128
	 *
1129
	 * @return void
1130
	 */
1131
	private function decrease_subtotal( $amount = 0.00 ) {
1132
		$amount         = (float) $amount;
1133
		$this->subtotal -= $amount;
1134
1135
		if ( $this->subtotal < 0 ) {
1136
			$this->subtotal = 0;
1137
		}
1138
1139
		$this->recalculate_total();
1140
	}
1141
1142
	/**
1143
	 * Set or update the total for a payment.
1144
	 *
1145
	 * @since  1.5
1146
	 * @access private
1147
	 *
1148
	 * @return void
1149
	 */
1150
	private function recalculate_total() {
1151
		$this->total = $this->subtotal;
1152
	}
1153
1154
	/**
1155
	 * Set the payment status and run any status specific changes necessary.
1156
	 *
1157
	 * @since  1.5
1158
	 * @access public
1159
	 *
1160
	 * @param  string|bool $status The status to set the payment to.
1161
	 *
1162
	 * @return bool   $updated Returns if the status was successfully updated.
1163
	 */
1164
	public function update_status( $status = false ) {
1165
1166
		// standardize the 'complete(d)' status.
1167
		if ( $status == 'completed' || $status == 'complete' ) {
1168
			$status = 'publish';
1169
		}
1170
1171
		$old_status = ! empty( $this->old_status ) ? $this->old_status : false;
1172
1173
		if ( $old_status === $status ) {
1174
			return false; // Don't permit status changes that aren't changes.
1175
		}
1176
1177
		$do_change = apply_filters( 'give_should_update_payment_status', true, $this->ID, $status, $old_status );
1178
1179
		$updated = false;
1180
1181
		if ( $do_change ) {
1182
1183
			/**
1184
			 * Fires before changing payment status.
1185
			 *
1186
			 * @since 1.5
1187
			 *
1188
			 * @param int $payment_id Payments ID.
1189
			 * @param string $status The new status.
1190
			 * @param string $old_status The old status.
1191
			 */
1192
			do_action( 'give_before_payment_status_change', $this->ID, $status, $old_status );
1193
1194
			$update_fields = array(
1195
				'ID'          => $this->ID,
1196
				'post_status' => $status,
1197
				'edit_date'   => current_time( 'mysql' ),
1198
			);
1199
1200
			$updated = wp_update_post( apply_filters( 'give_update_payment_status_fields', $update_fields ) );
1201
1202
			$all_payment_statuses  = give_get_payment_statuses();
1203
			$this->status_nicename = array_key_exists( $status, $all_payment_statuses ) ? $all_payment_statuses[ $status ] : ucfirst( $status );
1204
1205
			// Process any specific status functions.
1206
			switch ( $status ) {
1207
				case 'refunded':
1208
					$this->process_refund();
1209
					break;
1210
				case 'failed':
1211
					$this->process_failure();
0 ignored issues
show
Unused Code introduced by
The call to the method Give_Payment::process_failure() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
1212
					break;
1213
				case 'pending':
1214
					$this->process_pending();
1215
					break;
1216
				case 'cancelled':
1217
					$this->process_cancelled();
1218
					break;
1219
				case 'revoked':
1220
					$this->process_revoked();
1221
					break;
1222
			}
1223
1224
			/**
1225
			 * Fires after changing payment status.
1226
			 *
1227
			 * @since 1.5
1228
			 *
1229
			 * @param int $payment_id Payment ID.
1230
			 * @param string $status The new status.
1231
			 * @param string $old_status The old status.
1232
			 */
1233
			do_action( 'give_update_payment_status', $this->ID, $status, $old_status );
1234
1235
		}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1236
1237
		return $updated;
1238
1239
	}
1240
1241
	/**
1242
	 * Change the status of the payment to refunded, and run the necessary changes
1243
	 *
1244
	 * @since  1.5
1245
	 * @access public
1246
	 *
1247
	 * @return void
1248
	 */
1249
	public function refund() {
1250
		$this->old_status        = $this->status;
1251
		$this->status            = 'refunded';
1252
		$this->pending['status'] = $this->status;
1253
1254
		$this->save();
1255
	}
1256
1257
	/**
1258
	 * Get a post meta item for the payment
1259
	 *
1260
	 * @since  1.5
1261
	 * @access public
1262
	 *
1263
	 * @param  string  $meta_key The Meta Key
1264
	 * @param  boolean $single Return single item or array
1265
	 *
1266
	 * @return mixed             The value from the post meta
1267
	 */
1268
	public function get_meta( $meta_key = '_give_payment_meta', $single = true ) {
1269
1270
		$meta = give_get_meta( $this->ID, $meta_key, $single );
1271
1272
		if ( $meta_key === '_give_payment_meta' ) {
1273
			$meta = (array) $meta;
1274
1275
			if ( empty( $meta['key'] ) ) {
1276
				$meta['key'] = $this->setup_payment_key();
1277
			}
1278
1279
			if ( empty( $meta['form_title'] ) ) {
1280
				$meta['form_title'] = $this->setup_form_title();
1281
			}
1282
1283
			if ( empty( $meta['email'] ) ) {
1284
				$meta['email'] = $this->setup_email();
1285
			}
1286
1287
			if ( empty( $meta['date'] ) ) {
1288
				$meta['date'] = get_post_field( 'post_date', $this->ID );
1289
			}
1290
		}
1291
1292
		$meta = apply_filters( "give_get_payment_meta_{$meta_key}", $meta, $this->ID );
1293
1294
		return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1295
	}
1296
1297
	/**
1298
	 * Update the post meta
1299
	 *
1300
	 * @since  1.5
1301
	 * @access public
1302
	 *
1303
	 * @param  string $meta_key The meta key to update
1304
	 * @param  string $meta_value The meta value
1305
	 * @param  string $prev_value Previous meta value
1306
	 *
1307
	 * @return int|bool           Meta ID if the key didn't exist, true on successful update, false on failure
1308
	 */
1309
	public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1310
		if ( empty( $meta_key ) ) {
1311
			return false;
1312
		}
1313
1314
		if ( $meta_key == 'key' || $meta_key == 'date' ) {
1315
1316
			$current_meta              = $this->get_meta();
1317
			$current_meta[ $meta_key ] = $meta_value;
1318
1319
			$meta_key   = '_give_payment_meta';
1320
			$meta_value = $current_meta;
1321
1322
		} elseif ( $meta_key == 'email' || $meta_key == '_give_payment_user_email' ) {
1323
1324
			$meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1325
			give_update_meta( $this->ID, '_give_payment_user_email', $meta_value );
1326
1327
			$current_meta                       = $this->get_meta();
1328
			$current_meta['user_info']['email'] = $meta_value;
1329
1330
			$meta_key   = '_give_payment_meta';
1331
			$meta_value = $current_meta;
1332
1333
		}
1334
1335
		$meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1336
1337
		return give_update_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1338
	}
1339
1340
	/**
1341
	 * When a payment is set to a status of 'refunded' process the necessary actions to reduce stats
1342
	 *
1343
	 * @since  1.5
1344
	 * @access private
1345
	 *
1346
	 * @return void
1347
	 */
1348
	private function process_refund() {
1349
		$process_refund = true;
1350
1351
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1352
		if ( 'publish' != $this->old_status || 'refunded' != $this->status ) {
1353
			$process_refund = false;
1354
		}
1355
1356
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1357
		$process_refund = apply_filters( 'give_should_process_refund', $process_refund, $this );
1358
1359
		if ( false === $process_refund ) {
1360
			return;
1361
		}
1362
1363
		/**
1364
		 * Fires before refunding payment.
1365
		 *
1366
		 * @since 1.5
1367
		 *
1368
		 * @param Give_Payment $this Payment object.
1369
		 */
1370
		do_action( 'give_pre_refund_payment', $this );
1371
1372
		$decrease_earnings       = apply_filters( 'give_decrease_store_earnings_on_refund', true, $this );
1373
		$decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_refund', true, $this );
1374
		$decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_refund', true, $this );
1375
1376
		$this->maybe_alter_stats( $decrease_earnings, $decrease_customer_value, $decrease_purchase_count );
1377
		$this->delete_sales_logs();
1378
1379
		// @todo: Refresh only range related stat cache
1380
		give_delete_donation_stats();
1381
1382
		/**
1383
		 * Fires after refunding payment.
1384
		 *
1385
		 * @since 1.5
1386
		 *
1387
		 * @param Give_Payment $this Payment object.
1388
		 */
1389
		do_action( 'give_post_refund_payment', $this );
1390
	}
1391
1392
	/**
1393
	 * Process when a payment is set to failed
1394
	 *
1395
	 * @since  1.5
1396
	 * @access private
1397
	 *
1398
	 * @return void
1399
	 */
1400
	private function process_failure() {
1401
1402
	}
1403
1404
	/**
1405
	 * Process when a payment moves to pending
1406
	 *
1407
	 * @since  1.5
1408
	 * @access private
1409
	 *
1410
	 * @return void
1411
	 */
1412
	private function process_pending() {
1413
		$process_pending = true;
1414
1415
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1416
		if ( 'publish' != $this->old_status || 'pending' != $this->status ) {
1417
			$process_pending = false;
1418
		}
1419
1420
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1421
		$process_pending = apply_filters( 'give_should_process_pending', $process_pending, $this );
1422
1423
		if ( false === $process_pending ) {
1424
			return;
1425
		}
1426
1427
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_pending', true, $this );
1428
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_pending', true, $this );
1429
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_pending', true, $this );
1430
1431
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1432
		$this->delete_sales_logs();
1433
1434
		$this->completed_date = false;
1435
		$this->update_meta( '_give_completed_date', '' );
1436
1437
		// @todo: Refresh only range related stat cache
1438
		give_delete_donation_stats();
1439
	}
1440
1441
	/**
1442
	 * Process when a payment moves to cancelled.
1443
	 *
1444
	 * @since  1.5
1445
	 * @access private
1446
	 *
1447
	 * @return void
1448
	 */
1449
	private function process_cancelled() {
1450
		$process_cancelled = true;
1451
1452
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1453
		if ( 'publish' != $this->old_status || 'cancelled' != $this->status ) {
1454
			$process_cancelled = false;
1455
		}
1456
1457
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1458
		$process_cancelled = apply_filters( 'give_should_process_cancelled', $process_cancelled, $this );
1459
1460
		if ( false === $process_cancelled ) {
1461
			return;
1462
		}
1463
1464
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_cancelled', true, $this );
1465
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_cancelled', true, $this );
1466
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_cancelled', true, $this );
1467
1468
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1469
		$this->delete_sales_logs();
1470
1471
		$this->completed_date = false;
1472
		$this->update_meta( '_give_completed_date', '' );
1473
1474
		// @todo: Refresh only range related stat cache
1475
		give_delete_donation_stats();
1476
	}
1477
1478
	/**
1479
	 * Process when a payment moves to revoked.
1480
	 *
1481
	 * @since  1.5
1482
	 * @return void
1483
	 */
1484
	private function process_revoked() {
1485
		$process_revoked = true;
1486
1487
		// If the payment was not in publish, don't decrement stats as they were never incremented.
1488
		if ( 'publish' != $this->old_status || 'revoked' != $this->status ) {
1489
			$process_revoked = false;
1490
		}
1491
1492
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1493
		$process_revoked = apply_filters( 'give_should_process_revoked', $process_revoked, $this );
1494
1495
		if ( false === $process_revoked ) {
1496
			return;
1497
		}
1498
1499
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_revoked', true, $this );
1500
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_revoked', true, $this );
1501
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_revoked', true, $this );
1502
1503
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1504
		$this->delete_sales_logs();
1505
1506
		$this->completed_date = false;
1507
		$this->update_meta( '_give_completed_date', '' );
1508
1509
		// @todo: Refresh only range related stat cache
1510
		give_delete_donation_stats();
1511
	}
1512
1513
	/**
1514
	 * Used during the process of moving to refunded or pending, to decrement stats
1515
	 *
1516
	 * @since  1.5
1517
	 * @access private
1518
	 *
1519
	 * @param  bool $alter_store_earnings If the method should alter the store earnings
1520
	 * @param  bool $alter_customer_value If the method should reduce the donor value
1521
	 * @param  bool $alter_customer_purchase_count If the method should reduce the donor's purchase count
1522
	 *
1523
	 * @return void
1524
	 */
1525
	private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1526
1527
		give_undo_donation( $this->ID );
1528
1529
		// Decrease store earnings.
1530
		if ( true === $alter_store_earnings ) {
1531
			give_decrease_total_earnings( $this->total );
1532
		}
1533
1534
		// Decrement the stats for the donor.
1535
		if ( ! empty( $this->customer_id ) ) {
1536
1537
			$donor = new Give_Donor( $this->customer_id );
1538
1539
			if ( true === $alter_customer_value ) {
1540
				$donor->decrease_value( $this->total );
1541
			}
1542
1543
			if ( true === $alter_customer_purchase_count ) {
1544
				$donor->decrease_donation_count();
1545
			}
1546
		}
1547
1548
	}
1549
1550
	/**
1551
	 * Delete sales logs for this donation
1552
	 *
1553
	 * @since  1.5
1554
	 * @access private
1555
	 *
1556
	 * @return void
1557
	 */
1558
	private function delete_sales_logs() {
1559
		global $give_logs;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1560
1561
		// Remove related sale log entries.
1562
		$give_logs->delete_logs(
1563
			null,
1564
			'sale',
1565
			array(
1566
				array(
1567
					'key'   => '_give_log_payment_id',
1568
					'value' => $this->ID,
1569
				),
1570
			)
1571
		);
1572
	}
1573
1574
	/**
1575
	 * Setup functions only, these are not to be used by developers.
1576
	 * These functions exist only to allow the setup routine to be backwards compatible with our old
1577
	 * helper functions.
1578
	 *
1579
	 * These will run whenever setup_payment is called, which should only be called once.
1580
	 * To update an attribute, update it directly instead of re-running the setup routine
1581
	 */
1582
1583
	/**
1584
	 * Setup the payment completed date
1585
	 *
1586
	 * @since  1.5
1587
	 * @access private
1588
	 *
1589
	 * @return string The date the payment was completed
1590
	 */
1591
	private function setup_completed_date() {
1592
		$payment = get_post( $this->ID );
1593
1594
		if ( 'pending' == $payment->post_status || 'preapproved' == $payment->post_status ) {
1595
			return false; // This payment was never completed.
1596
		}
1597
1598
		$date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1599
1600
		return $date;
1601
	}
1602
1603
	/**
1604
	 * Setup the payment mode
1605
	 *
1606
	 * @since  1.5
1607
	 * @access private
1608
	 *
1609
	 * @return string The payment mode
1610
	 */
1611
	private function setup_mode() {
1612
		return $this->get_meta( '_give_payment_mode' );
1613
	}
1614
1615
	/**
1616
	 * Setup the payment total
1617
	 *
1618
	 * @since  1.5
1619
	 * @access private
1620
	 *
1621
	 * @return float The payment total
1622
	 */
1623
	private function setup_total() {
1624
		$amount = $this->get_meta( '_give_payment_total', true );
1625
1626
		if ( empty( $amount ) && '0.00' != $amount ) {
1627
			$meta = $this->get_meta( '_give_payment_meta', true );
1628
			$meta = maybe_unserialize( $meta );
1629
1630
			if ( isset( $meta['amount'] ) ) {
1631
				$amount = $meta['amount'];
1632
			}
1633
		}
1634
1635
		return round( floatval( $amount ), give_currency_decimal_filter() );
1636
	}
1637
1638
	/**
1639
	 * Setup the payment subtotal
1640
	 *
1641
	 * @since  1.5
1642
	 * @access private
1643
	 *
1644
	 * @return float The subtotal of the payment
1645
	 */
1646
	private function setup_subtotal() {
1647
		$subtotal = $this->total;
1648
1649
		return $subtotal;
1650
	}
1651
1652
	/**
1653
	 * Setup the currency code
1654
	 *
1655
	 * @since  1.5
1656
	 * @access private
1657
	 *
1658
	 * @return string The currency for the payment
1659
	 */
1660
	private function setup_currency() {
1661
		$currency = isset( $this->payment_meta['currency'] ) ? $this->payment_meta['currency'] : apply_filters( 'give_payment_currency_default', give_get_currency(), $this );
1662
1663
		return $currency;
1664
	}
1665
1666
	/**
1667
	 * Setup the gateway used for the payment
1668
	 *
1669
	 * @since  1.5
1670
	 * @access private
1671
	 *
1672
	 * @return string The gateway
1673
	 */
1674
	private function setup_gateway() {
1675
		$gateway = $this->get_meta( '_give_payment_gateway', true );
1676
1677
		return $gateway;
1678
	}
1679
1680
	/**
1681
	 * Setup the donation ID
1682
	 *
1683
	 * @since  1.5
1684
	 * @access private
1685
	 *
1686
	 * @return string The donation ID
1687
	 */
1688
	private function setup_transaction_id() {
1689
		$transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1690
1691
		if ( empty( $transaction_id ) ) {
1692
			$gateway        = $this->gateway;
1693
			$transaction_id = apply_filters( "give_get_payment_transaction_id-{$gateway}", $this->ID );
1694
		}
1695
1696
		return $transaction_id;
1697
	}
1698
1699
	/**
1700
	 * Setup the IP Address for the payment
1701
	 *
1702
	 * @since  1.5
1703
	 * @since  2.0 rename meta key
1704
	 * @access private
1705
	 *
1706
	 * @return string The IP address for the payment
1707
	 */
1708
	private function setup_ip() {
1709
		$ip = $this->get_meta( '_give_payment_donor_ip', true );
1710
1711
		return $ip;
1712
	}
1713
1714
	/**
1715
	 * Setup the donor ID.
1716
	 *
1717
	 * @since  1.5
1718
	 * @access private
1719
	 *
1720
	 * @return int The Donor ID.
1721
	 */
1722
	private function setup_donor_id() {
1723
		$donor_id = $this->get_meta( '_give_payment_donor_id', true );
1724
1725
		return $donor_id;
1726
	}
1727
1728
	/**
1729
	 * Setup the User ID associated with the donation
1730
	 *
1731
	 * @since  1.5
1732
	 * @since  2.0 Get user id connect to donor from donor table instead of payment meta.
1733
	 *
1734
	 * @access private
1735
	 *
1736
	 * @return int The User ID
1737
	 */
1738
	private function setup_user_id() {
1739
		$donor   = Give()->customers->get_customer_by( 'id', $this->customer_id );
0 ignored issues
show
Bug introduced by
The property customers does not seem to exist in Give.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1740
		$user_id = $donor ? absint( $donor->user_id ) : 0;
1741
1742
		return $user_id;
1743
	}
1744
1745
	/**
1746
	 * Setup the email address for the donation.
1747
	 *
1748
	 * @since  1.5
1749
	 * @access private
1750
	 *
1751
	 * @return string The email address for the payment.
1752
	 */
1753
	private function setup_email() {
1754
		$email = $this->get_meta( '_give_payment_donor_email', true );
1755
1756
		if ( empty( $email ) ) {
1757
			$email = Give()->donors->get_column( 'email', $this->customer_id );
1758
		}
1759
1760
		return $email;
1761
	}
1762
1763
	/**
1764
	 * Setup the user info.
1765
	 *
1766
	 * @since  1.5
1767
	 * @access private
1768
	 *
1769
	 * @return array The user info associated with the payment.
1770
	 */
1771
	private function setup_user_info() {
1772
		$defaults = array(
1773
			'first_name' => $this->first_name,
1774
			'last_name'  => $this->last_name,
1775
		);
1776
1777
		$user_info = isset( $this->payment_meta['user_info'] ) ? maybe_unserialize( $this->payment_meta['user_info'] ) : array();
1778
		$user_info = wp_parse_args( $user_info, $defaults );
1779
1780
		if ( empty( $user_info ) ) {
1781
			// Get the donor, but only if it's been created.
1782
			$donor = new Give_Donor( $this->customer_id );
1783
1784
			if ( $donor->id > 0 ) {
1785
				$name      = explode( ' ', $donor->name, 2 );
1786
				$user_info = array(
1787
					'first_name' => $name[0],
1788
					'last_name'  => $name[1],
1789
					'email'      => $donor->email,
1790
					'discount'   => 'none',
1791
				);
1792
			}
1793
		} else {
1794
			// Get the donor, but only if it's been created.
1795
			$donor = new Give_Donor( $this->customer_id );
1796
			if ( $donor->id > 0 ) {
1797
				foreach ( $user_info as $key => $value ) {
1798
					if ( ! empty( $value ) ) {
1799
						continue;
1800
					}
1801
1802
					switch ( $key ) {
1803
						case 'first_name':
1804
							$name = explode( ' ', $donor->name, 2 );
1805
1806
							$user_info[ $key ] = $name[0];
1807
							break;
1808
1809
						case 'last_name':
1810
							$name      = explode( ' ', $donor->name, 2 );
1811
							$last_name = ! empty( $name[1] ) ? $name[1] : '';
1812
1813
							$user_info[ $key ] = $last_name;
1814
							break;
1815
1816
						case 'email':
1817
							$user_info[ $key ] = $donor->email;
1818
							break;
1819
					}
1820
				}
1821
			}
1822
		}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

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