Completed
Pull Request — master (#859)
by Devin
19:40
created

Give_Payment::get_transaction_id()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
ccs 0
cts 0
cp 0
crap 2
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 24 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     http://opensource.org/licenses/gpl-2.0.php 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
 * @since 1.5
23
 */
24
final class Give_Payment {
25
26
	/**
27
	 * The Payment ID
28
	 *
29
	 * @since  1.5
30
	 *
31
	 * @var    integer
32
	 */
33
	public $ID = 0;
34
	protected $_ID = 0;
35
36
	/**
37
	 * Identify if the payment is a new one or existing
38
	 *
39
	 * @since  1.5
40
	 * @access protected
41
	 *
42
	 * @var    boolean
43
	 */
44
	protected $new = false;
45
46
	/**
47
	 * The Payment number (for use with sequential payments)
48
	 *
49
	 * @since  1.5
50
	 * @access protected
51
	 *
52
	 * @var    string
53
	 */
54
	protected $number = '';
55
56
	/**
57
	 * The Gateway mode the payment was made in
58
	 *
59
	 * @since  1.5
60
	 * @access protected
61
	 *
62
	 * @var    string
63
	 */
64
	protected $mode = 'live';
65
66
	/**
67
	 * The Unique Payment Key
68
	 *
69
	 * @since  1.5
70
	 * @access protected
71
	 *
72
	 * @var    string
73
	 */
74
	protected $key = '';
75
76
	/**
77
	 * The Donation Form Title
78
	 *
79
	 * @since  1.5
80
	 * @access protected
81
	 *
82
	 * @var    string
83
	 */
84
	protected $form_title = 0;
85
86
	/**
87
	 * The Donation Form ID
88
	 *
89
	 * @since  1.5
90
	 * @access protected
91
	 *
92
	 * @var    string
93
	 */
94
	protected $form_id = 0;
95
96
	/**
97
	 * The Donation Form Price ID
98
	 *
99
	 * @since  1.5
100
	 * @access protected
101
	 *
102
	 * @var    string
103
	 */
104
	protected $price_id = 0;
105
106
	/**
107
	 * The total amount the payment is for
108
	 * Includes donation amount and fees
109
	 *
110
	 * @since  1.5
111
	 * @access protected
112
	 *
113
	 * @var    float
114
	 */
115
	protected $total = 0.00;
116
117
	/**
118
	 * The Subtotal fo the payment before fees
119
	 *
120
	 * @since  1.5
121
	 * @access protected
122
	 *
123
	 * @var    float
124
	 */
125
	protected $subtotal = 0;
126
127
	/**
128
	 * Array of global fees for this payment
129
	 *
130
	 * @since  1.5
131
	 * @access protected
132
	 *
133
	 * @var    array
134
	 */
135
	protected $fees = array();
136
137
	/**
138
	 * The sum of the fee amounts
139
	 *
140
	 * @since  1.5
141
	 * @access protected
142
	 *
143
	 * @var    float
144
	 */
145
	protected $fees_total = 0;
146
147
	/**
148
	 * The date the payment was created
149
	 *
150
	 * @since  1.5
151
	 * @access protected
152
	 *
153
	 * @var    string
154
	 */
155
	protected $date = '';
156
	protected $post_date = '';
157
158
	/**
159
	 * The date the payment was marked as 'complete'
160
	 *
161
	 * @since  1.5
162
	 * @access protected
163
	 *
164
	 * @var    string
165
	 */
166
	protected $completed_date = '';
167
168
	/**
169
	 * The status of the payment
170
	 *
171
	 * @since  1.5
172
	 * @access protected
173
	 *
174
	 * @var    string
175
	 */
176
	protected $status = 'pending';
177
	protected $post_status = 'pending'; // Same as $status but here for backwards compat
178
179
	/**
180
	 * When updating, the old status prior to the change
181
	 *
182
	 * @since  1.5
183
	 * @access protected
184
	 *
185
	 * @var    string
186
	 */
187
	protected $old_status = '';
188
189
	/**
190
	 * The display name of the current payment status
191
	 *
192
	 * @since  1.5
193
	 * @access protected
194
	 *
195
	 * @var    string
196
	 */
197
	protected $status_nicename = '';
198
199
	/**
200
	 * The customer ID that made the payment
201
	 *
202
	 * @since  1.5
203
	 * @access protected
204
	 *
205
	 * @var    integer
206
	 */
207
	protected $customer_id = null;
208
209
	/**
210
	 * The User ID (if logged in) that made the payment
211
	 *
212
	 * @since  1.5
213
	 * @access protected
214
	 *
215
	 * @var    integer
216
	 */
217
	protected $user_id = 0;
218
219
	/**
220
	 * The first name of the payee
221
	 *
222
	 * @since  1.5
223
	 * @access protected
224
	 *
225
	 * @var    string
226
	 */
227
	protected $first_name = '';
228
229
	/**
230
	 * The last name of the payee
231
	 *
232
	 * @since  1.5
233
	 * @access protected
234
	 *
235
	 * @var    string
236
	 */
237
	protected $last_name = '';
238
239
	/**
240
	 * The email used for the payment
241
	 *
242
	 * @since  1.5
243
	 * @access protected
244
	 *
245
	 * @var    string
246
	 */
247
	protected $email = '';
248
249
	/**
250
	 * Legacy (not to be accessed) array of user information
251
	 *
252
	 * @since  1.5
253
	 * @access private
254
	 *
255
	 * @var    array
256
	 */
257
	private $user_info = array();
258
259
	/**
260
	 * Legacy (not to be accessed) payment meta array
261
	 *
262
	 * @since  1.5
263
	 * @access private
264
	 *
265
	 * @var    array
266
	 */
267
	private $payment_meta = array();
268
269
	/**
270
	 * The physical address used for the payment if provided
271
	 *
272
	 * @since  1.5
273
	 * @access protected
274
	 *
275
	 * @var    array
276
	 */
277
	protected $address = array();
278
279
	/**
280
	 * The transaction ID returned by the gateway
281
	 *
282
	 * @since  1.5
283
	 * @access protected
284
	 *
285
	 * @var    string
286
	 */
287
	protected $transaction_id = '';
288
289
	/**
290
	 * IP Address payment was made from
291
	 *
292
	 * @since  1.5
293
	 * @access protected
294
	 *
295
	 * @var    string
296
	 */
297
	protected $ip = '';
298 52
299
	/**
300 52
	 * The gateway used to process the payment
301 52
	 *
302
	 * @since  1.5
303
	 * @access protected
304 52
	 *
305 52
	 * @var    string
306
	 */
307
	protected $gateway = '';
308
309
	/**
310
	 * The the payment was made with
311
	 *
312
	 * @since  1.5
313
	 * @access protected
314
	 *
315
	 * @var    string
316 52
	 */
317
	protected $currency = '';
318 52
319
	/**
320 52
	 * Array of items that have changed since the last save() was run
321
	 * This is for internal use, to allow fewer update_payment_meta calls to be run
322 52
	 *
323
	 * @since  1.5
324 52
	 * @access private
325
	 *
326
	 * @var    array
327
	 */
328 52
	private $pending;
329
330
	/**
331
	 * The parent payment (if applicable)
332
	 *
333
	 * @since  1.5
334
	 * @access protected
335
	 *
336
	 * @var    integer
337
	 */
338
	protected $parent_payment = 0;
339
340
	/**
341 52
	 * Setup the Give Payments class
342 52
	 *
343
	 * @since  1.0
344 52
	 * @access public
345 52
	 *
346 52
	 * @param  int   $payment_id A given payment
347
	 *
348 52
	 * @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...
349 52
	 */
350 52
	public function __construct( $payment_id = false ) {
351
352 52
		if ( empty( $payment_id ) ) {
353 52
			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...
354 52
		}
355 52
356
		$this->setup_payment( $payment_id );
357
	}
358
359
	/**
360
	 * Magic GET function
361
	 *
362
	 * @since  1.5
363
	 * @access public
364
	 *
365
	 * @param  string $key The property
366 42
	 *
367 42
	 * @return mixed        The value
368 42
	 */
369
	public function __get( $key ) {
370
371
		if ( method_exists( $this, 'get_' . $key ) ) {
372
373
			$value = call_user_func( array( $this, 'get_' . $key ) );
374
375
		} else {
376
377
			$value = $this->$key;
378
379
		}
380
381
		return $value;
382
	}
383 52
384 52
	/**
385
	 * Magic SET function
386 52
	 *
387
	 * Sets up the pending array for the save method
388
	 *
389
	 * @since  1.5
390 52
	 * @access public
391
	 *
392 52
	 * @param  string $key The property name
393 7
	 * @param  mixed $value The value of the property
394
	 */
395
	public function __set( $key, $value ) {
396 52
		$ignore = array( '_ID' );
397
398
		if ( $key === 'status' ) {
399
			$this->old_status = $this->status;
400
		}
401 52
402
		if ( ! in_array( $key, $ignore ) ) {
403
			$this->pending[ $key ] = $value;
404 52
		}
405
406
		if ( '_ID' !== $key ) {
407 52
			$this->$key = $value;
408
		}
409
	}
410 52
411
	/**
412
	 * Magic ISSET function, which allows empty checks on protected elements
413 52
	 *
414 52
	 * @since  1.5
415 52
	 * @access public
416 52
	 *
417 52
	 * @param  string $name The attribute to get
418 52
	 *
419 52
	 * @return boolean       If the item is set or not
420
	 */
421 52
	public function __isset( $name ) {
422 52
		if ( property_exists( $this, $name ) ) {
423
			return false === empty( $this->$name );
424
		} else {
425 52
			return null;
426
		}
427
	}
428 52
429 52
	/**
430 52
	 * Setup payment properties
431 52
	 *
432
	 * @since  1.5
433
	 * @access private
434 52
	 *
435 52
	 * @param  int $payment_id The payment ID
436
	 *
437
	 * @return bool            If the setup was successful or not
438 52
	 */
439 52
	private function setup_payment( $payment_id ) {
440 52
		$this->pending = array();
441 52
442 52
		if ( empty( $payment_id ) ) {
443 52
			return false;
444 52
		}
445 52
446
		$payment = get_post( $payment_id );
447
448 52
		if ( ! $payment || is_wp_error( $payment ) ) {
449 52
			return false;
450 52
		}
451 52
452 52
		if ( 'give_payment' !== $payment->post_type ) {
453
			return false;
454
		}
455 52
456
		// Allow extensions to perform actions before the payment is loaded
457 52
		do_action( 'give_pre_setup_payment', $this, $payment_id );
458
459
		// Primary Identifier
460
		$this->ID = absint( $payment_id );
461
462
		// Protected ID that can never be changed
463
		$this->_ID = absint( $payment_id );
464
465
		// We have a payment, get the generic payment_meta item to reduce calls to it
466 52
		$this->payment_meta = $this->get_meta();
467
468
		// Status and Dates
469 52
		$this->date           = $payment->post_date;
470 52
		$this->post_date      = $payment->post_date;
471 31
		$this->completed_date = $this->setup_completed_date();
472 52
		$this->status         = $payment->post_status;
473
		$this->post_status    = $this->status;
474 22
		$this->mode           = $this->setup_mode();
475 21
		$this->parent_payment = $payment->post_parent;
476 21
477
		$all_payment_statuses  = give_get_payment_statuses();
478
		$this->status_nicename = array_key_exists( $this->status, $all_payment_statuses ) ? $all_payment_statuses[ $this->status ] : ucfirst( $this->status );
479 52
480
		// Items
481 1
		$this->fees = $this->setup_fees();
482 1
483 1
		// Currency Based
484 1
		$this->total      = $this->setup_total();
485
		$this->fees_total = $this->setup_fees_total();
486
		$this->subtotal   = $this->setup_subtotal();
487 52
		$this->currency   = $this->setup_currency();
488
489 1
		// Gateway based
490 1
		$this->gateway        = $this->setup_gateway();
491
		$this->transaction_id = $this->setup_transaction_id();
492 1
493
		// User based
494
		$this->ip          = $this->setup_ip();
495 52
		$this->customer_id = $this->setup_customer_id();
496 52
		$this->user_id     = $this->setup_user_id();
497 52
		$this->email       = $this->setup_email();
498 52
		$this->user_info   = $this->setup_user_info();
499 52
		$this->address     = $this->setup_address();
500 52
		$this->first_name  = $this->user_info['first_name'];
501 52
		$this->last_name   = $this->user_info['last_name'];
502 52
503
		// Other Identifiers
504 52
		$this->form_title = $this->setup_form_title();
505 52
		$this->form_id    = $this->setup_form_id();
506 52
		$this->price_id   = $this->setup_price_id();
507 52
		$this->key        = $this->setup_payment_key();
508 52
		$this->number     = $this->setup_payment_number();
509 52
510 52
		// Allow extensions to add items to this object via hook
511 52
		do_action( 'give_setup_payment', $this, $payment_id );
512 52
513
		return true;
514 52
	}
515 52
516 52
    /**
517 52
     * Payment class object is storing various meta value in object parameter.
518 52
     * So if user is updating payment meta but not updating payment object, then payment meta values will not reflect/changes on payment meta automatically
519 52
     * and you can still access payment meta old value in any old payment object ( previously created ) which can cause to show or save wrong payment data.
520 52
     * To prevent that user can use this function after updating any payment meta value ( in bulk or single update ).
521 52
     *  
522
     * @since  1.6
523
     * @access public
524 52
     * 
525
     * @param  int $payment_id Payment ID.
526 52
     * 
527
     * @return void
528 52
     */
529 52
    public function update_payment_setup( $payment_id ){
530
        $this->setup_payment( $payment_id );
531 52
    }
532
533 52
	/**
534
	 * Create the base of a payment.
535
	 *
536
	 * @since  1.5
537 52
	 * @access private
538 52
	 *
539 52
	 * @return int|bool False on failure, the payment ID on success.
540
	 */
541 52
	private function insert_payment() {
542
543
		// Construct the payment title
544 52
		$payment_title = '';
545 52
		if ( ! empty( $this->first_name ) && ! empty( $this->last_name ) ) {
546 52
			$payment_title = $this->first_name . ' ' . $this->last_name;
547 52
		} else if ( ! empty( $this->first_name ) && empty( $this->last_name ) ) {
548
			$payment_title = $this->first_name;
549 52
		} else if ( ! empty( $this->email ) && is_email( $this->email ) ) {
550
			$payment_title = $this->email;
551 52
		}
552
553 52
		//Set Key
554 52
		if ( empty( $this->key ) ) {
555 52
556
			$auth_key             = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
557 52
			$this->key            = strtolower( md5( $this->email . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) );  // Unique key
558 52
			$this->pending['key'] = $this->key;
559
		}
560
561
		//Set IP
562
		if ( empty( $this->ip ) ) {
563
564
			$this->ip            = give_get_ip();
565 52
			$this->pending['ip'] = $this->ip;
566 52
567 52
		}
568
569 52
		$payment_data = array(
570
			'price'        => $this->total,
571
			'date'         => $this->date,
572
			'user_email'   => $this->email,
573
			'purchase_key' => $this->key,
574
			'form_title'   => $this->form_title,
575
			'form_id'      => $this->form_id,
576
			'price_id'     => $this->price_id,
577
			'currency'     => $this->currency,
578
			'user_info'    => array(
579
				'id'         => $this->user_id,
580 52
				'email'      => $this->email,
581
				'first_name' => $this->first_name,
582 52
				'last_name'  => $this->last_name,
583
				'address'    => $this->address,
584
			),
585 52
			'status'       => $this->status,
586
			'fees'         => $this->fees,
587 52
		);
588
589 52
		$args = apply_filters( 'give_insert_payment_args', array(
590
			'post_title'    => $payment_title,
591
			'post_status'   => $this->status,
592 52
			'post_type'     => 'give_payment',
593
			'post_date'     => ! empty( $this->date ) ? $this->date : null,
594
			'post_date_gmt' => ! empty( $this->date ) ? get_gmt_from_date( $this->date ) : null,
595 52
			'post_parent'   => $this->parent_payment,
596
		), $payment_data );
597
598 52
		// Create a blank payment
599 1
		$payment_id = wp_insert_post( $args );
600 1
601
		if ( ! empty( $payment_id ) ) {
602
603 52
			$this->ID  = $payment_id;
604
			$this->_ID = $payment_id;
605 52
606 52
			$customer = new stdClass;
607
608 52
			if ( did_action( 'give_pre_process_purchase' ) && is_user_logged_in() ) {
609
				$customer = new Give_Customer( get_current_user_id(), true );
610
			}
611
612 52
			if ( empty( $customer->id ) ) {
613
				$customer = new Give_Customer( $this->email );
614 52
			}
615
616 52
			if ( empty( $customer->id ) ) {
617 52
618
				$customer_data = array(
619 52
					'name'    => ! is_email( $payment_title ) ? $this->first_name . ' ' . $this->last_name : '',
620
					'email'   => $this->email,
621 52
					'user_id' => $this->user_id,
622
				);
623 52
624
				$customer->create( $customer_data );
0 ignored issues
show
Bug introduced by
The method create does only exist in Give_Customer, 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...
625 52
626
			}
627
628 1
			$this->customer_id            = $customer->id;
629
			$this->pending['customer_id'] = $this->customer_id;
630 1
			$customer->attach_payment( $this->ID, false );
0 ignored issues
show
Bug introduced by
The method attach_payment does only exist in Give_Customer, 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...
631 1
632
			$this->payment_meta = apply_filters( 'give_payment_meta', $this->payment_meta, $payment_data );
633 1
			if ( ! empty( $this->payment_meta['fees'] ) ) {
634 1
				$this->fees = array_merge( $this->fees, $this->payment_meta['fees'] );
635 1
				foreach ( $this->fees as $fee ) {
636
					$this->increase_fees( $fee['amount'] );
637 1
				}
638 1
			}
639 1
640
			$this->update_meta( '_give_payment_meta', $this->payment_meta );
641 1
			$this->new = true;
642 1
		}
643 52
644
		return $this->ID;
645 2
646
	}
647 2
648 2
	/**
649 2
	 * Save
650
	 *
651
	 * Once items have been set, an update is needed to save them to the database.
652 2
	 *
653 2
     * @access public
654 2
	 *
655 2
	 * @return bool  True of the save occurred, false if it failed or wasn't needed
656
	 */
657 2
	public function save() {
658 2
659
		$saved = false;
660 2
661 2
		//Must have an ID 
662 2
		if ( empty( $this->ID ) ) {
663
664 2
			$payment_id = $this->insert_payment();
665 2
666 1
			if ( false === $payment_id ) {
667 2
				$saved = false;
668
			} else {
669 2
				$this->ID = $payment_id;
670 1
			}
671 1
672 1
		}
673
674 1
		//Set ID if not matching
675 1
		if ( $this->ID !== $this->_ID ) {
676 2
			$this->ID = $this->_ID;
677
		}
678 52
679
		// If we have something pending, let's save it
680 52
		if ( ! empty( $this->pending ) ) {
681 52
682
			$total_increase = 0;
683 52
			$total_decrease = 0;
684
685
			foreach ( $this->pending as $key => $value ) {
686
687
				switch ( $key ) {
688
689
					case 'donations':
690
						// Update totals for pending donations
691
						foreach ( $this->pending[ $key ] as $item ) {
692
693
							$quantity = isset( $item['quantity'] ) ? $item['quantity'] : 1;
694
							$price_id = isset( $item['price_id'] ) ? $item['price_id'] : 0;
695
696
							switch ( $item['action'] ) {
697
698
								case 'add':
699
700
									$price = $item['price'];
701
702
									if ( 'publish' === $this->status || 'complete' === $this->status ) {
703
704
										// Add sales logs
705
										$log_date = date_i18n( 'Y-m-d G:i:s', current_time( 'timestamp' ) );
706
707
										$y = 0;
708
										while ( $y < $quantity ) {
709
710
											give_record_sale_in_log( $item['id'], $this->ID, $price_id, $log_date );
711 52
											$y ++;
712 52
										}
713 52
714
										$form = new Give_Donate_Form( $item['id'] );
715 52
										$form->increase_sales( $quantity );
716 52
										$form->increase_earnings( $price );
717 52
718
										$total_increase += $price;
719 52
									}
720 52
									break;
721 52
722
								case 'remove':
723 52
									$log_args = array(
724 20
										'post_type'   => 'give_log',
725 20
										'post_parent' => $item['id'],
726
										'numberposts' => $quantity,
727 52
										'meta_query'  => array(
728 52
											array(
729 52
												'key'     => '_give_log_payment_id',
730
												'value'   => $this->ID,
731 52
												'compare' => '=',
732 52
											),
733 52
											array(
734
												'key'     => '_give_log_price_id',
735 52
												'value'   => $price_id,
736 52
												'compare' => '='
737 52
											)
738
										)
739 52
									);
740 52
741 52
									$found_logs = get_posts( $log_args );
742
									foreach ( $found_logs as $log ) {
743 52
										wp_delete_post( $log->ID, true );
744 52
									}
745 52
746
									if ( 'publish' === $this->status || 'complete' === $this->status ) {
747 52
										$form = new Give_Donate_Form( $item['id'] );
748 52
										$form->decrease_sales( $quantity );
749 52
										$form->decrease_earnings( $item['amount'] );
750
751 52
										$total_decrease += $item['amount'];
752 52
									}
753 52
									break;
754
755 52
							}
756 52
757 52
						}
758
						break;
759 52
760
					case 'fees':
761
762
						if ( 'publish' !== $this->status && 'complete' !== $this->status ) {
763 52
							break;
764 52
						}
765 52
766
						if ( empty( $this->pending[ $key ] ) ) {
767 52
							break;
768 52
						}
769 52
770
						foreach ( $this->pending[ $key ] as $fee ) {
771 52
772 20
							switch ( $fee['action'] ) {
773 20
774
								case 'add':
775 52
									$total_increase += $fee['amount'];
776
									break;
777 2
778 2
								case 'remove':
779 2
									$total_decrease += $fee['amount'];
780 2
									break;
781
782 2
							}
783 2
784
						}
785 52
786 42
						break;
787 42
788
					case 'status':
789 52
						$this->update_status( $this->status );
790
						break;
791 52
792 52
					case 'gateway':
793 52
						$this->update_meta( '_give_payment_gateway', $this->gateway );
794
						break;
795 52
796 52
					case 'mode':
797
						$this->update_meta( '_give_payment_mode', $this->mode );
798 52
						break;
799 52
800 52
					case 'transaction_id':
801 52
						$this->update_meta( '_give_payment_transaction_id', $this->transaction_id );
802 52
						break;
803
804 52
					case 'ip':
805
						$this->update_meta( '_give_payment_user_ip', $this->ip );
806 42
						break;
807
808 42
					case 'customer_id':
809 42
						$this->update_meta( '_give_payment_customer_id', $this->customer_id );
810
						break;
811 1
812
					case 'user_id':
813 1
						$this->update_meta( '_give_payment_user_id', $this->user_id );
814 1
						break;
815
816 42
					case 'form_title':
817
						$this->update_meta( '_give_payment_form_title', $this->form_title );
818
						break;
819 1
820 1
					case 'form_id':
821
						$this->update_meta( '_give_payment_form_id', $this->form_id );
822 1
						break;
823
824 42
					case 'price_id':
825
						$this->update_meta( '_give_payment_price_id', $this->price_id );
826 52
						break;
827
828
					case 'first_name':
829 52
						$this->user_info['first_name'] = $this->first_name;
830 52
						break;
831 52
832 52
					case 'last_name':
833 52
						$this->user_info['last_name'] = $this->last_name;
834 52
						break;
835 52
836
					case 'address':
837 52
						$this->user_info['address'] = $this->address;
838 52
						break;
839
840
					case 'email':
841 52
						$this->update_meta( '_give_payment_user_email', $this->email );
842 52
						break;
843 52
844 52
					case 'key':
845 52
						$this->update_meta( '_give_payment_purchase_key', $this->key );
846 52
						break;
847
848 52
					case 'number':
849 52
						$this->update_meta( '_give_payment_number', $this->number );
850 52
						break;
851
852 52
					case 'date':
853 52
						$args = array(
854 52
							'ID'        => $this->ID,
855
							'post_date' => $this->date,
856 52
							'edit_date' => true,
857
						);
858
859
						wp_update_post( $args );
860
						break;
861
862
					case 'completed_date':
863
						$this->update_meta( '_give_completed_date', $this->completed_date );
864
						break;
865
866
					case 'parent_payment':
867
						$args = array(
868
							'ID'          => $this->ID,
869
							'post_parent' => $this->parent_payment,
870 52
						);
871
872 52
						wp_update_post( $args );
873
						break;
874
875 52
					default:
876
						do_action( 'give_payment_save', $this, $key );
877
						break;
878
				}
879
			}
880
881 52
			if ( 'pending' !== $this->status ) {
882 52
883 52
				$customer = new Give_Customer( $this->customer_id );
884 52
885
				$total_change = $total_increase - $total_decrease;
886 52
				if ( $total_change < 0 ) {
887
888
					$total_change = - ( $total_change );
889 52
					// Decrease the customer's purchase stats
890 52
					$customer->decrease_value( $total_change );
891 52
					give_decrease_total_earnings( $total_change );
892
893
				} else if ( $total_change > 0 ) {
894 2
895 1
					// Increase the customer's purchase stats
896 1
					$customer->increase_value( $total_change );
897
					give_increase_total_earnings( $total_change );
898 1
899
				}
900
901 1
			}
902 1
903 1
			$this->update_meta( '_give_payment_total', $this->total );
904 1
905 1
			$new_meta = array(
906 1
				'form_title' => $this->form_title,
907
				'form_id'    => $this->form_id,
908 1
				'price_id'   => $this->price_id,
909
				'fees'       => $this->fees,
910
				'currency'   => $this->currency,
911
				'user_info'  => $this->user_info,
912 1
			);
913
914 1
			$meta        = $this->get_meta();
915
			$merged_meta = array_merge( $meta, $new_meta );
916
917
			// Only save the payment meta if it's changed
918
			if ( md5( serialize( $meta ) ) !== md5( serialize( $merged_meta ) ) ) {
919
				$updated = $this->update_meta( '_give_payment_meta', $merged_meta );
920 52
				if ( false !== $updated ) {
921 52
					$saved = true;
922
				}
923
			}
924 52
925 52
			$this->pending = array();
926 52
			$saved         = true;
927 52
		}
928 52
929
		if ( true === $saved ) {
930
			$this->setup_payment( $this->ID );
931 52
		}
932
933
		return $saved;
934
	}
935
936 52
	/**
937 52
	 * Add a donation to a given payment
938 52
	 *
939 52
	 * @since  1.5
940 52
     * @access public
941 52
	 *
942 52
	 * @param  int   $form_id The donation form to add
943
	 * @param  array $args    Other arguments to pass to the function
944 52
	 * @param  array $options List of donation options
945
	 *
946 52
	 * @return bool           True when successful, false otherwise
947
	 */
948 52
	public function add_donation( $form_id = 0, $args = array(), $options = array() ) {
949
950 52
		$donation = new Give_Donate_Form( $form_id );
951
952
		// Bail if this post isn't a give donation form
953
		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...
954
			return false;
955
		}
956
957
		// Set some defaults
958
		$defaults = array(
959
			'price'    => false,
960
			'price_id' => false,
961
			'fees'     => array(),
962
		);
963
964 2
		$args = wp_parse_args( apply_filters( 'give_payment_add_donation_args', $args, $donation->ID ), $defaults );
965
966
		// Allow overriding the price
967
		if ( false !== $args['price'] ) {
968 2
			$item_price = $args['price'];
969 2
		} else {
970 2
971 2
			// Deal with variable pricing
972 2
			if ( give_has_variable_prices( $donation->ID ) ) {
973
				$prices     = maybe_unserialize( get_post_meta( $form_id, '_give_donation_levels', true ) );
974 2
				$item_price = '';
975
				//Loop through prices
976
				foreach ( $prices as $price ) {
977 2
					//Find a match between price_id and level_id
978
					//First verify array keys exists THEN make the match
979
					if ( ( isset( $args['price_id'] ) && isset( $price['_give_id']['level_id'] ) )
980
					     && $args['price_id'] == $price['_give_id']['level_id']
981 2
					) {
982 2
						$item_price = $price['_give_amount'];
983 2
					}
984 2
				}
985 2
				//Fallback to the lowest price point
986 2
				if ( $item_price == '' ) {
987
					$item_price       = give_get_lowest_price_option( $donation->ID );
988 2
					$args['price_id'] = give_get_lowest_price_id( $donation->ID );
989
				}
990 2
			} else {
991
				//Simple form price
992 2
				$item_price = give_get_form_price( $donation->ID );
993
			}
994
995
		}
996
997
		// Sanitizing the price here so we don't have a dozen calls later
998
		$item_price = give_sanitize_amount( $item_price );
999
		$total      = round( $item_price, give_currency_decimal_filter() );
1000
1001
		//Add Options
1002
		$default_options = array();
1003
		if ( false !== $args['price_id'] ) {
1004
			$default_options['price_id'] = (int) $args['price_id'];
1005
		}
1006
		$options = wp_parse_args( $options, $default_options );
1007
1008
		// Do not allow totals to go negative
1009
		if ( $total < 0 ) {
1010
			$total = 0;
1011
		}
1012
1013
		$donation = array(
1014
			'name'     => $donation->post_title,
1015
			'id'       => $donation->ID,
1016
			'price'    => round( $total, give_currency_decimal_filter() ),
1017
			'subtotal' => round( $total, give_currency_decimal_filter() ),
1018
			'fees'     => $args['fees'],
1019
			'price_id' => $args['price_id'],
1020
			'action'   => 'add',
1021
			'options'  => $options
1022
		);
1023
1024
		$this->pending['donations'][] = $donation;
1025
1026
		$this->increase_subtotal( $total );
1027
1028
		return true;
1029
1030
	}
1031
1032
	/**
1033
	 * Remove a donation from the payment
1034
	 *
1035
	 * @since  1.5
1036
     * @access public
1037
	 *
1038
	 * @param  int   $form_id The form ID to remove
1039
	 * @param  array $args    Arguments to pass to identify (quantity, amount, price_id)
1040
	 *
1041
	 * @return bool           If the item was removed or not
1042
	 */
1043
	public function remove_donation( $form_id, $args = array() ) {
1044
1045
		// Set some defaults
1046
		$defaults = array(
1047
			'quantity' => 1,
1048
			'price'    => false,
1049
			'price_id' => false,
1050
		);
1051
		$args     = wp_parse_args( $args, $defaults );
1052
1053
		$form = new Give_Donate_Form( $form_id );
1054
1055
		// Bail if this post isn't a valid give donation form
1056
		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...
1057
			return false;
1058
		}
1059
1060
		$pending_args             = $args;
1061
		$pending_args['id']       = $form_id;
1062
		$pending_args['amount']   = $this->total;
1063
		$pending_args['price_id'] = false !== $args['price_id'] ? (int) $args['price_id'] : false;
1064
		$pending_args['quantity'] = $args['quantity'];
1065
		$pending_args['action']   = 'remove';
1066
1067
		$this->pending['donations'][] = $pending_args;
1068
1069
		$this->decrease_subtotal( $this->total );
1070
1071
		return true;
1072
	}
