Completed
Push — issues/1132 ( 362bb5...578281 )
by Ravinder
16:46
created

Give_Payment::get_meta()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 19
rs 9.4285
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 array      $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
		/**
1273
		 * Filter the specific meta key value.
1274
		 *
1275
		 * @since 1.5
1276
		 */
1277
		$meta = apply_filters( "give_get_payment_meta_{$meta_key}", $meta, $this->ID );
1278
1279
1280
		/**
1281
		 * Filter the all meta keys.
1282
		 *
1283
		 * @since 1.5
1284
		 */
1285
		return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1286
	}
1287
1288
	/**
1289
	 * Update the post meta
1290
	 *
1291
	 * @since  1.5
1292
	 * @access public
1293
	 *
1294
	 * @param  string $meta_key The meta key to update
1295
	 * @param  string $meta_value The meta value
1296
	 * @param  string $prev_value Previous meta value
1297
	 *
1298
	 * @return int|bool           Meta ID if the key didn't exist, true on successful update, false on failure
1299
	 */
1300
	public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1301
		if ( empty( $meta_key ) ) {
1302
			return false;
1303
		}
1304
1305
		if ( $meta_key == 'key' || $meta_key == 'date' ) {
1306
1307
			$current_meta              = $this->get_meta();
1308
			$current_meta[ $meta_key ] = $meta_value;
1309
1310
			$meta_key   = '_give_payment_meta';
1311
			$meta_value = $current_meta;
1312
1313
		} elseif ( $meta_key == 'email' || $meta_key == '_give_payment_user_email' ) {
1314
1315
			$meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1316
			give_update_meta( $this->ID, '_give_payment_user_email', $meta_value );
1317
1318
			$current_meta                       = $this->get_meta();
1319
			$current_meta['user_info']['email'] = $meta_value;
1320
1321
			$meta_key   = '_give_payment_meta';
1322
			$meta_value = $current_meta;
1323
1324
		}
1325
1326
		$meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1327
1328
		return give_update_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1329
	}
1330
1331
	/**
1332
	 * When a payment is set to a status of 'refunded' process the necessary actions to reduce stats
1333
	 *
1334
	 * @since  1.5
1335
	 * @access private
1336
	 *
1337
	 * @return void
1338
	 */
1339
	private function process_refund() {
1340
		$process_refund = true;
1341
1342
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1343
		if ( 'publish' != $this->old_status || 'refunded' != $this->status ) {
1344
			$process_refund = false;
1345
		}
1346
1347
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1348
		$process_refund = apply_filters( 'give_should_process_refund', $process_refund, $this );
1349
1350
		if ( false === $process_refund ) {
1351
			return;
1352
		}
1353
1354
		/**
1355
		 * Fires before refunding payment.
1356
		 *
1357
		 * @since 1.5
1358
		 *
1359
		 * @param Give_Payment $this Payment object.
1360
		 */
1361
		do_action( 'give_pre_refund_payment', $this );
1362
1363
		$decrease_earnings       = apply_filters( 'give_decrease_store_earnings_on_refund', true, $this );
1364
		$decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_refund', true, $this );
1365
		$decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_refund', true, $this );
1366
1367
		$this->maybe_alter_stats( $decrease_earnings, $decrease_customer_value, $decrease_purchase_count );
1368
		$this->delete_sales_logs();
1369
1370
		// @todo: Refresh only range related stat cache
1371
		give_delete_donation_stats();
1372
1373
		/**
1374
		 * Fires after refunding payment.
1375
		 *
1376
		 * @since 1.5
1377
		 *
1378
		 * @param Give_Payment $this Payment object.
1379
		 */
1380
		do_action( 'give_post_refund_payment', $this );
1381
	}
1382
1383
	/**
1384
	 * Process when a payment is set to failed
1385
	 *
1386
	 * @since  1.5
1387
	 * @access private
1388
	 *
1389
	 * @return void
1390
	 */
