PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.7.4
GiveWP – Donation Plugin and Fundraising Platform v2.7.4
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / payments / class-give-payment.php
give / includes / payments Last commit date
actions.php 6 years ago backward-compatibility.php 6 years ago class-give-payment.php 6 years ago class-give-sequential-donation-number.php 6 years ago class-payment-stats.php 6 years ago class-payments-query.php 6 years ago functions.php 6 years ago
class-give-payment.php
2095 lines
1 <?php
2 /**
3 * Payments
4 *
5 * @package Give
6 * @subpackage Classes/Give_Payment
7 * @copyright Copyright (c) 2016, GiveWP
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 $import
27 * @property string $key
28 * @property string $form_title
29 * @property string|int $form_id
30 * @property string|int $price_id
31 * @property string|int $total
32 * @property string|int $subtotal
33 * @property string|int $fees
34 * @property string|int $fees_total
35 * @property string $post_status
36 * @property string $date
37 * @property string $post_date
38 * @property string $status
39 * @property string $email
40 * @property array $payment_meta
41 * @property string $customer_id
42 * @property string $donor_id
43 * @property string $completed_date
44 * @property string $currency
45 * @property string $ip
46 * @property array $user_info
47 * @property string $gateway
48 * @property string $user_id
49 * @property string $title_prefix
50 * @property string $first_name
51 * @property string $last_name
52 * @property string $parent_payment
53 * @property string $transaction_id
54 * @property string $old_status
55 *
56 * @since 1.5
57 */
58 final class Give_Payment {
59
60 /**
61 * The Payment ID.
62 *
63 * @since 1.5
64 *
65 * @var int
66 */
67 public $ID = 0;
68
69 /**
70 * Protected non-read $_ID.
71 *
72 * @var int
73 */
74 protected $_ID = 0;
75
76 /**
77 * Identify if the payment is a new one or existing.
78 *
79 * @since 1.5
80 * @access protected
81 *
82 * @var boolean
83 */
84 protected $new = false;
85
86 /**
87 * The Payment number (for use with sequential payments).
88 *
89 * @since 1.5
90 * @access protected
91 *
92 * @var string
93 */
94 protected $number = '';
95
96 /**
97 * The Gateway mode the payment was made in.
98 *
99 * @since 1.5
100 * @access protected
101 *
102 * @var string
103 */
104 protected $mode = 'live';
105
106 /**
107 * Is donations is Import or not.
108 *
109 * @since 1.8.13
110 * @access protected
111 *
112 * @var bool
113 */
114 protected $import = false;
115
116 /**
117 * The unique donation payment key.
118 *
119 * @since 1.5
120 * @access protected
121 *
122 * @var string
123 */
124 protected $key = '';
125
126 /**
127 * The Donation Form Title
128 *
129 * @since 1.5
130 * @access protected
131 *
132 * @var string
133 */
134 protected $form_title = 0;
135
136 /**
137 * The Donation Form ID
138 *
139 * @since 1.5
140 * @access protected
141 *
142 * @var string
143 */
144 protected $form_id = 0;
145
146 /**
147 * The Donation Form Price ID
148 *
149 * @since 1.5
150 * @access protected
151 *
152 * @var string|int
153 */
154 protected $price_id = 0;
155
156 /**
157 * The total amount of the donation payment.
158 *
159 * @since 1.5
160 * @access protected
161 *
162 * @var float
163 */
164 protected $total = 0.00;
165
166 /**
167 * The Subtotal fo the payment.
168 *
169 * @since 1.5
170 * @access protected
171 *
172 * @var float
173 */
174 protected $subtotal = 0;
175
176 /**
177 * The date the payment was created
178 *
179 * @since 1.5
180 * @access protected
181 *
182 * @var string
183 */
184 protected $date = '';
185
186 /**
187 * The date the payment post was created.
188 *
189 * @var string
190 */
191 protected $post_date = '';
192
193 /**
194 * The date the payment was marked as 'complete'.
195 *
196 * @since 1.5
197 * @access protected
198 *
199 * @var string
200 */
201 protected $completed_date = '';
202
203 /**
204 * The status of the donation payment.
205 *
206 * @since 1.5
207 * @access protected
208 *
209 * @var string
210 */
211 protected $status = 'pending';
212
213 /**
214 * Donation Status.
215 *
216 * @var string
217 */
218 protected $post_status = 'pending'; // Same as $status but here for backwards compat.
219
220 /**
221 * When updating, the old status prior to the change
222 *
223 * @since 1.5
224 * @access protected
225 *
226 * @var string
227 */
228 protected $old_status = '';
229
230 /**
231 * The display name of the current payment status.
232 *
233 * @since 1.5
234 * @access protected
235 *
236 * @var string
237 */
238 protected $status_nicename = '';
239
240 /**
241 * The donor ID that made the payment.
242 *
243 * @since 1.5
244 * @access protected
245 *
246 * @var integer
247 */
248 protected $customer_id = null;
249
250 /**
251 * The Donor ID (if logged in) that made the payment
252 *
253 * @since 1.8.13
254 * @access protected
255 *
256 * @var integer
257 */
258 protected $donor_id = 0;
259
260 /**
261 * The User ID (if logged in) that made the payment
262 *
263 * @since 1.5
264 * @access protected
265 *
266 * @var integer
267 */
268 protected $user_id = 0;
269
270 /**
271 * The Title Prefix/Salutation of the Donor.
272 *
273 * @since 2.2
274 *
275 * @var string
276 */
277 protected $title_prefix = '';
278
279 /**
280 * The first name of the payee
281 *
282 * @since 1.5
283 * @access protected
284 *
285 * @var string
286 */
287 protected $first_name = '';
288
289 /**
290 * The last name of the payee
291 *
292 * @since 1.5
293 * @access protected
294 *
295 * @var string
296 */
297 protected $last_name = '';
298
299 /**
300 * The email used for the payment
301 *
302 * @since 1.5
303 * @access protected
304 *
305 * @var string
306 */
307 protected $email = '';
308
309 /**
310 * Legacy (not to be accessed) array of user information
311 *
312 * @since 1.5
313 * @access private
314 *
315 * @var array
316 */
317 private $user_info = array();
318
319 /**
320 * Legacy (not to be accessed) payment meta array
321 *
322 * @since 1.5
323 * @access private
324 *
325 * @var array
326 */
327 private $payment_meta = array();
328
329 /**
330 * The physical address used for the payment if provided
331 *
332 * @since 1.5
333 * @access protected
334 *
335 * @var array
336 */
337 protected $address = array();
338
339 /**
340 * The transaction ID returned by the gateway
341 *
342 * @since 1.5
343 * @access protected
344 *
345 * @var string
346 */
347 protected $transaction_id = '';
348
349 /**
350 * IP Address payment was made from
351 *
352 * @since 1.5
353 * @access protected
354 *
355 * @var string
356 */
357 protected $ip = '';
358
359 /**
360 * The gateway used to process the payment
361 *
362 * @since 1.5
363 * @access protected
364 *
365 * @var string
366 */
367 protected $gateway = '';
368
369 /**
370 * The the payment was made with
371 *
372 * @since 1.5
373 * @access protected
374 *
375 * @var string
376 */
377 protected $currency = '';
378
379 /**
380 * Array of items that have changed since the last save() was run.
381 * This is for internal use, to allow fewer update_payment_meta calls to be run.
382 *
383 * @since 1.5
384 * @access private
385 *
386 * @var array
387 */
388 private $pending;
389
390 /**
391 * The parent payment (if applicable)
392 *
393 * @since 1.5
394 * @access protected
395 *
396 * @var integer
397 */
398 protected $parent_payment = 0;
399
400 /**
401 * Setup the Give Payments class
402 *
403 * @since 1.5
404 * @access public
405 *
406 * @param int|bool $payment_id A given payment.
407 *
408 * @return mixed void|false
409 */
410 public function __construct( $payment_id = false ) {
411
412 if ( empty( $payment_id ) ) {
413 return false;
414 }
415
416 $this->setup_payment( $payment_id );
417 }
418
419 /**
420 * Magic GET function.
421 *
422 * @since 1.5
423 * @access public
424 *
425 * @param string $key The property.
426 *
427 * @return mixed The value.
428 */
429 public function __get( $key ) {
430
431 if ( method_exists( $this, 'get_' . $key ) ) {
432
433 $value = call_user_func( array( $this, 'get_' . $key ) );
434
435 } else {
436
437 $value = $this->$key;
438
439 }
440
441 return $value;
442 }
443
444 /**
445 * Magic SET function
446 *
447 * Sets up the pending array for the save method
448 *
449 * @since 1.5
450 * @access public
451 *
452 * @param string $key The property name.
453 * @param mixed $value The value of the property.
454 */
455 public function __set( $key, $value ) {
456 $ignore = array( '_ID' );
457
458 if ( 'status' === $key ) {
459 $this->old_status = $this->status;
460 }
461
462 if ( ! in_array( $key, $ignore ) ) {
463 $this->pending[ $key ] = $value;
464 }
465
466 if ( '_ID' !== $key ) {
467 $this->$key = $value;
468 }
469 }
470
471 /**
472 * Magic ISSET function, which allows empty checks on protected elements
473 *
474 * @since 1.5
475 * @access public
476 *
477 * @param string $name The attribute to get.
478 *
479 * @return boolean|null If the item is set or not
480 */
481 public function __isset( $name ) {
482 if ( property_exists( $this, $name ) ) {
483 return false === empty( $this->$name );
484 } else {
485 return null;
486 }
487 }
488
489 /**
490 * Setup payment properties
491 *
492 * @since 1.5
493 * @access private
494 *
495 * @param int $payment_id The payment ID.
496 *
497 * @return bool If the setup was successful or not
498 */
499 private function setup_payment( $payment_id ) {
500 $this->pending = array();
501
502 if ( empty( $payment_id ) ) {
503 return false;
504 }
505
506 $payment = get_post( absint( $payment_id ) );
507
508 if ( ! $payment || is_wp_error( $payment ) ) {
509 return false;
510 }
511
512 if ( 'give_payment' !== $payment->post_type ) {
513 return false;
514 }
515
516 Give_Payments_Query::update_meta_cache( array( $payment_id ) );
517
518 /**
519 * Fires before payment setup.
520 *
521 * Allow extensions to perform actions before the payment is loaded.
522 *
523 * @since 1.5
524 *
525 * @param Give_Payment $this Payment object.
526 * @param int $payment_id The ID of the payment.
527 */
528 do_action( 'give_pre_setup_payment', $this, $payment_id );
529
530 // Get payment from cache.
531 $donation_vars = Give_Cache::get_group( $payment_id, 'give-donations' );
532
533 if ( is_null( $donation_vars ) ) {
534 // Primary Identifier.
535 $this->ID = absint( $payment_id );
536
537 // Protected ID that can never be changed.
538 $this->_ID = absint( $payment_id );
539
540 // We have a payment, get the generic payment_meta item to reduce calls to it.
541 $this->payment_meta = $this->get_meta();
542
543 // Status and Dates.
544 $this->date = $payment->post_date;
545 $this->post_date = $payment->post_date;
546 $this->completed_date = $this->setup_completed_date();
547 $this->status = $payment->post_status;
548 $this->post_status = $this->status;
549 $this->mode = $this->setup_mode();
550 $this->import = $this->setup_import();
551 $this->parent_payment = $payment->post_parent;
552
553 $all_payment_statuses = give_get_payment_statuses();
554 $this->status_nicename = array_key_exists( $this->status, $all_payment_statuses ) ? $all_payment_statuses[ $this->status ] : ucfirst( $this->status );
555
556 // Currency Based.
557 $this->total = $this->setup_total();
558 $this->subtotal = $this->setup_subtotal();
559 $this->currency = $this->setup_currency();
560
561 // Gateway based.
562 $this->gateway = $this->setup_gateway();
563 $this->transaction_id = $this->setup_transaction_id();
564
565 // User based.
566 $this->ip = $this->setup_ip();
567 $this->customer_id = $this->setup_donor_id(); // Backward compatibility.
568 $this->donor_id = $this->setup_donor_id();
569 $this->user_id = $this->setup_user_id();
570 $this->email = $this->setup_email();
571 $this->user_info = $this->setup_user_info();
572 $this->address = $this->setup_address();
573 $this->first_name = $this->user_info['first_name'];
574 $this->last_name = $this->user_info['last_name'];
575 $this->title_prefix = isset( $this->user_info['title'] ) ? $this->user_info['title'] : '';
576
577 // Other Identifiers.
578 $this->form_title = $this->setup_form_title();
579 $this->form_id = $this->setup_form_id();
580 $this->price_id = $this->setup_price_id();
581 $this->key = $this->setup_payment_key();
582 $this->number = $this->setup_payment_number();
583
584 Give_Cache::set_group( $this->ID, get_object_vars( $this ), 'give-donations' );
585 } else {
586
587 foreach ( $donation_vars as $donation_var => $value ) {
588 $this->$donation_var = $value;
589 }
590 } // End if().
591
592 /**
593 * Fires after payment setup.
594 *
595 * Allow extensions to add items to this object via hook.
596 *
597 * @since 1.5
598 *
599 * @param Give_Payment $this Payment object.
600 * @param int $payment_id The ID of the payment.
601 */
602 do_action( 'give_setup_payment', $this, $payment_id );
603
604 return true;
605 }
606
607
608 /**
609 * Payment class object is storing various meta value in object parameter.
610 * So if user is updating payment meta but not updating payment object, then payment meta values will not reflect/changes on payment meta automatically
611 * 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.
612 * To prevent that user can use this function after updating any payment meta value ( in bulk or single update ).
613 *
614 * @since 1.6
615 * @access public
616 *
617 * @param int $payment_id Payment ID.
618 *
619 * @return void
620 */
621 public function update_payment_setup( $payment_id ) {
622 // Delete cache.
623 Give_Cache::delete_group( $this->ID, 'give-donations' );
624
625 $this->setup_payment( $payment_id );
626 }
627
628 /**
629 * Create the base of a payment.
630 *
631 * @since 1.5
632 * @access private
633 *
634 * @return int|bool False on failure, the payment ID on success.
635 */
636 private function insert_payment() {
637
638 // Construct the payment title.
639 $payment_title = '';
640 if ( ! empty( $this->first_name ) && ! empty( $this->last_name ) ) {
641 $payment_title = $this->first_name . ' ' . $this->last_name;
642 } elseif ( ! empty( $this->first_name ) && empty( $this->last_name ) ) {
643 $payment_title = $this->first_name;
644 } elseif ( ! empty( $this->email ) && is_email( $this->email ) ) {
645 $payment_title = $this->email;
646 }
647
648 // Set Key.
649 if ( empty( $this->key ) ) {
650
651 $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
652 $this->key = strtolower( md5( $this->email . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) ); // Unique key.
653 $this->pending['key'] = $this->key;
654 }
655
656 // Set IP.
657 if ( empty( $this->ip ) ) {
658
659 $this->ip = give_get_ip();
660 $this->pending['ip'] = $this->ip;
661
662 }
663
664 // @todo: payment data exist here only for backward compatibility
665 // issue: https://github.com/impress-org/give/issues/1132
666 $payment_data = array(
667 'price' => $this->total,
668 'date' => $this->date,
669 'user_email' => $this->email,
670 'purchase_key' => $this->key,
671 'form_title' => $this->form_title,
672 'form_id' => $this->form_id,
673 'donor_id' => $this->donor_id,
674 'price_id' => $this->price_id,
675 'currency' => $this->currency,
676 'user_info' => array(
677 'id' => $this->user_id,
678 'title' => $this->title_prefix,
679 'email' => $this->email,
680 'first_name' => $this->first_name,
681 'last_name' => $this->last_name,
682 'address' => $this->address,
683 ),
684 'status' => $this->status,
685 );
686
687 $args = apply_filters(
688 'give_insert_payment_args',
689 array(
690 'post_title' => $payment_title,
691 'post_status' => $this->status,
692 'post_type' => 'give_payment',
693 'post_date' => ! empty( $this->date ) ? $this->date : null,
694 'post_date_gmt' => ! empty( $this->date ) ? get_gmt_from_date( $this->date ) : null,
695 'post_parent' => $this->parent_payment,
696 ),
697 $payment_data
698 );
699
700 // Create a blank payment.
701 $payment_id = wp_insert_post( $args );
702
703 if ( ! empty( $payment_id ) ) {
704
705 $this->ID = $payment_id;
706 $this->_ID = $payment_id;
707
708 $donor = new stdClass();
709
710 if ( did_action( 'give_pre_process_donation' ) && is_user_logged_in() ) {
711 $donor = new Give_Donor( get_current_user_id(), true );
712
713 // Donor is logged in but used a different email to purchase with so assign to their donor record.
714 if ( ! empty( $donor->id ) && $this->email !== $donor->email ) {
715 $donor->add_email( $this->email );
716 }
717 }
718
719 if ( empty( $donor->id ) ) {
720 $donor = new Give_Donor( $this->email );
721 }
722
723 if ( empty( $donor->id ) ) {
724
725 $donor_data = array(
726 'name' => ! is_email( $payment_title ) ? $this->first_name . ' ' . $this->last_name : '',
727 'email' => $this->email,
728 'user_id' => $this->user_id,
729 );
730
731 $donor->create( $donor_data );
732
733 }
734
735 /**
736 * Filters the donor object after donation is completed but before donor table is updated.
737 *
738 * @since 1.8.13
739 * @since 2.4.2 Moved location of filter to occur after donor is hydrated.
740 *
741 * @param Give_Donor $donor Donor object.
742 * @param int $payment_id Payment ID.
743 * @param array $payment_data Payment data array.
744 * @param array $args Payment args.
745 */
746 $donor = apply_filters( 'give_update_donor_information', $donor, $payment_id, $payment_data, $args );
747
748 // Update Donor Meta once donor is created.
749 $donor->update_meta( '_give_donor_first_name', $this->first_name );
750 $donor->update_meta( '_give_donor_last_name', $this->last_name );
751 $donor->update_meta( '_give_donor_title_prefix', $this->title_prefix );
752
753 $this->customer_id = $donor->id;
754 $this->pending['customer_id'] = $this->customer_id;
755 $donor->attach_payment( $this->ID, false );
756
757 $this->payment_meta = apply_filters( 'give_payment_meta', $this->payment_meta, $payment_data );
758
759 /**
760 * _give_payment_meta backward compatibility.
761 *
762 * @since 2.0.1
763 */
764 $custom_payment_meta = array_diff(
765 array_map( 'maybe_serialize', $this->payment_meta ),
766 array_map( 'maybe_serialize', $payment_data )
767 );
768
769 if ( ! empty( $custom_payment_meta ) ) {
770 give_doing_it_wrong( '_give_payment_meta', __( 'This custom meta key has been deprecated for performance reasons. Your custom meta data will still be stored but we recommend updating your code to store meta keys individually from GiveWP 2.0.0.', 'give' ) );
771
772 $this->update_meta( '_give_payment_meta', array_map( 'maybe_unserialize', $custom_payment_meta ) );
773 }
774
775 $give_company = ( ! empty( $_REQUEST['give_company_name'] ) ? give_clean( $_REQUEST['give_company_name'] ) : '' );
776
777 // Check $page_url is not empty.
778 if ( $give_company ) {
779 give_update_meta( $payment_id, '_give_donation_company', $give_company );
780
781 $donor_id = absint( $donor->id );
782 if ( ! empty( $donor_id ) ) {
783 Give()->donor_meta->update_meta( $donor_id, '_give_donor_company', $give_company );
784 }
785 }
786
787 $this->new = true;
788 } // End if().
789
790 return $this->ID;
791
792 }
793
794 /**
795 * Save
796 *
797 * Once items have been set, an update is needed to save them to the database.
798 *
799 * @access public
800 *
801 * @return bool True of the save occurred, false if it failed or wasn't needed
802 */
803 public function save() {
804 $saved = false;
805
806 // Must have an ID.
807 if ( empty( $this->ID ) ) {
808
809 $payment_id = $this->insert_payment();
810
811 if ( false === $payment_id ) {
812 $saved = false;
813 } else {
814 $this->ID = $payment_id;
815 }
816 }
817
818 // Set ID if not matching.
819 if ( $this->ID !== $this->_ID ) {
820 $this->ID = $this->_ID;
821 }
822
823 // If we have something pending, let's save it.
824 if ( ! empty( $this->pending ) ) {
825
826 $total_increase = 0;
827 $total_decrease = 0;
828
829 foreach ( $this->pending as $key => $value ) {
830
831 switch ( $key ) {
832
833 case 'donations':
834 // Update totals for pending donations.
835 foreach ( $this->pending[ $key ] as $item ) {
836
837 $quantity = isset( $item['quantity'] ) ? $item['quantity'] : 1;
838 $price_id = isset( $item['price_id'] ) ? $item['price_id'] : 0;
839
840 switch ( $item['action'] ) {
841
842 case 'add':
843 $price = $item['price'];
844
845 if ( 'publish' === $this->status || 'complete' === $this->status ) {
846
847 // Add donation to logs.
848 $log_date = date_i18n( 'Y-m-d G:i:s', current_time( 'timestamp' ) );
849 give_record_donation_in_log( $item['id'], $this->ID, $price_id, $log_date );
850
851 $form = new Give_Donate_Form( $item['id'] );
852 $form->increase_sales( $quantity );
853 $form->increase_earnings( $price, $this->ID );
854
855 $total_increase += $price;
856 }
857 break;
858
859 case 'remove':
860 $this->delete_sales_logs();
861 if ( 'publish' === $this->status || 'complete' === $this->status ) {
862 $form = new Give_Donate_Form( $item['id'] );
863 $form->decrease_sales( $quantity );
864 $form->decrease_earnings( $item['amount'], $this->ID );
865
866 $total_decrease += $item['amount'];
867 }
868 break;
869
870 }// End switch().
871 }// End foreach().
872 break;
873
874 case 'status':
875 $this->update_status( $this->status );
876 break;
877
878 case 'gateway':
879 $this->update_meta( '_give_payment_gateway', $this->gateway );
880 break;
881
882 case 'mode':
883 $this->update_meta( '_give_payment_mode', $this->mode );
884 break;
885
886 case 'transaction_id':
887 $this->update_meta( '_give_payment_transaction_id', $this->transaction_id );
888 break;
889
890 case 'ip':
891 $this->update_meta( '_give_payment_donor_ip', $this->ip );
892 break;
893
894 case 'customer_id':
895 $this->update_meta( '_give_payment_donor_id', $this->customer_id );
896 break;
897
898 case 'form_title':
899 $this->update_meta( '_give_payment_form_title', $this->form_title );
900 break;
901
902 case 'form_id':
903 $this->update_meta( '_give_payment_form_id', $this->form_id );
904 break;
905
906 case 'price_id':
907 $this->update_meta( '_give_payment_price_id', $this->price_id );
908 break;
909
910 case 'first_name':
911 $this->update_meta( '_give_donor_billing_first_name', $this->first_name );
912 break;
913
914 case 'last_name':
915 $this->update_meta( '_give_donor_billing_last_name', $this->last_name );
916 break;
917
918 case 'currency':
919 $this->update_meta( '_give_payment_currency', $this->currency );
920 break;
921
922 case 'address':
923 if ( ! empty( $this->address ) ) {
924 foreach ( $this->address as $address_name => $address ) {
925 switch ( $address_name ) {
926 case 'line1':
927 $this->update_meta( '_give_donor_billing_address1', $address );
928 break;
929
930 case 'line2':
931 $this->update_meta( '_give_donor_billing_address2', $address );
932 break;
933
934 default:
935 $this->update_meta( "_give_donor_billing_{$address_name}", $address );
936 }
937 }
938 }
939 break;
940
941 case 'email':
942 $this->update_meta( '_give_payment_donor_email', $this->email );
943 break;
944
945 case 'title_prefix':
946 $this->update_meta( '_give_payment_donor_title_prefix', $this->title_prefix );
947 break;
948
949 case 'key':
950 $this->update_meta( '_give_payment_purchase_key', $this->key );
951 break;
952
953 case 'number':
954 // @todo: remove unused meta data.
955 // Core is using post_title to store donation serial code ( fi enabled ) instead this meta key.
956 // Do not use this meta key in your logic, can be remove in future
957 $this->update_meta( '_give_payment_number', $this->number );
958 break;
959
960 case 'date':
961 $args = array(
962 'ID' => $this->ID,
963 'post_date' => date( 'Y-m-d H:i:s', strtotime( $this->date ) ),
964 'post_date_gmt' => get_gmt_from_date( $this->date ),
965 'edit_date' => true,
966 );
967
968 wp_update_post( $args );
969 break;
970
971 case 'completed_date':
972 $this->update_meta( '_give_completed_date', $this->completed_date );
973 break;
974
975 case 'parent_payment':
976 $args = array(
977 'ID' => $this->ID,
978 'post_parent' => $this->parent_payment,
979 );
980
981 wp_update_post( $args );
982 break;
983
984 case 'total':
985 $this->update_meta( '_give_payment_total', give_sanitize_amount_for_db( $this->total ) );
986 break;
987
988 default:
989 /**
990 * Fires while saving payment.
991 *
992 * @since 1.7
993 *
994 * @param Give_Payment $this Payment object.
995 */
996 do_action( 'give_payment_save', $this, $key );
997 break;
998 } // End switch().
999 } // End foreach().
1000
1001 if ( 'pending' !== $this->status ) {
1002
1003 $donor = new Give_Donor( $this->customer_id );
1004
1005 $total_change = $total_increase - $total_decrease;
1006 if ( $total_change < 0 ) {
1007
1008 $total_change = - ( $total_change );
1009
1010 // Decrease the donor's donation stats.
1011 $donor->decrease_value( $total_change );
1012 give_decrease_total_earnings( $total_change );
1013
1014 $donor->decrease_donation_count();
1015
1016 } elseif ( $total_change > 0 ) {
1017
1018 // Increase the donor's donation stats.
1019 $donor->increase_value( $total_change );
1020 give_increase_total_earnings( $total_change );
1021
1022 $donor->increase_purchase_count();
1023
1024 }
1025
1026 // Verify and update form meta based on the form status.
1027 give_set_form_closed_status( $this->form_id );
1028 }
1029
1030 $this->pending = array();
1031 $saved = true;
1032 } // End if().
1033
1034 if ( true === $saved ) {
1035 $this->setup_payment( $this->ID );
1036 }
1037
1038 return $saved;
1039 }
1040
1041 /**
1042 * Add a donation to a given payment
1043 *
1044 * @since 1.5
1045 * @access public
1046 *
1047 * @param int $form_id The donation form to add.
1048 * @param array $args Other arguments to pass to the function.
1049 * @param array $options List of donation options.
1050 *
1051 * @return bool True when successful, false otherwise
1052 */
1053 public function add_donation( $form_id = 0, $args = array(), $options = array() ) {
1054
1055 $donation = new Give_Donate_Form( $form_id );
1056
1057 // Bail if this post isn't a give donation form.
1058 if ( ! $donation || 'give_forms' !== $donation->post_type ) {
1059 return false;
1060 }
1061
1062 // Set some defaults.
1063 $defaults = array(
1064 'price' => false,
1065 'price_id' => false,
1066 );
1067
1068 $args = wp_parse_args( apply_filters( 'give_payment_add_donation_args', $args, $donation->ID ), $defaults );
1069
1070 // Allow overriding the price.
1071 if ( false !== $args['price'] ) {
1072 $donation_amount = $args['price'];
1073 } else {
1074
1075 // Deal with variable pricing.
1076 if ( give_has_variable_prices( $donation->ID ) ) {
1077 $prices = give_get_meta( $form_id, '_give_donation_levels', true );
1078 $donation_amount = '';
1079
1080 // Loop through prices.
1081 foreach ( $prices as $price ) {
1082 // Find a match between price_id and level_id.
1083 // First verify array keys exists THEN make the match.
1084 if (
1085 isset( $args['price_id'] ) &&
1086 isset( $price['_give_id']['level_id'] ) &&
1087 $args['price_id'] === (int) $price['_give_id']['level_id']
1088 ) {
1089 $donation_amount = $price['_give_amount'];
1090 }
1091 }
1092
1093 // Fallback to the lowest price point.
1094 if ( '' === $donation_amount ) {
1095 $donation_amount = give_get_lowest_price_option( $donation->ID );
1096 $args['price_id'] = give_get_lowest_price_id( $donation->ID );
1097 }
1098 } else {
1099 // Simple form price.
1100 $donation_amount = give_get_form_price( $donation->ID );
1101 }
1102 }
1103
1104 // Sanitizing the price here so we don't have a dozen calls later.
1105 $donation_amount = give_maybe_sanitize_amount( $donation_amount );
1106 $total = round( $donation_amount, give_get_price_decimals( $this->ID ) );
1107
1108 // Add Options.
1109 $default_options = array();
1110 if ( false !== $args['price_id'] ) {
1111 $default_options['price_id'] = (int) $args['price_id'];
1112 }
1113 $options = wp_parse_args( $options, $default_options );
1114
1115 // Do not allow totals to go negative.
1116 if ( $total < 0 ) {
1117 $total = 0;
1118 }
1119
1120 $donation = array(
1121 'name' => $donation->post_title,
1122 'id' => $donation->ID,
1123 'price' => round( $total, give_get_price_decimals( $this->ID ) ),
1124 'subtotal' => round( $total, give_get_price_decimals( $this->ID ) ),
1125 'price_id' => $args['price_id'],
1126 'action' => 'add',
1127 'options' => $options,
1128 );
1129
1130 $this->pending['donations'][] = $donation;
1131
1132 $this->increase_subtotal( $total );
1133
1134 return true;
1135
1136 }
1137
1138 /**
1139 * Remove a donation from the payment
1140 *
1141 * @since 1.5
1142 * @access public
1143 *
1144 * @param int $form_id The form ID to remove.
1145 * @param array $args Arguments to pass to identify (quantity, amount, price_id).
1146 *
1147 * @return bool If the item was removed or not
1148 */
1149 public function remove_donation( $form_id, $args = array() ) {
1150
1151 // Set some defaults.
1152 $defaults = array(
1153 'quantity' => 1,
1154 'price' => false,
1155 'price_id' => false,
1156 );
1157 $args = wp_parse_args( $args, $defaults );
1158
1159 $form = new Give_Donate_Form( $form_id );
1160
1161 // Bail if this post isn't a valid give donation form.
1162 if ( ! $form || 'give_forms' !== $form->post_type ) {
1163 return false;
1164 }
1165
1166 $pending_args = $args;
1167 $pending_args['id'] = $form_id;
1168 $pending_args['amount'] = $this->total;
1169 $pending_args['price_id'] = false !== $args['price_id'] ? (int) $args['price_id'] : false;
1170 $pending_args['quantity'] = $args['quantity'];
1171 $pending_args['action'] = 'remove';
1172
1173 $this->pending['donations'][] = $pending_args;
1174
1175 $this->decrease_subtotal( $this->total );
1176
1177 return true;
1178 }
1179
1180
1181 /**
1182 * Add a note to a payment
1183 *
1184 * @since 1.5
1185 * @access public
1186 *
1187 * @param string|bool $note The note to add.
1188 *
1189 * @return bool If the note was specified or not
1190 */
1191 public function add_note( $note = false ) {
1192 // Bail if no note specified.
1193 if ( ! $note ) {
1194 return false;
1195 }
1196
1197 give_insert_payment_note( $this->ID, $note );
1198 }
1199
1200 /**
1201 * Increase the payment's subtotal
1202 *
1203 * @since 1.5
1204 * @access private
1205 *
1206 * @param float $amount The amount to increase the payment subtotal by.
1207 *
1208 * @return void
1209 */
1210 private function increase_subtotal( $amount = 0.00 ) {
1211 $amount = (float) $amount;
1212 $this->subtotal += $amount;
1213
1214 $this->recalculate_total();
1215 }
1216
1217 /**
1218 * Decrease the payment's subtotal.
1219 *
1220 * @since 1.5
1221 * @access private
1222 *
1223 * @param float $amount The amount to decrease the payment subtotal by.
1224 *
1225 * @return void
1226 */
1227 private function decrease_subtotal( $amount = 0.00 ) {
1228 $amount = (float) $amount;
1229 $this->subtotal -= $amount;
1230
1231 if ( $this->subtotal < 0 ) {
1232 $this->subtotal = 0;
1233 }
1234
1235 $this->recalculate_total();
1236 }
1237
1238 /**
1239 * Set or update the total for a payment.
1240 *
1241 * @since 1.5
1242 * @since 2.1.4 reset total in pending property
1243 * @access private
1244 *
1245 * @return void
1246 */
1247 private function recalculate_total() {
1248 $this->pending['total'] = $this->total = $this->subtotal;
1249 }
1250
1251 /**
1252 * Set the payment status and run any status specific changes necessary.
1253 *
1254 * @since 1.5
1255 * @access public
1256 *
1257 * @param string|bool $status The status to set the payment to.
1258 *
1259 * @return bool $updated Returns if the status was successfully updated.
1260 */
1261 public function update_status( $status = false ) {
1262
1263 // standardize the 'complete(d)' status.
1264 if ( 'completed' === $status || 'complete' === $status ) {
1265 $status = 'publish';
1266 }
1267
1268 $old_status = ! empty( $this->old_status ) ? $this->old_status : false;
1269
1270 if ( $old_status === $status ) {
1271 return false; // Don't permit status changes that aren't changes.
1272 }
1273
1274 $do_change = apply_filters( 'give_should_update_payment_status', true, $this->ID, $status, $old_status );
1275
1276 $updated = false;
1277
1278 if ( $do_change ) {
1279
1280 /**
1281 * Fires before changing payment status.
1282 *
1283 * @since 1.5
1284 *
1285 * @param int $payment_id Payments ID.
1286 * @param string $status The new status.
1287 * @param string $old_status The old status.
1288 */
1289 do_action( 'give_before_payment_status_change', $this->ID, $status, $old_status );
1290
1291 $update_fields = array(
1292 'ID' => $this->ID,
1293 'post_status' => $status,
1294 'edit_date' => current_time( 'mysql' ),
1295 );
1296
1297 $updated = wp_update_post( apply_filters( 'give_update_payment_status_fields', $update_fields ) );
1298
1299 $all_payment_statuses = give_get_payment_statuses();
1300 $this->status_nicename = array_key_exists( $status, $all_payment_statuses ) ? $all_payment_statuses[ $status ] : ucfirst( $status );
1301
1302 // Process any specific status functions.
1303 $this->process_status( $status );
1304
1305 /**
1306 * Fires after changing payment status.
1307 *
1308 * @since 1.5
1309 *
1310 * @param int $payment_id Payment ID.
1311 * @param string $status The new status.
1312 * @param string $old_status The old status.
1313 */
1314 do_action( 'give_update_payment_status', $this->ID, $status, $old_status );
1315
1316 } // End if().
1317
1318 return $updated;
1319
1320 }
1321
1322 /**
1323 * Change the status of the payment to refunded, and run the necessary changes
1324 *
1325 * @since 1.5
1326 * @access public
1327 *
1328 * @return void
1329 */
1330 public function refund() {
1331 $this->old_status = $this->status;
1332 $this->status = 'refunded';
1333 $this->pending['status'] = $this->status;
1334
1335 $this->save();
1336 }
1337
1338 /**
1339 * Get a post meta item for the payment
1340 *
1341 * @since 1.5
1342 * @access public
1343 *
1344 * @param string $meta_key The Meta Key.
1345 * @param boolean $single Return single item or array.
1346 *
1347 * @return mixed The value from the post meta
1348 */
1349 public function get_meta( $meta_key = '_give_payment_meta', $single = true ) {
1350 if (
1351 ! has_filter( 'get_post_metadata', 'give_bc_v20_get_payment_meta' ) &&
1352 ! doing_filter( 'get_post_metadata' )
1353 ) {
1354 add_filter( 'get_post_metadata', 'give_bc_v20_get_payment_meta', 999, 4 );
1355 }
1356
1357 $meta = give_get_meta( $this->ID, $meta_key, $single );
1358
1359 /**
1360 * Filter the specific meta key value.
1361 *
1362 * @since 1.5
1363 */
1364 $meta = apply_filters( "give_get_payment_meta_{$meta_key}", $meta, $this->ID );
1365
1366 // Security check.
1367 if ( is_serialized( $meta ) ) {
1368 preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $meta, $matches );
1369 if ( ! empty( $matches ) ) {
1370 $meta = array();
1371 }
1372 }
1373
1374 /**
1375 * Filter the all meta keys.
1376 *
1377 * @since 1.5
1378 */
1379 return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1380 }
1381
1382 /**
1383 * Update the post meta
1384 *
1385 * @since 1.5
1386 * @access public
1387 *
1388 * @param string $meta_key The meta key to update.
1389 * @param string $meta_value The meta value.
1390 * @param string $prev_value Previous meta value.
1391 *
1392 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure
1393 */
1394 public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1395 if ( empty( $meta_key ) ) {
1396 return false;
1397 }
1398
1399 /**
1400 * Filter the single meta key while updating
1401 *
1402 * @since 1.5
1403 */
1404 $meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1405
1406 return give_update_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1407 }
1408
1409 /**
1410 * Process Donation Status.
1411 *
1412 * @param string $status Donation Status.
1413 *
1414 * @since 2.0.2
1415 * @access private
1416 *
1417 * @return void
1418 */
1419 private function process_status( $status ) {
1420 $process = true;
1421
1422 // Bailout, if changed from completed to preapproval/processing.
1423 // Bailout, if current status = previous status or status is publish.
1424 if (
1425 'preapproval' === $status ||
1426 'processing' === $status ||
1427 'publish' !== $this->old_status ||
1428 $status !== $this->status
1429 ) {
1430 $process = false;
1431 }
1432
1433 // Allow extensions to filter for their own payment types, Example: Recurring Payments.
1434 $process = apply_filters( "give_should_process_{$status}", $process, $this );
1435
1436 if ( false === $process ) {
1437 return;
1438 }
1439
1440 /**
1441 * Fires before processing donation status.
1442 *
1443 * @param Give_Payment $this Payment object.
1444 *
1445 * @since 1.5
1446 */
1447 do_action( "give_pre_{$status}_payment", $this );
1448
1449 $decrease_earnings = apply_filters( "give_decrease_earnings_on_{$status}", true, $this );
1450 $decrease_donor_value = apply_filters( "give_decrease_donor_value_on_{$status}", true, $this );
1451 $decrease_donation_count = apply_filters( "give_decrease_donors_donation_count_on_{$status}", true, $this );
1452
1453 $this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1454 $this->delete_sales_logs();
1455
1456 // @todo: Refresh only range related stat cache
1457 give_delete_donation_stats();
1458
1459 /**
1460 * Fires after processing donation status.
1461 *
1462 * @param Give_Payment $this Payment object.
1463 *
1464 * @since 1.5
1465 */
1466 do_action( "give_post_{$status}_payment", $this );
1467 }
1468
1469 /**
1470 * Used during the process of moving to refunded or pending, to decrement stats
1471 *
1472 * @since 1.5
1473 * @access private
1474 *
1475 * @param bool $alter_store_earnings If the method should alter the store earnings.
1476 * @param bool $alter_customer_value If the method should reduce the donor value.
1477 * @param bool $alter_customer_purchase_count If the method should reduce the donor's purchase count.
1478 *
1479 * @return void
1480 */
1481 private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1482
1483 give_undo_donation( $this->ID );
1484
1485 // Decrease store earnings.
1486 if ( true === $alter_store_earnings ) {
1487 give_decrease_total_earnings( $this->total );
1488 }
1489
1490 // Decrement the stats for the donor.
1491 if ( ! empty( $this->customer_id ) ) {
1492
1493 $donor = new Give_Donor( $this->customer_id );
1494
1495 if ( true === $alter_customer_value ) {
1496 $donor->decrease_value( $this->total );
1497 }
1498
1499 if ( true === $alter_customer_purchase_count ) {
1500 $donor->decrease_donation_count();
1501 }
1502 }
1503
1504 }
1505
1506 /**
1507 * Delete sales logs for this donation
1508 *
1509 * @since 1.5
1510 * @access private
1511 *
1512 * @return void
1513 */
1514 private function delete_sales_logs() {
1515 // Remove related sale log entries.
1516 Give()->logs->delete_logs( $this->ID );
1517 }
1518
1519 /**
1520 * Setup functions only, these are not to be used by developers.
1521 * These functions exist only to allow the setup routine to be backwards compatible with our old
1522 * helper functions.
1523 *
1524 * These will run whenever setup_payment is called, which should only be called once.
1525 * To update an attribute, update it directly instead of re-running the setup routine
1526 */
1527
1528 /**
1529 * Setup the payment completed date
1530 *
1531 * @since 1.5
1532 * @access private
1533 *
1534 * @return string The date the payment was completed
1535 */
1536 private function setup_completed_date() {
1537 $payment = get_post( $this->ID );
1538
1539 if ( 'pending' === $payment->post_status || 'preapproved' === $payment->post_status ) {
1540 return false; // This payment was never completed.
1541 }
1542
1543 $date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1544
1545 return $date;
1546 }
1547
1548 /**
1549 * Setup the payment mode
1550 *
1551 * @since 1.5
1552 * @access private
1553 *
1554 * @return string The payment mode
1555 */
1556 private function setup_mode() {
1557 return $this->get_meta( '_give_payment_mode' );
1558 }
1559
1560 /**
1561 * Setup the payment import data
1562 *
1563 * @since 1.8.13
1564 * @access private
1565 *
1566 * @return bool The payment import
1567 */
1568 private function setup_import() {
1569 return (bool) $this->get_meta( '_give_payment_import' );
1570 }
1571
1572 /**
1573 * Setup the payment total
1574 *
1575 * @since 1.5
1576 * @access private
1577 *
1578 * @return float The payment total
1579 */
1580 private function setup_total() {
1581 $amount = $this->get_meta( '_give_payment_total', true );
1582
1583 return round( floatval( $amount ), give_get_price_decimals( $this->ID ) );
1584 }
1585
1586 /**
1587 * Setup the payment subtotal
1588 *
1589 * @since 1.5
1590 * @access private
1591 *
1592 * @return float The subtotal of the payment
1593 */
1594 private function setup_subtotal() {
1595 $subtotal = $this->total;
1596
1597 return $subtotal;
1598 }
1599
1600 /**
1601 * Setup the currency code
1602 *
1603 * @since 1.5
1604 * @since 2.0 Set currency from _give_payment_currency meta key
1605 * @access private
1606 *
1607 * @return string The currency for the payment
1608 */
1609 private function setup_currency() {
1610 $currency = $this->get_meta( '_give_payment_currency', true );
1611 $currency = ! empty( $currency ) ?
1612 $currency :
1613 /**
1614 * Filter the default donation currency
1615 *
1616 * @since 1.5
1617 */
1618 apply_filters(
1619 'give_payment_currency_default',
1620 give_get_currency( $this->form_id, $this ),
1621 $this
1622 );
1623
1624 return $currency;
1625 }
1626
1627 /**
1628 * Setup the gateway used for the payment
1629 *
1630 * @since 1.5
1631 * @access private
1632 *
1633 * @return string The gateway
1634 */
1635 private function setup_gateway() {
1636 $gateway = $this->get_meta( '_give_payment_gateway', true );
1637
1638 return $gateway;
1639 }
1640
1641 /**
1642 * Setup the donation ID
1643 *
1644 * @since 1.5
1645 * @access private
1646 *
1647 * @return string The donation ID
1648 */
1649 private function setup_transaction_id() {
1650 $transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1651
1652 if ( empty( $transaction_id ) ) {
1653 $gateway = $this->gateway;
1654 $transaction_id = apply_filters( "give_get_payment_transaction_id-{$gateway}", $this->ID );
1655 }
1656
1657 return $transaction_id;
1658 }
1659
1660 /**
1661 * Setup the IP Address for the payment
1662 *
1663 * @since 1.5
1664 * @since 2.0 Set ip address from _give_payment_donor_ip meta key
1665 * @access private
1666 *
1667 * @return string The IP address for the payment
1668 */
1669 private function setup_ip() {
1670 $ip = $this->get_meta( '_give_payment_donor_ip', true );
1671
1672 return $ip;
1673 }
1674
1675 /**
1676 * Setup the donor ID.
1677 *
1678 * @since 1.5
1679 * @since 2.0 Set id from _give_payment_donor_id meta key
1680 * @access private
1681 *
1682 * @return int The Donor ID.
1683 */
1684 private function setup_donor_id() {
1685 $donor_id = $this->get_meta( '_give_payment_donor_id', true );
1686
1687 return $donor_id;
1688 }
1689
1690 /**
1691 * Setup the User ID associated with the donation
1692 *
1693 * @since 1.5
1694 * @since 2.0 Get user id connect to donor from donor table instead of payment meta.
1695 *
1696 * @access private
1697 *
1698 * @return int The User ID
1699 */
1700 private function setup_user_id() {
1701
1702 $donor = Give()->donors->get_donor_by( 'id', $this->donor_id );
1703 $user_id = $donor ? absint( $donor->user_id ) : 0;
1704
1705 return $user_id;
1706 }
1707
1708 /**
1709 * Setup the email address for the donation.
1710 *
1711 * @since 1.5
1712 * @since 2.0 Set email from _give_payment_donor_email meta key
1713 *
1714 * @access private
1715 *
1716 * @return string The email address for the payment.
1717 */
1718 private function setup_email() {
1719 $email = $this->get_meta( '_give_payment_donor_email', true );
1720
1721 if ( empty( $email ) && $this->customer_id ) {
1722 $email = Give()->donors->get_column( 'email', $this->customer_id );
1723 }
1724
1725 return $email;
1726 }
1727
1728 /**
1729 * Setup the user info.
1730 *
1731 * @since 1.5
1732 * @access private
1733 *
1734 * @return array The user info associated with the payment.
1735 */
1736 private function setup_user_info() {
1737 $defaults = array(
1738 'title' => $this->title_prefix,
1739 'first_name' => $this->first_name,
1740 'last_name' => $this->last_name,
1741 );
1742
1743 $user_info = isset( $this->payment_meta['user_info'] ) ? $this->payment_meta['user_info'] : array();
1744
1745 if ( is_serialized( $user_info ) ) {
1746 preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $user_info, $matches );
1747 if ( ! empty( $matches ) ) {
1748 $user_info = array();
1749 }
1750 }
1751
1752 $user_info = wp_parse_args( $user_info, $defaults );
1753
1754 if ( empty( $user_info ) ) {
1755 // Get the donor, but only if it's been created.
1756 $donor = new Give_Donor( $this->customer_id );
1757
1758 if ( $donor->id > 0 ) {
1759 $user_info = array(
1760 'first_name' => $donor->get_first_name(),
1761 'last_name' => $donor->get_last_name(),
1762 'email' => $donor->email,
1763 'discount' => 'none',
1764 );
1765 }
1766 } else {
1767 // Get the donor, but only if it's been created.
1768 $donor = new Give_Donor( $this->customer_id );
1769
1770 if ( $donor->id > 0 ) {
1771 foreach ( $user_info as $key => $value ) {
1772 if ( ! empty( $value ) ) {
1773 continue;
1774 }
1775
1776 switch ( $key ) {
1777 case 'title':
1778 $user_info[ $key ] = Give()->donor_meta->get_meta( $donor->id, '_give_donor_title_prefix', true );
1779 break;
1780
1781 case 'first_name':
1782 $user_info[ $key ] = $donor->get_first_name();
1783 break;
1784
1785 case 'last_name':
1786 $user_info[ $key ] = $donor->get_last_name();
1787 break;
1788
1789 case 'email':
1790 $user_info[ $key ] = $donor->email;
1791 break;
1792 }
1793 }
1794 }
1795 }// End if().
1796
1797 return $user_info;
1798
1799 }
1800
1801 /**
1802 * Setup the Address for the payment.
1803 *
1804 * @since 1.5
1805 * @access private
1806 *
1807 * @return array The Address information for the payment.
1808 */
1809 private function setup_address() {
1810 $address['line1'] = give_get_meta( $this->ID, '_give_donor_billing_address1', true, '' );
1811 $address['line2'] = give_get_meta( $this->ID, '_give_donor_billing_address2', true, '' );
1812 $address['city'] = give_get_meta( $this->ID, '_give_donor_billing_city', true, '' );
1813 $address['state'] = give_get_meta( $this->ID, '_give_donor_billing_state', true, '' );
1814 $address['zip'] = give_get_meta( $this->ID, '_give_donor_billing_zip', true, '' );
1815 $address['country'] = give_get_meta( $this->ID, '_give_donor_billing_country', true, '' );
1816
1817 return $address;
1818 }
1819
1820 /**
1821 * Setup the form title.
1822 *
1823 * @since 1.5
1824 * @access private
1825 *
1826 * @return string The Form Title.
1827 */
1828 private function setup_form_title() {
1829
1830 $form_id = $this->get_meta( '_give_payment_form_title', true );
1831
1832 return $form_id;
1833 }
1834
1835 /**
1836 * Setup the form ID.
1837 *
1838 * @since 1.5
1839 * @access private
1840 *
1841 * @return int The Form ID
1842 */
1843 private function setup_form_id() {
1844
1845 $form_id = $this->get_meta( '_give_payment_form_id', true );
1846
1847 return $form_id;
1848 }
1849
1850 /**
1851 * Setup the price ID.
1852 *
1853 * @since 1.5
1854 * @access private
1855 *
1856 * @return int The Form Price ID.
1857 */
1858 private function setup_price_id() {
1859 $price_id = $this->get_meta( '_give_payment_price_id', true );
1860
1861 return $price_id;
1862 }
1863
1864 /**
1865 * Setup the payment key.
1866 *
1867 * @since 1.5
1868 * @access private
1869 *
1870 * @return string The Payment Key.
1871 */
1872 private function setup_payment_key() {
1873 $key = $this->get_meta( '_give_payment_purchase_key', true );
1874
1875 return $key;
1876 }
1877
1878 /**
1879 * Setup the payment number.
1880 *
1881 * @since 1.5
1882 * @access private
1883 *
1884 * @return int|string Integer by default, or string if sequential order numbers is enabled.
1885 */
1886 private function setup_payment_number() {
1887 return $this->get_serial_code();
1888 }
1889
1890 /**
1891 * Converts this object into an array for special cases.
1892 *
1893 * @access public
1894 *
1895 * @return array The payment object as an array.
1896 */
1897 public function array_convert() {
1898 return get_object_vars( $this );
1899 }
1900
1901
1902 /**
1903 * Flag to check if donation is completed or not.
1904 *
1905 * @since 1.8
1906 * @access public
1907 *
1908 * @return bool
1909 */
1910 public function is_completed() {
1911 return ( 'publish' === $this->status && $this->completed_date );
1912 }
1913
1914 /**
1915 * Retrieve payment completion date.
1916 *
1917 * @since 1.5
1918 * @access private
1919 *
1920 * @return string Date payment was completed.
1921 */
1922 private function get_completed_date() {
1923 return apply_filters( 'give_payment_completed_date', $this->completed_date, $this->ID, $this );
1924 }
1925
1926 /**
1927 * Retrieve payment subtotal.
1928 *
1929 * @since 1.5
1930 * @access private
1931 *
1932 * @return float Payment subtotal.
1933 */
1934 private function get_subtotal() {
1935 return apply_filters( 'give_get_payment_subtotal', $this->subtotal, $this->ID, $this );
1936 }
1937
1938 /**
1939 * Retrieve payment currency.
1940 *
1941 * @since 1.5
1942 * @access private
1943 *
1944 * @return string Payment currency code.
1945 */
1946 private function get_currency() {
1947 return apply_filters( 'give_payment_currency_code', $this->currency, $this->ID, $this );
1948 }
1949
1950 /**
1951 * Retrieve payment gateway.
1952 *
1953 * @since 1.5
1954 * @access private
1955 *
1956 * @return string Gateway used.
1957 */
1958 private function get_gateway() {
1959 return apply_filters( 'give_payment_gateway', $this->gateway, $this->ID, $this );
1960 }
1961
1962 /**
1963 * Retrieve donation ID.
1964 *
1965 * @since 1.5
1966 * @access private
1967 *
1968 * @return string Donation ID from merchant processor.
1969 */
1970 private function get_transaction_id() {
1971 return apply_filters( 'give_get_payment_transaction_id', $this->transaction_id, $this->ID, $this );
1972 }
1973
1974 /**
1975 * Retrieve payment IP
1976 *
1977 * @since 1.5
1978 * @access private
1979 *
1980 * @return string Payment IP address
1981 */
1982 private function get_ip() {
1983 return apply_filters( 'give_payment_user_ip', $this->ip, $this->ID, $this );
1984 }
1985
1986 /**
1987 * Retrieve payment donor ID.
1988 *
1989 * @since 1.5
1990 * @access private
1991 *
1992 * @return int Payment donor ID.
1993 */
1994 private function get_donor_id() {
1995 return apply_filters( 'give_payment_customer_id', $this->customer_id, $this->ID, $this );
1996 }
1997
1998 /**
1999 * Retrieve payment user ID.
2000 *
2001 * @since 1.5
2002 * @access private
2003 *
2004 * @return int Payment user ID.
2005 */
2006 private function get_user_id() {
2007 return apply_filters( 'give_payment_user_id', $this->user_id, $this->ID, $this );
2008 }
2009
2010 /**
2011 * Retrieve payment email.
2012 *
2013 * @since 1.5
2014 * @access private
2015 *
2016 * @return string Payment donor email.
2017 */
2018 private function get_email() {
2019 return apply_filters( 'give_payment_user_email', $this->email, $this->ID, $this );
2020 }
2021
2022 /**
2023 * Retrieve payment user info.
2024 *
2025 * @since 1.5
2026 * @access private
2027 *
2028 * @return array Payment user info.
2029 */
2030 private function get_user_info() {
2031 return apply_filters( 'give_payment_meta_user_info', $this->user_info, $this->ID, $this );
2032 }
2033
2034 /**
2035 * Retrieve payment billing address.
2036 *
2037 * @since 1.5
2038 * @access private
2039 *
2040 * @return array Payment billing address.
2041 */
2042 private function get_address() {
2043 return apply_filters( 'give_payment_address', $this->address, $this->ID, $this );
2044 }
2045
2046 /**
2047 * Retrieve payment key.
2048 *
2049 * @since 1.5
2050 * @access private
2051 *
2052 * @return string Payment key.
2053 */
2054 private function get_key() {
2055 return apply_filters( 'give_payment_key', $this->key, $this->ID, $this );
2056 }
2057
2058 /**
2059 * Retrieve payment form id
2060 *
2061 * @since 1.5
2062 * @access private
2063 *
2064 * @return string Payment form id
2065 */
2066 private function get_form_id() {
2067 return apply_filters( 'give_payment_form_id', $this->form_id, $this->ID, $this );
2068 }
2069
2070 /**
2071 * Retrieve payment number
2072 *
2073 * @since 1.5
2074 * @access private
2075 *
2076 * @return int|string Payment number
2077 */
2078 private function get_number() {
2079 return apply_filters( 'give_payment_number', $this->number, $this->ID, $this );
2080 }
2081
2082 /**
2083 * Get serial code
2084 *
2085 * @since 2.1
2086 *
2087 * @param array $args List of arguments.
2088 *
2089 * @return string
2090 */
2091 public function get_serial_code( $args = array() ) {
2092 return Give()->seq_donation_number->get_serial_code( $this, $args );
2093 }
2094 }
2095