1073
1074
	/**
1075
	 * Add a fee to a given payment
1076
	 *
1077
	 * @since  1.5
1078
     * @access public
1079
	 *
1080
	 * @param  array $args   Array of arguments for the fee to add
1081
	 * @param  bool  $global
1082
	 *
1083
	 * @return bool          If the fee was added
1084
	 */
1085
	public function add_fee( $args, $global = true ) {
0 ignored issues
show
Unused Code introduced by
The parameter $global is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1086
1087
		$default_args = array(
1088
			'label'    => '',
1089
			'amount'   => 0,
1090
			'type'     => 'fee',
1091
			'id'       => '',
1092
			'price_id' => 0,
1093
		);
1094
1095
		$fee          = wp_parse_args( $args, $default_args );
1096
		$this->fees[] = $fee;
1097
1098
1099
		$added_fee               = $fee;
1100
		$added_fee['action']     = 'add';
1101
		$this->pending['fees'][] = $added_fee;
1102
		reset( $this->fees );
1103
1104
		$this->increase_fees( $fee['amount'] );
1105
1106
		return true;
1107
	}
1108
1109
	/**
1110
	 * Remove a fee from the payment
1111
	 *
1112
	 * @since  1.5
1113
     * @access public
1114
	 *
1115
	 * @param  int $key The array key index to remove
1116
	 *
1117
	 * @return bool     If the fee was removed successfully
1118
	 */