1391
	private function process_failure() {
1392
1393
	}
1394
1395
	/**
1396
	 * Process when a payment moves to pending
1397
	 *
1398
	 * @since  1.5
1399
	 * @access private
1400
	 *
1401
	 * @return void
1402
	 */
1403
	private function process_pending() {
1404
		$process_pending = true;
1405
1406
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1407
		if ( 'publish' != $this->old_status || 'pending' != $this->status ) {
1408
			$process_pending = false;
1409
		}
1410
1411
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1412
		$process_pending = apply_filters( 'give_should_process_pending', $process_pending, $this );
1413
1414
		if ( false === $process_pending ) {
1415
			return;
1416
		}
1417
1418
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_pending', true, $this );
1419
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_pending', true, $this );
1420
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_pending', true, $this );
1421
1422
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1423
		$this->delete_sales_logs();
1424
1425
		$this->completed_date = false;
1426
		$this->update_meta( '_give_completed_date', '' );
1427
1428
		// @todo: Refresh only range related stat cache
1429
		give_delete_donation_stats();
1430
	}
1431
1432
	/**
1433
	 * Process when a payment moves to cancelled.
1434
	 *
1435
	 * @since  1.5
1436
	 * @access private
1437
	 *
1438
	 * @return void
1439
	 */
1440
	private function process_cancelled() {
1441
		$process_cancelled = true;
1442
1443
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented.
1444
		if ( 'publish' != $this->old_status || 'cancelled' != $this->status ) {
1445
			$process_cancelled = false;
1446
		}
1447
1448
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1449
		$process_cancelled = apply_filters( 'give_should_process_cancelled', $process_cancelled, $this );
1450
1451
		if ( false === $process_cancelled ) {
1452
			return;
1453
		}
1454
1455
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_cancelled', true, $this );
1456
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_cancelled', true, $this );
1457
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_cancelled', true, $this );
1458
1459
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1460
		$this->delete_sales_logs();
1461
1462
		$this->completed_date = false;
1463
		$this->update_meta( '_give_completed_date', '' );
1464
1465
		// @todo: Refresh only range related stat cache
1466
		give_delete_donation_stats();
1467
	}
1468
1469
	/**
1470
	 * Process when a payment moves to revoked.
1471
	 *
1472
	 * @since  1.5
1473
	 * @return void
1474
	 */
1475
	private function process_revoked() {
1476
		$process_revoked = true;
1477
1478
		// If the payment was not in publish, don't decrement stats as they were never incremented.
1479
		if ( 'publish' != $this->old_status || 'revoked' != $this->status ) {
1480
			$process_revoked = false;
1481
		}
1482
1483
		// Allow extensions to filter for their own payment types, Example: Recurring Payments.
1484
		$process_revoked = apply_filters( 'give_should_process_revoked', $process_revoked, $this );
1485
1486
		if ( false === $process_revoked ) {
1487
			return;
1488
		}
1489
1490
		$decrease_earnings       = apply_filters( 'give_decrease_earnings_on_revoked', true, $this );
1491
		$decrease_donor_value    = apply_filters( 'give_decrease_donor_value_on_revoked', true, $this );
1492
		$decrease_donation_count = apply_filters( 'give_decrease_donors_donation_count_on_revoked', true, $this );
1493
1494
		$this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1495
		$this->delete_sales_logs();
1496
1497
		$this->completed_date = false;
1498
		$this->update_meta( '_give_completed_date', '' );
1499
1500
		// @todo: Refresh only range related stat cache
1501
		give_delete_donation_stats();
1502
	}
1503
1504
	/**
1505
	 * Used during the process of moving to refunded or pending, to decrement stats
1506
	 *
1507
	 * @since  1.5
1508
	 * @access private
1509
	 *
1510
	 * @param  bool $alter_store_earnings If the method should alter the store earnings
1511
	 * @param  bool $alter_customer_value If the method should reduce the donor value
1512
	 * @param  bool $alter_customer_purchase_count If the method should reduce the donor's purchase count
1513
	 *
1514
	 * @return void
1515
	 */
1516
	private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1517
1518
		give_undo_donation( $this->ID );
1519
1520
		// Decrease store earnings.
1521
		if ( true === $alter_store_earnings ) {
1522
			give_decrease_total_earnings( $this->total );
1523
		}
1524
1525
		// Decrement the stats for the donor.
1526
		if ( ! empty( $this->customer_id ) ) {
1527
1528
			$donor = new Give_Donor( $this->customer_id );
1529
1530
			if ( true === $alter_customer_value ) {
1531
				$donor->decrease_value( $this->total );
1532
			}
1533
1534
			if ( true === $alter_customer_purchase_count ) {
1535
				$donor->decrease_donation_count();
1536
			}
1537
		}
1538
1539
	}
1540
1541
	/**
1542
	 * Delete sales logs for this donation
1543
	 *
1544
	 * @since  1.5
1545
	 * @access private
1546
	 *
1547
	 * @return void
1548
	 */
1549
	private function delete_sales_logs() {
1550
		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...
1551
1552
		// Remove related sale log entries.
1553
		$give_logs->delete_logs(
1554
			null,
1555
			'sale',
1556
			array(
1557
				array(
1558
					'key'   => '_give_log_payment_id',
1559
					'value' => $this->ID,
1560
				),
1561
			)
1562
		);
1563
	}
1564
1565
	/**
1566
	 * Setup functions only, these are not to be used by developers.
1567
	 * These functions exist only to allow the setup routine to be backwards compatible with our old
1568
	 * helper functions.
1569
	 *
1570
	 * These will run whenever setup_payment is called, which should only be called once.
1571
	 * To update an attribute, update it directly instead of re-running the setup routine
1572
	 */
1573
1574
	/**
1575
	 * Setup the payment completed date
1576
	 *
1577
	 * @since  1.5
1578
	 * @access private
1579
	 *
1580
	 * @return string The date the payment was completed
1581
	 */
1582
	private function setup_completed_date() {
1583
		$payment = get_post( $this->ID );
1584
1585
		if ( 'pending' == $payment->post_status || 'preapproved' == $payment->post_status ) {
1586
			return false; // This payment was never completed.
1587
		}
1588
1589
		$date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1590
1591
		return $date;
1592
	}
1593
1594
	/**
1595
	 * Setup the payment mode
1596
	 *
1597
	 * @since  1.5
1598
	 * @access private
1599
	 *
1600
	 * @return string The payment mode
1601
	 */
1602
	private function setup_mode() {
1603
		return $this->get_meta( '_give_payment_mode' );
1604
	}
1605
1606
	/**
1607
	 * Setup the payment total
1608
	 *
1609
	 * @since  1.5
1610
	 * @access private
1611
	 *
1612
	 * @return float The payment total
1613
	 */
1614
	private function setup_total() {
1615
		$amount = $this->get_meta( '_give_payment_total', true );
1616
1617
		if ( empty( $amount ) && '0.00' != $amount ) {
1618
			$meta = $this->get_meta( '_give_payment_meta', true );
1619
			$meta = maybe_unserialize( $meta );
1620
1621
			if ( isset( $meta['amount'] ) ) {
1622
				$amount = $meta['amount'];
1623
			}
1624
		}
1625
1626
		return round( floatval( $amount ), give_currency_decimal_filter() );
1627
	}
1628
1629
	/**
1630
	 * Setup the payment subtotal
1631
	 *
1632
	 * @since  1.5
1633
	 * @access private
1634
	 *
1635
	 * @return float The subtotal of the payment
1636
	 */
1637
	private function setup_subtotal() {
1638
		$subtotal = $this->total;
1639
1640
		return $subtotal;
1641
	}