1119
	public function remove_fee( $key ) {
1120
		$removed = false;
1121
1122
		if ( is_numeric( $key ) ) {
1123
			$removed = $this->remove_fee_by( 'index', $key );
1124
		}
1125
1126
		return $removed;
1127
	}
1128
1129
	/**
1130
	 * Remove a fee by the defined attributed
1131
	 *
1132
	 * @since  1.5
1133
     * @access public
1134
	 *
1135
	 * @param  string     $key    The key to remove by
1136
	 * @param  int|string $value  The value to search for
1137
	 * @param  boolean    $global False - removes the first value it fines,
1138
	 *                            True - removes all matches.
1139
	 *
1140
	 * @return boolean            If the item is removed
1141
	 */
1142
	public function remove_fee_by( $key, $value, $global = false ) {
1143
1144
		$allowed_fee_keys = apply_filters( 'give_payment_fee_keys', array(
1145
			'index',
1146
			'label',
1147
			'amount',
1148
			'type',
1149
		) );
1150
1151
		if ( ! in_array( $key, $allowed_fee_keys ) ) {
1152
			return false;
1153
		}
1154
1155
		$removed = false;
1156
		if ( 'index' === $key && array_key_exists( $value, $this->fees ) ) {
1157
1158
			$removed_fee             = $this->fees[ $value ];
1159
			$removed_fee['action']   = 'remove';
1160
			$this->pending['fees'][] = $removed_fee;
1161
1162
			$this->decrease_fees( $removed_fee['amount'] );
1163
1164
			unset( $this->fees[ $value ] );
1165
			$removed = true;
1166
1167
		} else if ( 'index' !== $key ) {
1168
1169
			foreach ( $this->fees as $index => $fee ) {
1170
1171
				if ( isset( $fee[ $key ] ) && $fee[ $key ] == $value ) {
1172 52
1173 52
					$removed_fee             = $fee;
1174 52
					$removed_fee['action']   = 'remove';
1175
					$this->pending['fees'][] = $removed_fee;
1176 52
1177 52
					$this->decrease_fees( $removed_fee['amount'] );
1178
1179
					unset( $this->fees[ $index ] );
1180
					$removed = true;
1181
1182
					if ( false === $global ) {
1183
						break;
1184
					}
1185
1186
				}
1187
1188 2
			}
1189 2
1190 2
		}
1191
1192 2
		if ( true === $removed ) {
1193
			$this->fees = array_values( $this->fees );
1194
		}
1195
1196 2
		return $removed;
1197 2
	}