1642
1643
	/**
1644
	 * Setup the currency code
1645
	 *
1646
	 * @since  1.5
1647
	 * @since  2.0 Set currency from _give_payment_currency meta key
1648
	 * @access private
1649
	 *
1650
	 * @return string The currency for the payment
1651
	 */
1652
	private function setup_currency() {
1653
		$currency = $this->get_meta( '_give_payment_currency', true );
1654
		$currency = ! empty( $currency ) ?
1655
			$currency :
1656
			apply_filters( 'give_payment_currency_default', give_get_currency(), $this );
1657
1658
		return $currency;
1659
	}
1660
1661
	/**
1662
	 * Setup the gateway used for the payment
1663
	 *
1664
	 * @since  1.5
1665
	 * @access private
1666
	 *
1667
	 * @return string The gateway
1668
	 */
1669
	private function setup_gateway() {
1670
		$gateway = $this->get_meta( '_give_payment_gateway', true );
1671
1672
		return $gateway;
1673
	}
1674
1675
	/**
1676
	 * Setup the donation ID
1677
	 *
1678
	 * @since  1.5
1679
	 * @access private
1680
	 *
1681
	 * @return string The donation ID
1682
	 */
1683
	private function setup_transaction_id() {
1684
		$transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1685
1686
		if ( empty( $transaction_id ) ) {
1687
			$gateway        = $this->gateway;
1688
			$transaction_id = apply_filters( "give_get_payment_transaction_id-{$gateway}", $this->ID );
1689
		}
1690
1691
		return $transaction_id;
1692
	}
1693
1694
	/**
1695
	 * Setup the IP Address for the payment
1696
	 *
1697
	 * @since  1.5
1698
	 * @since  2.0 Set ip address from _give_payment_donor_ip meta key
1699
	 * @access private
1700
	 *
1701
	 * @return string The IP address for the payment
1702
	 */
1703
	private function setup_ip() {
1704
		$ip = $this->get_meta( '_give_payment_donor_ip', true );
1705
1706
		return $ip;
1707
	}
1708
1709
	/**
1710
	 * Setup the donor ID.
1711
	 *
1712
	 * @since  1.5
1713
	 * @since  2.0 Set id from _give_payment_donor_id meta key
1714
	 * @access private
1715
	 *
1716
	 * @return int The Donor ID.
1717
	 */
1718
	private function setup_donor_id() {
1719
		$donor_id = $this->get_meta( '_give_payment_donor_id', true );
1720
1721
		return $donor_id;
1722
	}
1723
1724
	/**
1725
	 * Setup the User ID associated with the donation
1726
	 *
1727
	 * @since  1.5
1728
	 * @since  2.0 Get user id connect to donor from donor table instead of payment meta.
1729
	 *
1730
	 * @access private
1731
	 *
1732
	 * @return int The User ID
1733
	 */
1734
	private function setup_user_id() {
1735
		if ( ! ( $user_id = Give_Cache::payment( $this->ID, 'user_id' ) ) ) {
1736
			$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...
1737
			$user_id = $donor ? absint( $donor->user_id ) : 0;
1738
1739
			Give_Cache::payment( $this->ID, 'user_id', $user_id );
1740
		}
1741
1742
		return $user_id;
1743
	}
1744
1745
	/**
1746
	 * Setup the email address for the donation.
1747
	 *
1748
	 * @since  1.5
1749
	 * @since  2.0 Set email from _give_payment_donor_email meta key
1750
	 *
1751
	 * @access private
1752
	 *
1753
	 * @return string The email address for the payment.
1754
	 */
1755
	private function setup_email() {
1756
		$email = $this->get_meta( '_give_payment_donor_email', true );
1757
1758
		if ( empty( $email ) ) {
1759
			$email = Give()->donors->get_column( 'email', $this->customer_id );
1760
		}
1761
1762
		return $email;
1763
	}
1764
1765
	/**
1766
	 * Setup the user info.
1767
	 *
1768
	 * @since  1.5
1769
	 * @access private
1770
	 *
1771
	 * @return array The user info associated with the payment.
1772
	 */
1773
	private function setup_user_info() {
1774
		$defaults = array(
1775
			'first_name' => $this->first_name,
1776
			'last_name'  => $this->last_name,
1777
		);
1778
1779
		$user_info = isset( $this->payment_meta['user_info'] ) ? maybe_unserialize( $this->payment_meta['user_info'] ) : array();
1780
		$user_info = wp_parse_args( $user_info, $defaults );
1781
1782
		if ( empty( $user_info ) ) {
1783
			// Get the donor, but only if it's been created.
1784
			$donor = new Give_Donor( $this->customer_id );
1785
1786
			if ( $donor->id > 0 ) {
1787
				$name      = explode( ' ', $donor->name, 2 );
1788
				$user_info = array(
1789
					'first_name' => $name[0],
1790
					'last_name'  => $name[1],
1791
					'email'      => $donor->email,
1792
					'discount'   => 'none',
1793
				);
1794
			}
1795
		} else {
1796
			// Get the donor, but only if it's been created.
1797
			$donor = new Give_Donor( $this->customer_id );
1798
			if ( $donor->id > 0 ) {
1799
				foreach ( $user_info as $key => $value ) {
1800
					if ( ! empty( $value ) ) {
1801
						continue;
1802
					}
1803
1804
					switch ( $key ) {
1805
						case 'first_name':
1806
							$name = explode( ' ', $donor->name, 2 );
1807
1808
							$user_info[ $key ] = $name[0];
1809
							break;
1810
1811
						case 'last_name':
1812
							$name      = explode( ' ', $donor->name, 2 );
1813
							$last_name = ! empty( $name[1] ) ? $name[1] : '';
1814
1815
							$user_info[ $key ] = $last_name;
1816
							break;
1817
1818
						case 'email':
1819
							$user_info[ $key ] = $donor->email;
1820
							break;
1821
					}
1822
				}
1823
			}
1824
		}// 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...
1825
1826
		return $user_info;
1827
1828
	}
1829
1830
	/**
1831
	 * Setup the Address for the payment.
1832
	 *
1833
	 * @since  1.5
1834
	 * @access private
1835
	 *
1836
	 * @return array The Address information for the payment.
1837
	 */
1838
	private function setup_address() {
1839
		// Get address from cache.
1840
		if ( ! ( $address = Give_Cache::payment( $this->ID, 'address' ) ) ) {
1841
			$address['line1']   = give_get_meta( $this->ID, '_give_donor_billing_address1', true );
1842
			$address['line2']   = give_get_meta( $this->ID, '_give_donor_billing_address2', true );
1843
			$address['city']    = give_get_meta( $this->ID, '_give_donor_billing_city', true );
1844
			$address['state']   = give_get_meta( $this->ID, '_give_donor_billing_state', true );
1845
			$address['zip']     = give_get_meta( $this->ID, '_give_donor_billing_zip', true );
1846
			$address['country'] = give_get_meta( $this->ID, '_give_donor_billing_country', true );
1847
1848
			// Save address to cache.
1849
			Give_Cache::payment( $this->ID, 'address', $address );
1850
		}
1851
1852
		$address = wp_parse_args(
1853
			$address,
1854
			array(
1855
				'line1'   => '',
1856
				'line2'   => '',
1857
				'city'    => '',
1858
				'country' => '',
1859
				'state'   => '',
1860
				'zip'     => '',
1861
			)
1862
		);
1863
1864
		return $address;
1865
	}
1866
1867
	/**
1868
	 * Setup the form title.
1869
	 *
1870
	 * @since  1.5
1871
	 * @access private
1872
	 *
1873
	 * @return string The Form Title.
1874
	 */