1198
1199
	/**
1200
	 * Get the fees, filterable by type
1201
	 *
1202
	 * @since  1.5
1203
     * @access public
1204
	 *
1205
	 * @param  string $type All, item, fee
1206
	 *
1207
	 * @return array        The Fees for the type specified
1208
	 */
1209
	public function get_fees( $type = 'all' ) {
1210
		$fees = array();
1211
1212
		if ( ! empty( $this->fees ) && is_array( $this->fees ) ) {
1213
1214
			foreach ( $this->fees as $fee_id => $fee ) {
1215
1216
				if ( 'all' != $type && ! empty( $fee['type'] ) && $type != $fee['type'] ) {
1217
					continue;
1218
				}
1219
1220
				$fee['id'] = $fee_id;
1221
				$fees[]    = $fee;
1222
1223
			}
1224
		}
1225
1226
		return apply_filters( 'give_get_payment_fees', $fees, $this->ID, $this );
1227
	}
1228
1229
	/**
1230
	 * Add a note to a payment
1231
	 *
1232
	 * @since  1.0
1233
     * @access public
1234
	 *
1235
	 * @param  string $note The note to add
1236
	 *
1237
	 * @return void
1238
	 */
1239
	public function add_note( $note = false ) {
1240
		// Bail if no note specified
1241 52
		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...
1242 52
			return false;
1243 52
		}