1875
	private function setup_form_title() {
1876
1877
		$form_id = $this->get_meta( '_give_payment_form_title', true );
1878
1879
		return $form_id;
1880
	}
1881
1882
	/**
1883
	 * Setup the form ID.
1884
	 *
1885
	 * @since  1.5
1886
	 * @access private
1887
	 *
1888
	 * @return int The Form ID
1889
	 */
1890
	private function setup_form_id() {
1891
1892
		$form_id = $this->get_meta( '_give_payment_form_id', true );
1893
1894
		return $form_id;
1895
	}
1896
1897
	/**
1898
	 * Setup the price ID.
1899
	 *
1900
	 * @since  1.5
1901
	 * @access private
1902
	 *
1903
	 * @return int The Form Price ID.
1904
	 */
1905
	private function setup_price_id() {
1906
		$price_id = $this->get_meta( '_give_payment_price_id', true );
1907
1908
		return $price_id;
1909
	}
1910
1911
	/**
1912
	 * Setup the payment key.
1913
	 *
1914
	 * @since  1.5
1915
	 * @access private
1916
	 *
1917
	 * @return string The Payment Key.
1918
	 */
1919
	private function setup_payment_key() {
1920
		$key = $this->get_meta( '_give_payment_purchase_key', true );
1921
1922
		return $key;
1923
	}
1924
1925
	/**
1926
	 * Setup the payment number.
1927
	 *
1928
	 * @since  1.5
1929
	 * @access private
1930
	 *
1931
	 * @return int|string Integer by default, or string if sequential order numbers is enabled.
1932
	 */
1933
	private function setup_payment_number() {
1934
		$number = $this->ID;
1935
1936
		if ( give_get_option( 'enable_sequential' ) ) {
1937
1938
			$number = $this->get_meta( '_give_payment_number', true );
1939
1940
			if ( ! $number ) {
1941
1942
				$number = $this->ID;
1943
1944
			}
1945
		}
1946
1947
		return $number;
1948
	}
1949
1950
	/**
1951
	 * Converts this object into an array for special cases.
1952
	 *
1953
	 * @access public
1954
	 *
1955
	 * @return array The payment object as an array.
1956
	 */
1957
	public function array_convert() {
1958
		return get_object_vars( $this );
1959
	}
1960
1961
1962
	/**
1963
	 * Flag to check if donation is completed or not.
1964
	 *
1965
	 * @since  1.8
1966
	 * @access public
1967
	 *
1968
	 * @return bool
1969
	 */
1970
	public function is_completed() {
1971
		return ( 'publish' === $this->status && $this->completed_date );
1972
	}
1973
1974
	/**
1975
	 * Retrieve payment completion date.
1976
	 *
1977
	 * @since  1.5
1978
	 * @access private
1979
	 *
1980
	 * @return string Date payment was completed.
1981
	 */
1982
	private function get_completed_date() {
1983
		return apply_filters( 'give_payment_completed_date', $this->completed_date, $this->ID, $this );
1984
	}
1985
1986
	/**
1987
	 * Retrieve payment subtotal.
1988
	 *
1989
	 * @since  1.5
1990
	 * @access private
1991
	 *
1992
	 * @return float Payment subtotal.
1993
	 */
1994
	private function get_subtotal() {
1995
		return apply_filters( 'give_get_payment_subtotal', $this->subtotal, $this->ID, $this );
1996
	}
1997
1998
	/**
1999
	 * Retrieve payment currency.
2000
	 *
2001
	 * @since  1.5
2002
	 * @access private
2003
	 *
2004
	 * @return string Payment currency code.
2005
	 */
2006
	private function get_currency() {
2007
		return apply_filters( 'give_payment_currency_code', $this->currency, $this->ID, $this );
2008
	}
2009
2010
	/**
2011
	 * Retrieve payment gateway.
2012
	 *
2013
	 * @since  1.5
2014
	 * @access private
2015
	 *
2016
	 * @return string Gateway used.
2017
	 */
2018
	private function get_gateway() {
2019
		return apply_filters( 'give_payment_gateway', $this->gateway, $this->ID, $this );
2020
	}
2021
2022
	/**
2023
	 * Retrieve donation ID.
2024
	 *
2025
	 * @since  1.5
2026
	 * @access private
2027
	 *
2028
	 * @return string Donation ID from merchant processor.
2029
	 */
2030
	private function get_transaction_id() {
2031
		return apply_filters( 'give_get_payment_transaction_id', $this->transaction_id, $this->ID, $this );
2032
	}
2033
2034
	/**
2035
	 * Retrieve payment IP
2036
	 *
2037
	 * @since  1.5
2038
	 * @access private
2039
	 *
2040
	 * @return string Payment IP address
2041
	 */
2042
	private function get_ip() {
2043
		return apply_filters( 'give_payment_user_ip', $this->ip, $this->ID, $this );
2044
	}
2045
2046
	/**
2047
	 * Retrieve payment donor ID.
2048
	 *
2049
	 * @since  1.5
2050
	 * @access private
2051
	 *
2052
	 * @return int Payment donor ID.
2053
	 */
2054
	private function get_donor_id() {
2055
		return apply_filters( 'give_payment_customer_id', $this->customer_id, $this->ID, $this );
2056
	}
2057
2058
	/**
2059
	 * Retrieve payment user ID.
2060
	 *
2061
	 * @since  1.5
2062
	 * @access private
2063
	 *
2064
	 * @return int Payment user ID.
2065
	 */
2066
	private function get_user_id() {
2067
		return apply_filters( 'give_payment_user_id', $this->user_id, $this->ID, $this );
2068
	}
2069
2070
	/**
2071
	 * Retrieve payment email.
2072
	 *
2073
	 * @since  1.5
2074
	 * @access private
2075
	 *
2076
	 * @return string Payment donor email.
2077
	 */
2078
	private function get_email() {
2079
		return apply_filters( 'give_payment_user_email', $this->email, $this->ID, $this );
2080
	}
2081
2082
	/**
2083
	 * Retrieve payment user info.
2084
	 *
2085
	 * @since  1.5
2086
	 * @access private
2087
	 *
2088
	 * @return array Payment user info.
2089
	 */
2090
	private function get_user_info() {
2091
		return apply_filters( 'give_payment_meta_user_info', $this->user_info, $this->ID, $this );
2092
	}
2093
2094
	/**
2095
	 * Retrieve payment billing address.
2096
	 *
2097
	 * @since  1.5
2098
	 * @access private
2099
	 *
2100
	 * @return array Payment billing address.
2101
	 */
2102
	private function get_address() {
2103
		return apply_filters( 'give_payment_address', $this->address, $this->ID, $this );
2104
	}
2105
2106
	/**
2107
	 * Retrieve payment key.
2108
	 *
2109
	 * @since  1.5
2110
	 * @access private
2111
	 *
2112
	 * @return string Payment key.
2113
	 */
2114
	private function get_key() {
2115
		return apply_filters( 'give_payment_key', $this->key, $this->ID, $this );
2116
	}
2117
2118
	/**
2119
	 * Retrieve payment form id
2120
	 *
2121
	 * @since  1.5
2122
	 * @access private
2123
	 *
2124
	 * @return string Payment form id
2125
	 */
2126
	private function get_form_id() {
2127
		return apply_filters( 'give_payment_form_id', $this->form_id, $this->ID, $this );
2128
	}
2129
2130
	/**
2131
	 * Retrieve payment number
2132
	 *
2133
	 * @since  1.5
2134
	 * @access private
2135
	 *
2136
	 * @return int|string Payment number
2137
	 */
2138
	private function get_number() {
2139
		return apply_filters( 'give_payment_number', $this->number, $this->ID, $this );
2140
	}
2141
}
2142