1244
1245
		give_insert_payment_note( $this->ID, $note );
1246
	}
1247
1248
	/**
1249
	 * Increase the payment's subtotal
1250
	 *
1251
	 * @since  1.5
1252
     * @access private
1253
	 *
1254 52
	 * @param  float $amount The amount to increase the payment subtotal by
1255
	 *
1256
	 * @return void
1257 52
	 */
1258 39
	private function increase_subtotal( $amount = 0.00 ) {
1259 39
		$amount = (float) $amount;
1260
		$this->subtotal += $amount;
1261 52
1262
		$this->recalculate_total();
1263 52
	}
1264 52
1265
	/**
1266
	 * Decrease the payment's subtotal
1267 42
	 *
1268
	 * @since  1.5
1269 42
     * @access private
1270
	 *
1271
	 * @param  float $amount The amount to decrease the payment subtotal by
1272 42
	 *
1273
	 * @return void
1274 42
	 */
1275
	private function decrease_subtotal( $amount = 0.00 ) {
1276
		$amount = (float) $amount;
1277 42
		$this->subtotal -= $amount;
1278 42
1279 42
		if ( $this->subtotal < 0 ) {
1280 42
			$this->subtotal = 0;
1281
		}
1282 42
1283
		$this->recalculate_total();
1284 42
	}
1285 42
1286
	/**
1287
	 * Increase the payment's subtotal
1288
	 *
1289 42
	 * @since  1.5
1290 4
     * @access private
1291 4
	 *
1292 42
	 * @param  float $amount The amount to increase the payment subtotal by
1293
	 *
1294
	 * @return void
1295 42
	 */
1296 3
	private function increase_fees( $amount = 0.00 ) {
1297 3
		$amount = (float) $amount;
1298
		$this->fees_total += $amount;
1299
1300 42
		$this->recalculate_total();
1301
	}
1302 42
1303
	/**
1304 42
	 * Decrease the payment's subtotal
1305
	 *
1306
	 * @since  1.5
1307
     * @access private
1308
	 *
1309
	 * @param  float $amount The amount to decrease the payment subtotal by
1310
	 *
1311
	 * @return void
1312
	 */
1313
	private function decrease_fees( $amount = 0.00 ) {
1314 4
		$amount = (float) $amount;
1315 4
		$this->fees_total -= $amount;
1316 4
1317 4
		if ( $this->fees_total < 0 ) {
1318
			$this->fees_total = 0;
1319 4
		}
1320 4
1321
		$this->recalculate_total();
1322
	}
1323
1324
	/**
1325
	 * Set or update the total for a payment
1326
	 *
1327
	 * @since  1.0
1328
     * @access private
1329
	 *
1330
	 * @return void
1331
	 */
1332 52
	private function recalculate_total() {
1333
		$this->total = $this->subtotal + $this->fees_total;
1334 52
	}
1335
1336 52
	/**
1337
	 * Set the payment status and run any status specific changes necessary
1338 52
	 *
1339 52
	 * @since  1.0
1340 52
     * @access public
1341
	 *
1342 52
	 * @param  string $status  The status to set the payment to
1343 52
	 *
1344 52
	 * @return bool   $updated Returns if the status was successfully updated
1345
	 */
1346 52
	public function update_status( $status = false ) {
1347 52
1348 52
		//standardize the 'complete(d)' status
1349
		if ( $status == 'completed' || $status == 'complete' ) {
1350 52
			$status = 'publish';
1351 52
		}
1352 52
1353 52
		$old_status = ! empty( $this->old_status ) ? $this->old_status : false;
1354
1355 52
		if ( $old_status === $status ) {
1356
			return false; // Don't permit status changes that aren't changes
1357 52
		}
1358
1359
		$do_change = apply_filters( 'give_should_update_payment_status', true, $this->ID, $status, $old_status );
1360
1361
		$updated = false;
1362
1363
1364
		if ( $do_change ) {
1365
1366
			do_action( 'give_before_payment_status_change', $this->ID, $status, $old_status );
1367
1368
			$update_fields = array(
1369
				'ID'          => $this->ID,
1370
				'post_status' => $status,
1371 52
				'edit_date'   => current_time( 'mysql' )
1372 52
			);
1373
1374
			$updated = wp_update_post( apply_filters( 'give_update_payment_status_fields', $update_fields ) );
1375
1376 52
			$all_payment_statuses  = give_get_payment_statuses();
1377
			$this->status_nicename = array_key_exists( $status, $all_payment_statuses ) ? $all_payment_statuses[ $status ] : ucfirst( $status );
1378
1379
			// Process any specific status functions
1380
			switch ( $status ) {
1381
				case 'refunded':
1382
					$this->process_refund();
1383
					break;
1384 52
				case 'failed':
1385
					$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...
1386 52
					break;
1387 52
				case 'pending':
1388
					$this->process_pending();
1389 52
					break;
1390 52
                case 'cancelled':
1391
                    $this->process_cancelled();
1392 52
                    break;
1393 52
                case 'revoked':
1394
                    $this->process_revoked();
1395 52
                    break;
1396
			}
1397 52
1398
			do_action( 'give_update_payment_status', $this->ID, $status, $old_status );
1399 52
1400
		}
1401
1402
		return $updated;
1403
1404
	}
1405
1406
	/**
1407
	 * Change the status of the payment to refunded, and run the necessary changes
1408
	 *
1409 4
	 * @since  1.5
1410 4
     * @access public
1411
	 *
1412
	 * @return void
1413 4
	 */
1414
	public function refund() {
1415
		$this->old_status        = $this->status;
1416
		$this->status            = 'refunded';
1417
		$this->pending['status'] = $this->status;
1418 4
1419
		$this->save();
1420 4
	}
1421
1422
	/**
1423
	 * Get a post meta item for the payment
1424 4
	 *
1425
	 * @since  1.5
1426 4
     * @access public
1427 4
	 *
1428 4
	 * @param  string  $meta_key The Meta Key
1429
	 * @param  boolean $single   Return single item or array
1430 4
	 *
1431 4
	 * @return mixed             The value from the post meta
1432
	 */
1433
	public function get_meta( $meta_key = '_give_payment_meta', $single = true ) {
1434 4
1435
		$meta = get_post_meta( $this->ID, $meta_key, $single );
1436 4
1437 4
		if ( $meta_key === '_give_payment_meta' ) {
1438
1439
			if ( empty( $meta['key'] ) ) {
1440
				$meta['key'] = $this->setup_payment_key();
1441
			}
1442
1443
			if ( empty( $meta['form_title'] ) ) {
1444
				$meta['form_title'] = $this->setup_form_title();
1445
			}
1446
1447
			if ( empty( $meta['email'] ) ) {
1448
				$meta['email'] = $this->setup_email();
1449
			}
1450
1451
			if ( empty( $meta['date'] ) ) {
1452
				$meta['date'] = get_post_field( 'post_date', $this->ID );
1453
			}
1454
		}
1455
1456 3
		$meta = apply_filters( 'give_get_payment_meta_' . $meta_key, $meta, $this->ID );
1457 3
1458
		return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1459
	}
1460 3
1461 1
	/**
1462 1
	 * Update the post meta
1463
	 *
1464
	 * @since  1.5
1465 3
     * @access public
1466
	 *
1467 3
	 * @param  string $meta_key   The meta key to update
1468 1
	 * @param  string $meta_value The meta value
1469
	 * @param  string $prev_value Previous meta value
1470
	 *
1471 2
	 * @return int|bool           Meta ID if the key didn't exist, true on successful update, false on failure
1472 2
	 */
1473 2
	public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1474
		if ( empty( $meta_key ) ) {
1475 2
			return false;
1476 2
		}
1477
1478 2
		if ( $meta_key == 'key' || $meta_key == 'date' ) {
1479 2
1480
			$current_meta              = $this->get_meta();
1481
			$current_meta[ $meta_key ] = $meta_value;
1482 2
1483 2
			$meta_key   = '_give_payment_meta';
1484
			$meta_value = $current_meta;
1485
1486
		} else if ( $meta_key == 'email' || $meta_key == '_give_payment_user_email' ) {
1487
1488
			$meta_value = apply_filters( 'give_give_update_payment_meta_' . $meta_key, $meta_value, $this->ID );
1489
			update_post_meta( $this->ID, '_give_payment_user_email', $meta_value );
1490
1491
			$current_meta                       = $this->get_meta();
1492
			$current_meta['user_info']['email'] = $meta_value;
1493
1494
			$meta_key   = '_give_payment_meta';
1495
			$meta_value = $current_meta;
1496 6
1497
		}
1498 6
1499
		$meta_value = apply_filters( 'give_update_payment_meta_' . $meta_key, $meta_value, $this->ID );
1500
1501 6
		return update_post_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1502 4
	}
1503 4
1504
	/**
1505
	 * When a payment is set to a status of 'refunded' process the necessary actions to reduce stats
1506 6
	 *
1507
	 * @since  1.5
1508 6
	 * @access private
1509
	 *
1510 6
	 * @return void
1511 4
	 */
1512 4
	private function process_refund() {
1513
		$process_refund = true;
1514 6
1515 4
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
1516 4
		if ( 'publish' != $this->old_status || 'refunded' != $this->status ) {
1517
			$process_refund = false;
1518 6
		}
1519
1520 6
		// Allow extensions to filter for their own payment types, Example: Recurring Payments
1521
		$process_refund = apply_filters( 'give_should_process_refund', $process_refund, $this );
1522
1523
		if ( false === $process_refund ) {
1524
			return;
1525
		}
1526
1527
		do_action( 'give_pre_refund_payment', $this );
1528 6
1529 6
		$decrease_store_earnings = apply_filters( 'give_decrease_store_earnings_on_refund', true, $this );
1530
		$decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_refund', true, $this );
1531
		$decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_refund', true, $this );
1532 6
1533 6
		$this->maybe_alter_stats( $decrease_store_earnings, $decrease_customer_value, $decrease_purchase_count );
1534 6
		$this->delete_sales_logs();
1535
1536
		// Clear the This Month earnings (this_monththis_month is NOT a typo)
1537 6
		delete_transient( md5( 'give_earnings_this_monththis_month' ) );
1538 6
1539 6
		do_action( 'give_post_refund_payment', $this );
1540
	}
1541 6
1542 6
	/**
1543
	 * Process when a payment is set to failed
1544
	 *
1545
	 * @since  1.5
1546
	 * @access private
1547
	 *
1548
	 * @return void
1549
	 */
1550
	private function process_failure() {
1551
1552
	}
1553
1554
	/**
1555
	 * Process when a payment moves to pending
1556
	 *
1557
	 * @since  1.5
1558
	 * @access private
1559 52
	 *
1560 52
	 * @return void
1561
	 */
1562 52
	private function process_pending() {
1563 52
		$process_pending = true;
1564
1565
		// If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
1566 42
		if ( 'publish' != $this->old_status || 'pending' != $this->status ) {
1567
			$process_pending = false;
1568 42
		}
1569
1570
		// Allow extensions to filter for their own payment types, Example: Recurring Payments
1571
		$process_pending = apply_filters( 'give_should_process_pending', $process_pending, $this );
1572
1573
		if ( false === $process_pending ) {
1574
			return;
1575
		}
1576
1577 52
		$decrease_store_earnings = apply_filters( 'give_decrease_store_earnings_on_pending', true, $this );
1578 52
		$decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_pending', true, $this );
1579
		$decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_pending', true, $this );
1580
1581
		$this->maybe_alter_stats( $decrease_store_earnings, $decrease_customer_value, $decrease_purchase_count );
1582
		$this->delete_sales_logs();
1583
1584
		$this->completed_date = false;
1585
		$this->update_meta( '_give_completed_date', '' );
1586
1587 52
		// Clear the This Month earnings (this_monththis_month is NOT a typo)
1588 52
		delete_transient( md5( 'give_earnings_this_monththis_month' ) );
1589
	}
1590 52
1591 2
    /**
1592 2
     * Process when a payment moves to cancelled
1593
     *
1594 2
     * @since  1.5
1595
	 * @access private
1596
	 *
1597 2
     * @return void
1598
     */
1599 52
    private function process_cancelled() {
1600
        $process_cancelled = true;
1601
1602
        // If the payment was not in publish or revoked status, don't decrement stats as they were never incremented
1603
        if ( 'publish' != $this->old_status || 'cancelled' != $this->status ) {
1604
            $process_cancelled = false;
1605
        }
1606
1607
        // Allow extensions to filter for their own payment types, Example: Recurring Payments
1608 52
        $process_cancelled = apply_filters( 'give_should_process_cancelled', $process_cancelled, $this );
1609 52
1610
        if ( false === $process_cancelled ) {
1611 52
            return;
1612
        }
1613
1614
        $decrease_store_earnings = apply_filters( 'give_decrease_store_earnings_on_cancelled', true, $this );
1615
        $decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_cancelled', true, $this );
1616
        $decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_cancelled', true, $this );
1617
1618
        $this->maybe_alter_stats( $decrease_store_earnings, $decrease_customer_value, $decrease_purchase_count );
1619
        $this->delete_sales_logs();
1620 52
1621 52
        $this->completed_date = false;
1622
        $this->update_meta( '_give_completed_date', '' );
1623 52
1624 52
        // Clear the This Month earnings (this_monththis_month is NOT a typo)
1625
        delete_transient( md5( 'give_earnings_this_monththis_month' ) );
1626
    }
1627
1628
    /**
1629
     * Process when a payment moves to revoked
1630 52
     *
1631
     * @since  1.5
1632
     * @return void
1633
     */
1634
    private function process_revoked() {
1635
        $process_revoked = true;
1636
1637
        // If the payment was not in publish, don't decrement stats as they were never incremented
1638
        if ( 'publish' != $this->old_status || 'revoked' != $this->status ) {
1639
            $process_revoked = false;
1640 52
        }
1641 52
1642
        // Allow extensions to filter for their own payment types, Example: Recurring Payments
1643 52
        $process_revoked = apply_filters( 'give_should_process_revoked', $process_revoked, $this );
1644
1645
        if ( false === $process_revoked ) {
1646
            return;
1647
        }
1648
1649
        $decrease_store_earnings = apply_filters( 'give_decrease_store_earnings_on_revoked', true, $this );
1650
        $decrease_customer_value = apply_filters( 'give_decrease_customer_value_on_revoked', true, $this );
1651
        $decrease_purchase_count = apply_filters( 'give_decrease_customer_purchase_count_on_revoked', true, $this );
1652 52
1653 52
        $this->maybe_alter_stats( $decrease_store_earnings, $decrease_customer_value, $decrease_purchase_count );
1654
        $this->delete_sales_logs();
1655 52
1656
        $this->completed_date = false;
1657
        $this->update_meta( '_give_completed_date', '' );
1658
1659
        // Clear the This Month earnings (this_monththis_month is NOT a typo)
1660
        delete_transient( md5( 'give_earnings_this_monththis_month' ) );
1661
    }
1662
1663
	/**
1664 52
	 * Used during the process of moving to refunded or pending, to decrement stats
1665 52
	 *
1666
	 * @since  1.5
1667 52
	 * @access private
1668
	 *
1669
	 * @param  bool $alter_store_earnings          If the method should alter the store earnings
1670
	 * @param  bool $alter_customer_value          If the method should reduce the customer value
1671
	 * @param  bool $alter_customer_purchase_count If the method should reduce the customer's purchase count
1672
	 *
1673
	 * @return void
1674
	 */
1675
	private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1676 52
1677 52
		give_undo_purchase( false, $this->ID );
1678
1679 52
		// Decrease store earnings
1680
		if ( true === $alter_store_earnings ) {
1681 52
			give_decrease_total_earnings( $this->total );
1682 52
		}
1683
1684 52
		// Decrement the stats for the customer
1685
		if ( ! empty( $this->customer_id ) ) {
1686 52
1687
			$customer = new Give_Customer( $this->customer_id );
1688
1689
			if ( true === $alter_customer_value ) {
1690
				$customer->decrease_value( $this->total );
1691
			}
1692
1693
			if ( true === $alter_customer_purchase_count ) {
1694
				$customer->decrease_purchase_count();
1695 52
			}
1696 52
1697
		}
1698 52
1699
	}
1700
1701
	/**
1702
	 * Delete sales logs for this purchase
1703
	 *
1704
	 * @since  1.5
1705
	 * @access private
1706
	 *
1707 52
	 * @return void
1708 52
	 */
1709
	private function delete_sales_logs() {
1710 52
		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...
1711
1712
		// Remove related sale log entries
1713
		$give_logs->delete_logs(
1714
			null,
1715
			'sale',
1716
			array(
1717
				array(
1718
					'key'   => '_give_log_payment_id',
1719 52
					'value' => $this->ID,
1720 52
				),
1721
			)
1722 52
		);
1723
	}
1724
1725
	/**
1726
	 * Setup functions only, these are not to be used by developers.
1727
	 * These functions exist only to allow the setup routine to be backwards compatible with our old
1728
	 * helper functions.
1729
	 *
1730
	 * These will run whenever setup_payment is called, which should only be called once.
1731 52
	 * To update an attribute, update it directly instead of re-running the setup routine
1732 52
	 */
1733
1734 52
	/**
1735 2
	 * Setup the payment completed date
1736 2
	 *
1737
	 * @since  1.5
1738 52
	 * @access private
1739
	 *
1740
	 * @return string The date the payment was completed
1741
	 */
1742
	private function setup_completed_date() {
1743
		$payment = get_post( $this->ID );
1744
1745
		if ( 'pending' == $payment->post_status || 'preapproved' == $payment->post_status ) {
1746
			return false; // This payment was never completed
1747 52
		}
1748
1749 52
		$date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1750 52
1751 52
		return $date;
1752
	}
1753 52
1754 52
	/**
1755
	 * Setup the payment mode
1756 52
	 *
1757
	 * @since  1.5
1758
	 * @access private
1759
	 *
1760
	 * @return string The payment mode
1761
	 */
1762
	private function setup_mode() {
1763
		return $this->get_meta( '_give_payment_mode' );
1764
	}
1765
1766
	/**
1767
	 * Setup the payment total
1768
	 *
1769
	 * @since  1.5
1770
	 * @access private
1771 52
	 *
1772 52
	 * @return float The payment total
1773 52
	 */
1774 52
	private function setup_total() {
1775 52
		$amount = $this->get_meta( '_give_payment_total', true );
1776
1777
		if ( empty( $amount ) && '0.00' != $amount ) {
1778
			$meta = $this->get_meta( '_give_payment_meta', true );
1779 21
			$meta = maybe_unserialize( $meta );
1780 21
1781
			if ( isset( $meta['amount'] ) ) {
1782 21
				$amount = $meta['amount'];
1783 21
			}
1784
		}
1785 21
1786 21
		return $amount;
1787 21
	}
1788
1789 21
	/**
1790 21
	 * Setup the payment subtotal
1791
	 *
1792
	 * @since  1.5
1793
	 * @access private
1794
	 *
1795
	 * @return float The subtotal of the payment
1796 52
	 */
1797
	private function setup_subtotal() {
1798 52
		$subtotal = $this->total;
1799
1800
		return $subtotal;
1801 52
	}
1802
1803
	/**
1804
	 * Setup the payment fees
1805
	 *
1806
	 * @since  1.5
1807
	 * @access private
1808
	 *
1809
	 * @return float The fees total for the payment
1810
	 */
1811 52
	private function setup_fees_total() {
1812
		$fees_total = (float) 0.00;
1813 52
1814 52
		$payment_fees = isset( $this->payment_meta['fees'] ) ? $this->payment_meta['fees'] : array();
1815 52
		if ( ! empty( $payment_fees ) ) {
1816 52
			foreach ( $payment_fees as $fee ) {
1817 52
				$fees_total += (float) $fee['amount'];
1818 52
			}
1819
		}
1820 52
1821
		return $fees_total;
1822 52
1823
	}
1824
1825
	/**
1826
	 * Setup the currency code
1827
	 *
1828
	 * @since  1.5
1829
	 * @access private
1830
	 *
1831 52
	 * @return string The currency for the payment
1832
	 */
1833 52
	private function setup_currency() {
1834
		$currency = isset( $this->payment_meta['currency'] ) ? $this->payment_meta['currency'] : apply_filters( 'give_payment_currency_default', give_get_currency(), $this );
1835 52
1836
		return $currency;
1837
	}
1838
1839
	/**
1840
	 * Setup any fees associated with the payment
1841
	 *
1842
	 * @since  1.5
1843
	 * @access private
1844 52
	 *
1845
	 * @return array The Fees
1846 52
	 */
1847
	private function setup_fees() {
1848 52
		$payment_fees = isset( $this->payment_meta['fees'] ) ? $this->payment_meta['fees'] : array();
1849
1850
		return $payment_fees;
1851
	}
1852
1853
	/**
1854
	 * Setup the gateway used for the payment
1855
	 *
1856
	 * @since  1.5
1857 52
	 * @access private
1858 52
	 *
1859
	 * @return string The gateway
1860 52
	 */
1861
	private function setup_gateway() {
1862
		$gateway = $this->get_meta( '_give_payment_gateway', true );
1863
1864
		return $gateway;
1865
	}
1866
1867
	/**
1868
	 * Setup the transaction ID
1869 52
	 *
1870 52
	 * @since  1.5
1871
	 * @access private
1872 52
	 *
1873
	 * @return string The transaction ID for the payment
1874
	 */
1875
	private function setup_transaction_id() {
1876
		$transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1877
1878
		if ( empty( $transaction_id ) || (int) $transaction_id === (int) $this->ID ) {
1879
1880
			$gateway        = $this->gateway;
1881 52
			$transaction_id = apply_filters( 'give_get_payment_transaction_id-' . $gateway, $this->ID );
1882 52
1883
		}
1884 52
1885
		return $transaction_id;
1886 20
	}
1887
1888 20
	/**
1889
	 * Setup the IP Address for the payment
1890 2
	 *
1891
	 * @since  1.5
1892 2
	 * @access private
1893
	 *
1894 20
	 * @return string The IP address for the payment
1895
	 */
1896 52
	private function setup_ip() {
1897
		$ip = $this->get_meta( '_give_payment_user_ip', true );
1898
1899
		return $ip;
1900
	}
1901
1902
	/**
1903
	 * Setup the customer ID
1904
	 *
1905
	 * @since  1.5
1906
	 * @access private
1907
	 *
1908
	 * @return int The Customer ID
1909
	 */
1910
	private function setup_customer_id() {
1911
		$customer_id = $this->get_meta( '_give_payment_customer_id', true );
1912
1913
		return $customer_id;
1914 42
	}
1915 42
1916
	/**
1917
	 * Setup the User ID associated with the purchase
1918
	 *
1919
	 * @since  1.5
1920
	 * @access private
1921
	 *
1922
	 * @return int The User ID
1923
	 */
1924
	private function setup_user_id() {
1925
		$user_id = $this->get_meta( '_give_payment_user_id', true );
1926
1927
		return $user_id;
1928
	}
1929
1930
	/**
1931
	 * Setup the email address for the purchase
1932
	 *
1933
	 * @since  1.5
1934 42
	 * @access private
1935 42
	 *
1936
	 * @return string The email address for the payment
1937
	 */
1938
	private function setup_email() {
1939
		$email = $this->get_meta( '_give_payment_user_email', true );
1940
1941
		if ( empty( $email ) ) {
1942
			$email = Give()->customers->get_column( 'email', $this->customer_id );
1943
		}
1944 42
1945 42
		return $email;
1946
	}
1947
1948
	/**
1949
	 * Setup the user info
1950
	 *
1951
	 * @since  1.5
1952
	 * @access private
1953
	 *
1954 11
	 * @return array The user info associated with the payment
1955 11
	 */
1956
	private function setup_user_info() {
1957
		$defaults = array(
1958
			'first_name' => $this->first_name,
1959
			'last_name'  => $this->last_name,
1960
		);
1961
1962
		$user_info = isset( $this->payment_meta['user_info'] ) ? maybe_unserialize( $this->payment_meta['user_info'] ) : array();
1963
		$user_info = wp_parse_args( $user_info, $defaults );
1964
1965
		if ( empty( $user_info ) ) {
1966
			// Get the customer, but only if it's been created
1967
			$customer = new Give_Customer( $this->customer_id );
1968
1969
			if ( $customer->id > 0 ) {
1970
				$name      = explode( ' ', $customer->name, 2 );
1971
				$user_info = array(
1972
					'first_name' => $name[0],
1973
					'last_name'  => $name[1],
1974 52
					'email'      => $customer->email,
1975 52
					'discount'   => 'none',
1976
				);
1977
			}
1978
		} else {
1979
			// Get the customer, but only if it's been created
1980
			$customer = new Give_Customer( $this->customer_id );
1981
			if ( $customer->id > 0 ) {
1982
				foreach ( $user_info as $key => $value ) {
1983
					if ( ! empty( $value ) ) {
1984 41
						continue;
1985 41
					}
1986
1987
					switch ( $key ) {
1988
						case 'first_name':
1989
							$name = explode( ' ', $customer->name, 2 );
1990
1991
							$user_info[ $key ] = $name[0];
1992
							break;
1993
1994 42
						case 'last_name':
1995 42
							$name      = explode( ' ', $customer->name, 2 );
1996
							$last_name = ! empty( $name[1] ) ? $name[1] : '';
1997
1998
							$user_info[ $key ] = $last_name;
1999
							break;
2000
2001
						case 'email':
2002
							$user_info[ $key ] = $customer->email;
2003
							break;
2004 43
					}
2005 43
				}
2006
2007
			}
2008
		}
2009
2010
		return $user_info;
2011
2012
	}
2013
2014
	/**
2015
	 * Setup the Address for the payment
2016
	 *
2017
	 * @since  1.5
2018
	 * @access private
2019
	 *
2020
	 * @return array The Address information for the payment
2021
	 */
2022
	private function setup_address() {
2023
2024 52
		$address = ! empty( $this->payment_meta['user_info']['address'] ) ? $this->payment_meta['user_info']['address'] : array(
2025 52
			'line1'   => '',
2026
			'line2'   => '',
2027
			'city'    => '',
2028
			'country' => '',
2029
			'state'   => '',
2030
			'zip'     => ''
2031
		);
2032
2033
		return $address;
2034 52
	}
2035 52
2036
	/**
2037
	 * Setup the form title
2038
	 *
2039
	 * @since  1.5
2040
	 * @access private
2041
	 *
2042
	 * @return string The Form Title
2043
	 */
2044 42
	private function setup_form_title() {
2045 42
2046
		$form_id = $this->get_meta( '_give_payment_form_title', true );
2047
2048
		return $form_id;
2049
	}
2050
2051
	/**
2052
	 * Setup the form ID
2053
	 *
2054
	 * @since  1.5
2055
	 * @access private
2056
	 *
2057
	 * @return int The Form ID
2058
	 */
2059
	private function setup_form_id() {
2060
2061
		$form_id = $this->get_meta( '_give_payment_form_id', true );
2062
2063
		return $form_id;
2064
	}
2065
2066
	/**
2067
	 * Setup the price ID
2068
	 *
2069
	 * @since  1.5
2070
	 * @access private
2071
	 *
2072
	 * @return int The Form Price ID
2073
	 */
2074
	private function setup_price_id() {
2075
		$price_id = $this->get_meta( '_give_payment_price_id', true );
2076
2077
		return $price_id;
2078
	}
2079
2080
	/**
2081
	 * Setup the payment key
2082
	 *
2083
	 * @since  1.5
2084
	 * @access private
2085
	 *
2086
	 * @return string The Payment Key
2087
	 */
2088
	private function setup_payment_key() {
2089
		$key = $this->get_meta( '_give_payment_purchase_key', true );
2090
2091
		return $key;
2092
	}
2093
2094
	/**
2095
	 * Setup the payment number
2096
	 *
2097
	 * @since  1.5
2098
	 * @access private
2099
	 *
2100
	 * @return int|string Integer by default, or string if sequential order numbers is enabled
2101
	 */
2102
	private function setup_payment_number() {
2103
		$number = $this->ID;
2104
2105
		if ( give_get_option( 'enable_sequential' ) ) {
2106
2107
			$number = $this->get_meta( '_give_payment_number', true );
2108
2109
			if ( ! $number ) {
2110
2111
				$number = $this->ID;
2112
2113
			}
2114
2115
		}
2116
2117
		return $number;
2118
	}
2119
2120
	/**
2121
	 * Converts this object into an array for special cases
2122
	 *
2123
	 * @access public
2124
	 *
2125
	 * @return array The payment object as an array
2126
	 */
2127
	public function array_convert() {
2128
		return get_object_vars( $this );
2129
	}
2130
2131
	/**
2132
	 * Retrieve payment completion date
2133
	 *
2134
	 * @since  1.5
2135
	 * @access private
2136
	 *
2137
	 * @return string Date payment was completed
2138
	 */
2139
	private function get_completed_date() {
2140
		return apply_filters( 'give_payment_completed_date', $this->completed_date, $this->ID, $this );
2141
	}
2142
2143
	/**
2144
	 * Retrieve payment subtotal
2145
	 *
2146
	 * @since  1.5
2147
	 * @access private
2148
	 *
2149
	 * @return float Payment subtotal
2150
	 */
2151
	private function get_subtotal() {
2152
		return apply_filters( 'give_get_payment_subtotal', $this->subtotal, $this->ID, $this );
2153
	}
2154
2155
	/**
2156
	 * Retrieve payment currency
2157
	 *
2158
	 * @since  1.5
2159
	 * @access private
2160
	 *
2161
	 * @return string Payment currency code
2162
	 */
2163
	private function get_currency() {
2164
		return apply_filters( 'give_payment_currency_code', $this->currency, $this->ID, $this );
2165
	}
2166
2167
	/**
2168
	 * Retrieve payment gateway
2169
	 *
2170
	 * @since  1.5
2171
	 * @access private
2172
	 *
2173
	 * @return string Gateway used
2174
	 */
2175
	private function get_gateway() {
2176
		return apply_filters( 'give_payment_gateway', $this->gateway, $this->ID, $this );
2177
	}
2178
2179
	/**
2180
	 * Retrieve payment transaction ID
2181
	 *
2182
	 * @since  1.5
2183
	 * @access private
2184
	 *
2185
	 * @return string Transaction ID from merchant processor
2186
	 */
2187
	private function get_transaction_id() {
2188
		return apply_filters( 'give_get_payment_transaction_id', $this->transaction_id, $this->ID, $this );
2189
	}
2190
2191
	/**
2192
	 * Retrieve payment IP
2193
	 *
2194
	 * @since  1.5
2195
	 * @access private
2196
	 *
2197
	 * @return string Payment IP address
2198
	 */
2199
	private function get_ip() {
2200
		return apply_filters( 'give_payment_user_ip', $this->ip, $this->ID, $this );
2201
	}
2202
2203
	/**
2204
	 * Retrieve payment customer ID
2205
	 *
2206
	 * @since  1.5
2207
	 * @access private
2208
	 *
2209
	 * @return int Payment customer ID
2210
	 */
2211
	private function get_customer_id() {
2212
		return apply_filters( 'give_payment_customer_id', $this->customer_id, $this->ID, $this );
2213
	}
2214
2215
	/**
2216
	 * Retrieve payment user ID
2217
	 *
2218
	 * @since  1.5
2219
	 * @access private
2220
	 *
2221
	 * @return int Payment user ID
2222
	 */
2223
	private function get_user_id() {
2224
		return apply_filters( 'give_payment_user_id', $this->user_id, $this->ID, $this );
2225
	}
2226
2227
	/**
2228
	 * Retrieve payment email
2229
	 *
2230
	 * @since  1.5
2231
	 * @access private
2232
	 *
2233
	 * @return string Payment customer email
2234
	 */
2235
	private function get_email() {
2236
		return apply_filters( 'give_payment_user_email', $this->email, $this->ID, $this );
2237
	}
2238
2239
	/**
2240
	 * Retrieve payment user info
2241
	 *
2242
	 * @since  1.5
2243
	 * @access private
2244
	 *
2245
	 * @return array Payment user info
2246
	 */
2247
	private function get_user_info() {
2248
		return apply_filters( 'give_payment_meta_user_info', $this->user_info, $this->ID, $this );
2249
	}
2250
2251
	/**
2252
	 * Retrieve payment billing address
2253
	 *
2254
	 * @since  1.5
2255
	 * @access private
2256
	 *
2257
	 * @return array Payment billing address
2258
	 */
2259
	private function get_address() {
2260
		return apply_filters( 'give_payment_address', $this->address, $this->ID, $this );
2261
	}
2262
2263
	/**
2264
	 * Retrieve payment key
2265
	 *
2266
	 * @since  1.5
2267
	 * @access private
2268
	 *
2269
	 * @return string Payment key
2270
	 */
2271
	private function get_key() {
2272
		return apply_filters( 'give_payment_key', $this->key, $this->ID, $this );
2273
	}
2274
2275
	/**
2276
	 * Retrieve payment form id
2277
	 *
2278
	 * @since  1.5
2279
	 * @access private
2280
	 *
2281
	 * @return string Payment form id
2282
	 */
2283
	private function get_form_id() {
2284
		return apply_filters( 'give_payment_form_id', $this->form_id, $this->ID, $this );
2285
	}
2286
2287
	/**
2288
	 * Retrieve payment number
2289
	 *
2290
	 * @since  1.5
2291
	 * @access private
2292
	 *
2293
	 * @return int|string Payment number
2294
	 */
2295
	private function get_number() {
2296
		return apply_filters( 'give_payment_number', $this->number, $this->ID, $this );
2297
	}
2298
2299
}
2300