PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.3.2
GiveWP – Donation Plugin and Fundraising Platform v2.3.2
4.16.3 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 7 years ago backward-compatibility.php 7 years ago class-give-payment.php 7 years ago class-give-sequential-donation-number.php 7 years ago class-payment-stats.php 7 years ago class-payments-query.php 7 years ago functions.php 7 years ago
class-give-payment.php
2086 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 /**
517 * Fires before payment setup.
518 *
519 * Allow extensions to perform actions before the payment is loaded.
520 *
521 * @since 1.5
522 *
523 * @param Give_Payment $this Payment object.
524 * @param int $payment_id The ID of the payment.
525 */
526 do_action( 'give_pre_setup_payment', $this, $payment_id );
527
528 // Get payment from cache.
529 $donation_vars = Give_Cache::get_group( $payment_id, 'give-donations' );
530
531 if ( is_null( $donation_vars ) ) {
532 // Primary Identifier.
533 $this->ID = absint( $payment_id );
534
535 // Protected ID that can never be changed.
536 $this->_ID = absint( $payment_id );
537
538 // We have a payment, get the generic payment_meta item to reduce calls to it.
539 $this->payment_meta = $this->get_meta();
540
541 // Status and Dates.
542 $this->date = $payment->post_date;
543 $this->post_date = $payment->post_date;
544 $this->completed_date = $this->setup_completed_date();
545 $this->status = $payment->post_status;
546 $this->post_status = $this->status;
547 $this->mode = $this->setup_mode();
548 $this->import = $this->setup_import();
549 $this->parent_payment = $payment->post_parent;
550
551 $all_payment_statuses = give_get_payment_statuses();
552 $this->status_nicename = array_key_exists( $this->status, $all_payment_statuses ) ? $all_payment_statuses[ $this->status ] : ucfirst( $this->status );
553
554 // Currency Based.
555 $this->total = $this->setup_total();
556 $this->subtotal = $this->setup_subtotal();
557 $this->currency = $this->setup_currency();
558
559 // Gateway based.
560 $this->gateway = $this->setup_gateway();
561 $this->transaction_id = $this->setup_transaction_id();
562
563 // User based.
564 $this->ip = $this->setup_ip();
565 $this->customer_id = $this->setup_donor_id(); // Backward compatibility.
566 $this->donor_id = $this->setup_donor_id();
567 $this->user_id = $this->setup_user_id();
568 $this->email = $this->setup_email();
569 $this->user_info = $this->setup_user_info();
570 $this->address = $this->setup_address();
571 $this->first_name = $this->user_info['first_name'];
572 $this->last_name = $this->user_info['last_name'];
573 $this->title_prefix = isset( $this->user_info['title'] ) ? $this->user_info['title'] : '';
574
575 // Other Identifiers.
576 $this->form_title = $this->setup_form_title();
577 $this->form_id = $this->setup_form_id();
578 $this->price_id = $this->setup_price_id();
579 $this->key = $this->setup_payment_key();
580 $this->number = $this->setup_payment_number();
581
582 Give_Cache::set_group( $this->ID, get_object_vars( $this ), 'give-donations' );
583 } else {
584
585 foreach ( $donation_vars as $donation_var => $value ) {
586 $this->$donation_var = $value;
587 }
588 } // End if().
589
590 /**
591 * Fires after payment setup.
592 *
593 * Allow extensions to add items to this object via hook.
594 *
595 * @since 1.5
596 *
597 * @param Give_Payment $this Payment object.
598 * @param int $payment_id The ID of the payment.
599 */
600 do_action( 'give_setup_payment', $this, $payment_id );
601
602 return true;
603 }
604
605
606 /**
607 * Payment class object is storing various meta value in object parameter.
608 * So if user is updating payment meta but not updating payment object, then payment meta values will not reflect/changes on payment meta automatically
609 * 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.
610 * To prevent that user can use this function after updating any payment meta value ( in bulk or single update ).
611 *
612 * @since 1.6
613 * @access public
614 *
615 * @param int $payment_id Payment ID.
616 *
617 * @return void
618 */
619 public function update_payment_setup( $payment_id ) {
620 // Delete cache.
621 Give_Cache::delete_group( $this->ID,'give-donations' );
622
623 $this->setup_payment( $payment_id );
624 }
625
626 /**
627 * Create the base of a payment.
628 *
629 * @since 1.5
630 * @access private
631 *
632 * @return int|bool False on failure, the payment ID on success.
633 */
634 private function insert_payment() {
635
636 // Construct the payment title.
637 $payment_title = '';
638 if ( ! empty( $this->first_name ) && ! empty( $this->last_name ) ) {
639 $payment_title = $this->first_name . ' ' . $this->last_name;
640 } elseif ( ! empty( $this->first_name ) && empty( $this->last_name ) ) {
641 $payment_title = $this->first_name;
642 } elseif ( ! empty( $this->email ) && is_email( $this->email ) ) {
643 $payment_title = $this->email;
644 }
645
646 // Set Key.
647 if ( empty( $this->key ) ) {
648
649 $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
650 $this->key = strtolower( md5( $this->email . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) ); // Unique key.
651 $this->pending['key'] = $this->key;
652 }
653
654 // Set IP.
655 if ( empty( $this->ip ) ) {
656
657 $this->ip = give_get_ip();
658 $this->pending['ip'] = $this->ip;
659
660 }
661
662 // @todo: payment data exist here only for backward compatibility
663 // issue: https://github.com/impress-org/give/issues/1132
664 $payment_data = array(
665 'price' => $this->total,
666 'date' => $this->date,
667 'user_email' => $this->email,
668 'purchase_key' => $this->key,
669 'form_title' => $this->form_title,
670 'form_id' => $this->form_id,
671 'donor_id' => $this->donor_id,
672 'price_id' => $this->price_id,
673 'currency' => $this->currency,
674 'user_info' => array(
675 'id' => $this->user_id,
676 'title' => $this->title_prefix,
677 'email' => $this->email,
678 'first_name' => $this->first_name,
679 'last_name' => $this->last_name,
680 'address' => $this->address,
681 ),
682 'status' => $this->status,
683 );
684
685 $args = apply_filters( 'give_insert_payment_args', array(
686 'post_title' => $payment_title,
687 'post_status' => $this->status,
688 'post_type' => 'give_payment',
689 'post_date' => ! empty( $this->date ) ? $this->date : null,
690 'post_date_gmt' => ! empty( $this->date ) ? get_gmt_from_date( $this->date ) : null,
691 'post_parent' => $this->parent_payment,
692 ), $payment_data );
693
694 // Create a blank payment.
695 $payment_id = wp_insert_post( $args );
696
697 if ( ! empty( $payment_id ) ) {
698
699 $this->ID = $payment_id;
700 $this->_ID = $payment_id;
701
702 $donor = new stdClass;
703
704 /**
705 * Filter donor class after the donation is completed and before customer table is updated.
706 *
707 * @since 1.8.13
708 */
709 $donor = apply_filters( 'give_update_donor_information', $donor, $payment_id, $payment_data, $args );
710
711 if ( did_action( 'give_pre_process_donation' ) && is_user_logged_in() ) {
712 $donor = new Give_Donor( get_current_user_id(), true );
713
714 // Donor is logged in but used a different email to purchase with so assign to their donor record.
715 if ( ! empty( $donor->id ) && $this->email !== $donor->email ) {
716 $donor->add_email( $this->email );
717 }
718 }
719
720 if ( empty( $donor->id ) ) {
721 $donor = new Give_Donor( $this->email );
722 }
723
724 if ( empty( $donor->id ) ) {
725
726 $donor_data = array(
727 'name' => ! is_email( $payment_title ) ? $this->first_name . ' ' . $this->last_name : '',
728 'email' => $this->email,
729 'user_id' => $this->user_id,
730 );
731
732 $donor->create( $donor_data );
733
734 }
735
736 // Update Donor Meta once donor is created.
737 $donor->update_meta( '_give_donor_first_name', $this->first_name );
738 $donor->update_meta( '_give_donor_last_name', $this->last_name );
739 $donor->update_meta( '_give_donor_title_prefix', $this->title_prefix );
740
741 $this->customer_id = $donor->id;
742 $this->pending['customer_id'] = $this->customer_id;
743 $donor->attach_payment( $this->ID, false );
744
745 $this->payment_meta = apply_filters( 'give_payment_meta', $this->payment_meta, $payment_data );
746
747 /*
748 * _give_payment_meta backward compatibility.
749 *
750 * @since 2.0.1
751 */
752 $custom_payment_meta = array_diff(
753 array_map( 'maybe_serialize', $this->payment_meta ),
754 array_map( 'maybe_serialize', $payment_data )
755 );
756
757 if ( ! empty( $custom_payment_meta ) ) {
758 give_doing_it_wrong( '_give_payment_meta', __( 'This custom meta key deprecated. We are not using this meta key for storing payment meta but your custom meta data will be store because we added backward compatibility. Please change your logic because in future we can remove it.', 'give' ), '2.0.0' );
759
760 $this->update_meta( '_give_payment_meta', array_map( 'maybe_unserialize', $custom_payment_meta ) );
761 }
762
763 $give_company = ( ! empty( $_REQUEST['give_company_name'] ) ? give_clean( $_REQUEST['give_company_name'] ) : '' );
764
765 // Check $page_url is not empty.
766 if ( $give_company ) {
767 give_update_meta( $payment_id, '_give_donation_company', $give_company );
768
769 $donor_id = absint( $donor->id );
770 if ( ! empty( $donor_id ) ) {
771 Give()->donor_meta->update_meta( $donor_id, '_give_donor_company', $give_company );
772 }
773 }
774
775 $this->new = true;
776 } // End if().
777
778 return $this->ID;
779
780 }
781
782 /**
783 * Save
784 *
785 * Once items have been set, an update is needed to save them to the database.
786 *
787 * @access public
788 *
789 * @return bool True of the save occurred, false if it failed or wasn't needed
790 */
791 public function save() {
792 $saved = false;
793
794 // Must have an ID.
795 if ( empty( $this->ID ) ) {
796
797 $payment_id = $this->insert_payment();
798
799 if ( false === $payment_id ) {
800 $saved = false;
801 } else {
802 $this->ID = $payment_id;
803 }
804 }
805
806 // Set ID if not matching.
807 if ( $this->ID !== $this->_ID ) {
808 $this->ID = $this->_ID;
809 }
810
811 // If we have something pending, let's save it.
812 if ( ! empty( $this->pending ) ) {
813
814 $total_increase = 0;
815 $total_decrease = 0;
816
817 foreach ( $this->pending as $key => $value ) {
818
819 switch ( $key ) {
820
821 case 'donations':
822 // Update totals for pending donations.
823 foreach ( $this->pending[ $key ] as $item ) {
824
825 $quantity = isset( $item['quantity'] ) ? $item['quantity'] : 1;
826 $price_id = isset( $item['price_id'] ) ? $item['price_id'] : 0;
827
828 switch ( $item['action'] ) {
829
830 case 'add':
831
832 $price = $item['price'];
833
834 if ( 'publish' === $this->status || 'complete' === $this->status ) {
835
836 // Add donation to logs.
837 $log_date = date_i18n( 'Y-m-d G:i:s', current_time( 'timestamp' ) );
838 give_record_donation_in_log( $item['id'], $this->ID, $price_id, $log_date );
839
840 $form = new Give_Donate_Form( $item['id'] );
841 $form->increase_sales( $quantity );
842 $form->increase_earnings( $price, $this->ID );
843
844 $total_increase += $price;
845 }
846 break;
847
848 case 'remove':
849 $this->delete_sales_logs();
850 if ( 'publish' === $this->status || 'complete' === $this->status ) {
851 $form = new Give_Donate_Form( $item['id'] );
852 $form->decrease_sales( $quantity );
853 $form->decrease_earnings( $item['amount'], $this->ID );
854
855 $total_decrease += $item['amount'];
856 }
857 break;
858
859 }// End switch().
860 }// End foreach().
861 break;
862
863 case 'status':
864 $this->update_status( $this->status );
865 break;
866
867 case 'gateway':
868 $this->update_meta( '_give_payment_gateway', $this->gateway );
869 break;
870
871 case 'mode':
872 $this->update_meta( '_give_payment_mode', $this->mode );
873 break;
874
875 case 'transaction_id':
876 $this->update_meta( '_give_payment_transaction_id', $this->transaction_id );
877 break;
878
879 case 'ip':
880 $this->update_meta( '_give_payment_donor_ip', $this->ip );
881 break;
882
883 case 'customer_id':
884 $this->update_meta( '_give_payment_donor_id', $this->customer_id );
885 break;
886
887 case 'form_title':
888 $this->update_meta( '_give_payment_form_title', $this->form_title );
889 break;
890
891 case 'form_id':
892 $this->update_meta( '_give_payment_form_id', $this->form_id );
893 break;
894
895 case 'price_id':
896 $this->update_meta( '_give_payment_price_id', $this->price_id );
897 break;
898
899 case 'first_name':
900 $this->update_meta( '_give_donor_billing_first_name', $this->first_name );
901 break;
902
903 case 'last_name':
904 $this->update_meta( '_give_donor_billing_last_name', $this->last_name );
905 break;
906
907 case 'currency':
908 $this->update_meta( '_give_payment_currency', $this->currency );
909 break;
910
911 case 'address':
912 if ( ! empty( $this->address ) ) {
913 foreach ( $this->address as $address_name => $address ) {
914 switch ( $address_name ) {
915 case 'line1':
916 $this->update_meta( '_give_donor_billing_address1', $address );
917 break;
918
919 case 'line2':
920 $this->update_meta( '_give_donor_billing_address2', $address );
921 break;
922
923 default:
924 $this->update_meta( "_give_donor_billing_{$address_name}", $address );
925 }
926 }
927 }
928 break;
929
930 case 'email':
931 $this->update_meta( '_give_payment_donor_email', $this->email );
932 break;
933
934 case 'title_prefix':
935 $this->update_meta( '_give_payment_donor_title_prefix', $this->title_prefix );
936 break;
937
938 case 'key':
939 $this->update_meta( '_give_payment_purchase_key', $this->key );
940 break;
941
942 case 'number':
943 // @todo: remove unused meta data.
944 // Core is using post_title to store donation serial code ( fi enabled ) instead this meta key.
945 // Do not use this meta key in your logic, can be remove in future
946 $this->update_meta( '_give_payment_number', $this->number );
947 break;
948
949 case 'date':
950 $args = array(
951 'ID' => $this->ID,
952 'post_date' => date( 'Y-m-d H:i:s', strtotime( $this->date ) ),
953 'post_date_gmt' => get_gmt_from_date( $this->date ),
954 'edit_date' => true,
955 );
956
957 wp_update_post( $args );
958 break;
959
960 case 'completed_date':
961 $this->update_meta( '_give_completed_date', $this->completed_date );
962 break;
963
964 case 'parent_payment':
965 $args = array(
966 'ID' => $this->ID,
967 'post_parent' => $this->parent_payment,
968 );
969
970 wp_update_post( $args );
971 break;
972
973 case 'total':
974 $this->update_meta( '_give_payment_total', give_sanitize_amount_for_db( $this->total ) );
975 break;
976
977 default:
978 /**
979 * Fires while saving payment.
980 *
981 * @since 1.7
982 *
983 * @param Give_Payment $this Payment object.
984 */
985 do_action( 'give_payment_save', $this, $key );
986 break;
987 } // End switch().
988 } // End foreach().
989
990 if ( 'pending' !== $this->status ) {
991
992 $donor = new Give_Donor( $this->customer_id );
993
994 $total_change = $total_increase - $total_decrease;
995 if ( $total_change < 0 ) {
996
997 $total_change = - ( $total_change );
998
999 // Decrease the donor's donation stats.
1000 $donor->decrease_value( $total_change );
1001 give_decrease_total_earnings( $total_change );
1002
1003 $donor->decrease_donation_count();
1004
1005 } elseif ( $total_change > 0 ) {
1006
1007 // Increase the donor's donation stats.
1008 $donor->increase_value( $total_change );
1009 give_increase_total_earnings( $total_change );
1010
1011 $donor->increase_purchase_count();
1012
1013 }
1014
1015 // Verify and update form meta based on the form status.
1016 give_set_form_closed_status( $this->form_id );
1017 }
1018
1019 $this->pending = array();
1020 $saved = true;
1021 } // End if().
1022
1023 if ( true === $saved ) {
1024 $this->setup_payment( $this->ID );
1025 }
1026
1027 return $saved;
1028 }
1029
1030 /**
1031 * Add a donation to a given payment
1032 *
1033 * @since 1.5
1034 * @access public
1035 *
1036 * @param int $form_id The donation form to add.
1037 * @param array $args Other arguments to pass to the function.
1038 * @param array $options List of donation options.
1039 *
1040 * @return bool True when successful, false otherwise
1041 */
1042 public function add_donation( $form_id = 0, $args = array(), $options = array() ) {
1043
1044 $donation = new Give_Donate_Form( $form_id );
1045
1046 // Bail if this post isn't a give donation form.
1047 if ( ! $donation || 'give_forms' !== $donation->post_type ) {
1048 return false;
1049 }
1050
1051 // Set some defaults.
1052 $defaults = array(
1053 'price' => false,
1054 'price_id' => false,
1055 );
1056
1057 $args = wp_parse_args( apply_filters( 'give_payment_add_donation_args', $args, $donation->ID ), $defaults );
1058
1059 // Allow overriding the price.
1060 if ( false !== $args['price'] ) {
1061 $donation_amount = $args['price'];
1062 } else {
1063
1064 // Deal with variable pricing.
1065 if ( give_has_variable_prices( $donation->ID ) ) {
1066 $prices = give_get_meta( $form_id, '_give_donation_levels', true );
1067 $donation_amount = '';
1068
1069 // Loop through prices.
1070 foreach ( $prices as $price ) {
1071 // Find a match between price_id and level_id.
1072 // First verify array keys exists THEN make the match.
1073 if (
1074 isset( $args['price_id'] ) &&
1075 isset( $price['_give_id']['level_id'] ) &&
1076 $args['price_id'] === (int) $price['_give_id']['level_id']
1077 ) {
1078 $donation_amount = $price['_give_amount'];
1079 }
1080 }
1081
1082 // Fallback to the lowest price point.
1083 if ( '' === $donation_amount ) {
1084 $donation_amount = give_get_lowest_price_option( $donation->ID );
1085 $args['price_id'] = give_get_lowest_price_id( $donation->ID );
1086 }
1087 } else {
1088 // Simple form price.
1089 $donation_amount = give_get_form_price( $donation->ID );
1090 }
1091 }
1092
1093 // Sanitizing the price here so we don't have a dozen calls later.
1094 $donation_amount = give_maybe_sanitize_amount( $donation_amount );
1095 $total = round( $donation_amount, give_get_price_decimals( $this->ID ) );
1096
1097 // Add Options.
1098 $default_options = array();
1099 if ( false !== $args['price_id'] ) {
1100 $default_options['price_id'] = (int) $args['price_id'];
1101 }
1102 $options = wp_parse_args( $options, $default_options );
1103
1104 // Do not allow totals to go negative.
1105 if ( $total < 0 ) {
1106 $total = 0;
1107 }
1108
1109 $donation = array(
1110 'name' => $donation->post_title,
1111 'id' => $donation->ID,
1112 'price' => round( $total, give_get_price_decimals( $this->ID ) ),
1113 'subtotal' => round( $total, give_get_price_decimals( $this->ID ) ),
1114 'price_id' => $args['price_id'],
1115 'action' => 'add',
1116 'options' => $options,
1117 );
1118
1119 $this->pending['donations'][] = $donation;
1120
1121 $this->increase_subtotal( $total );
1122
1123 return true;
1124
1125 }
1126
1127 /**
1128 * Remove a donation from the payment
1129 *
1130 * @since 1.5
1131 * @access public
1132 *
1133 * @param int $form_id The form ID to remove.
1134 * @param array $args Arguments to pass to identify (quantity, amount, price_id).
1135 *
1136 * @return bool If the item was removed or not
1137 */
1138 public function remove_donation( $form_id, $args = array() ) {
1139
1140 // Set some defaults.
1141 $defaults = array(
1142 'quantity' => 1,
1143 'price' => false,
1144 'price_id' => false,
1145 );
1146 $args = wp_parse_args( $args, $defaults );
1147
1148 $form = new Give_Donate_Form( $form_id );
1149
1150 // Bail if this post isn't a valid give donation form.
1151 if ( ! $form || 'give_forms' !== $form->post_type ) {
1152 return false;
1153 }
1154
1155 $pending_args = $args;
1156 $pending_args['id'] = $form_id;
1157 $pending_args['amount'] = $this->total;
1158 $pending_args['price_id'] = false !== $args['price_id'] ? (int) $args['price_id'] : false;
1159 $pending_args['quantity'] = $args['quantity'];
1160 $pending_args['action'] = 'remove';
1161
1162 $this->pending['donations'][] = $pending_args;
1163
1164 $this->decrease_subtotal( $this->total );
1165
1166 return true;
1167 }
1168
1169
1170 /**
1171 * Add a note to a payment
1172 *
1173 * @since 1.5
1174 * @access public
1175 *
1176 * @param string|bool $note The note to add.
1177 *
1178 * @return bool If the note was specified or not
1179 */
1180 public function add_note( $note = false ) {
1181 // Bail if no note specified.
1182 if ( ! $note ) {
1183 return false;
1184 }
1185
1186 give_insert_payment_note( $this->ID, $note );
1187 }
1188
1189 /**
1190 * Increase the payment's subtotal
1191 *
1192 * @since 1.5
1193 * @access private
1194 *
1195 * @param float $amount The amount to increase the payment subtotal by.
1196 *
1197 * @return void
1198 */
1199 private function increase_subtotal( $amount = 0.00 ) {
1200 $amount = (float) $amount;
1201 $this->subtotal += $amount;
1202
1203 $this->recalculate_total();
1204 }
1205
1206 /**
1207 * Decrease the payment's subtotal.
1208 *
1209 * @since 1.5
1210 * @access private
1211 *
1212 * @param float $amount The amount to decrease the payment subtotal by.
1213 *
1214 * @return void
1215 */
1216 private function decrease_subtotal( $amount = 0.00 ) {
1217 $amount = (float) $amount;
1218 $this->subtotal -= $amount;
1219
1220 if ( $this->subtotal < 0 ) {
1221 $this->subtotal = 0;
1222 }
1223
1224 $this->recalculate_total();
1225 }
1226
1227 /**
1228 * Set or update the total for a payment.
1229 *
1230 * @since 1.5
1231 * @since 2.1.4 reset total in pending property
1232 * @access private
1233 *
1234 * @return void
1235 */
1236 private function recalculate_total() {
1237 $this->pending['total'] = $this->total = $this->subtotal;
1238 }
1239
1240 /**
1241 * Set the payment status and run any status specific changes necessary.
1242 *
1243 * @since 1.5
1244 * @access public
1245 *
1246 * @param string|bool $status The status to set the payment to.
1247 *
1248 * @return bool $updated Returns if the status was successfully updated.
1249 */
1250 public function update_status( $status = false ) {
1251
1252 // standardize the 'complete(d)' status.
1253 if ( 'completed' === $status || 'complete' === $status ) {
1254 $status = 'publish';
1255 }
1256
1257 $old_status = ! empty( $this->old_status ) ? $this->old_status : false;
1258
1259 if ( $old_status === $status ) {
1260 return false; // Don't permit status changes that aren't changes.
1261 }
1262
1263 $do_change = apply_filters( 'give_should_update_payment_status', true, $this->ID, $status, $old_status );
1264
1265 $updated = false;
1266
1267 if ( $do_change ) {
1268
1269 /**
1270 * Fires before changing payment status.
1271 *
1272 * @since 1.5
1273 *
1274 * @param int $payment_id Payments ID.
1275 * @param string $status The new status.
1276 * @param string $old_status The old status.
1277 */
1278 do_action( 'give_before_payment_status_change', $this->ID, $status, $old_status );
1279
1280 $update_fields = array(
1281 'ID' => $this->ID,
1282 'post_status' => $status,
1283 'edit_date' => current_time( 'mysql' ),
1284 );
1285
1286 $updated = wp_update_post( apply_filters( 'give_update_payment_status_fields', $update_fields ) );
1287
1288 $all_payment_statuses = give_get_payment_statuses();
1289 $this->status_nicename = array_key_exists( $status, $all_payment_statuses ) ? $all_payment_statuses[ $status ] : ucfirst( $status );
1290
1291 // Process any specific status functions.
1292 $this->process_status( $status );
1293
1294 /**
1295 * Fires after changing payment status.
1296 *
1297 * @since 1.5
1298 *
1299 * @param int $payment_id Payment ID.
1300 * @param string $status The new status.
1301 * @param string $old_status The old status.
1302 */
1303 do_action( 'give_update_payment_status', $this->ID, $status, $old_status );
1304
1305 } // End if().
1306
1307 return $updated;
1308
1309 }
1310
1311 /**
1312 * Change the status of the payment to refunded, and run the necessary changes
1313 *
1314 * @since 1.5
1315 * @access public
1316 *
1317 * @return void
1318 */
1319 public function refund() {
1320 $this->old_status = $this->status;
1321 $this->status = 'refunded';
1322 $this->pending['status'] = $this->status;
1323
1324 $this->save();
1325 }
1326
1327 /**
1328 * Get a post meta item for the payment
1329 *
1330 * @since 1.5
1331 * @access public
1332 *
1333 * @param string $meta_key The Meta Key.
1334 * @param boolean $single Return single item or array.
1335 *
1336 * @return mixed The value from the post meta
1337 */
1338 public function get_meta( $meta_key = '_give_payment_meta', $single = true ) {
1339 if (
1340 ! has_filter( 'get_post_metadata', 'give_bc_v20_get_payment_meta' ) &&
1341 ! doing_filter( 'get_post_metadata' )
1342 ) {
1343 add_filter( 'get_post_metadata', 'give_bc_v20_get_payment_meta', 999, 4 );
1344 }
1345
1346 $meta = give_get_meta( $this->ID, $meta_key, $single );
1347
1348 /**
1349 * Filter the specific meta key value.
1350 *
1351 * @since 1.5
1352 */
1353 $meta = apply_filters( "give_get_payment_meta_{$meta_key}", $meta, $this->ID );
1354
1355 // Security check.
1356 if ( is_serialized( $meta ) ) {
1357 preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $meta, $matches );
1358 if ( ! empty( $matches ) ) {
1359 $meta = array();
1360 }
1361 }
1362
1363 /**
1364 * Filter the all meta keys.
1365 *
1366 * @since 1.5
1367 */
1368 return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1369 }
1370
1371 /**
1372 * Update the post meta
1373 *
1374 * @since 1.5
1375 * @access public
1376 *
1377 * @param string $meta_key The meta key to update.
1378 * @param string $meta_value The meta value.
1379 * @param string $prev_value Previous meta value.
1380 *
1381 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure
1382 */
1383 public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1384 if ( empty( $meta_key ) ) {
1385 return false;
1386 }
1387
1388
1389 /**
1390 * Filter the single meta key while updating
1391 *
1392 * @since 1.5
1393 */
1394 $meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1395
1396 return give_update_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1397 }
1398
1399 /**
1400 * Process Donation Status.
1401 *
1402 * @param string $status Donation Status.
1403 *
1404 * @since 2.0.2
1405 * @access private
1406 *
1407 * @return void
1408 */
1409 private function process_status( $status ) {
1410 $process = true;
1411
1412 // Bailout, if changed from completed to preapproval/processing.
1413 // Bailout, if current status = previous status or status is publish.
1414 if (
1415 'preapproval' === $status ||
1416 'processing' === $status ||
1417 'publish' !== $this->old_status ||
1418 $status !== $this->status
1419 ) {
1420 $process = false;
1421 }
1422
1423 // Allow extensions to filter for their own payment types, Example: Recurring Payments.
1424 $process = apply_filters( "give_should_process_{$status}", $process, $this );
1425
1426 if ( false === $process ) {
1427 return;
1428 }
1429
1430 /**
1431 * Fires before processing donation status.
1432 *
1433 * @param Give_Payment $this Payment object.
1434 *
1435 * @since 1.5
1436 */
1437 do_action( "give_pre_{$status}_payment", $this );
1438
1439 $decrease_earnings = apply_filters( "give_decrease_earnings_on_{$status}", true, $this );
1440 $decrease_donor_value = apply_filters( "give_decrease_donor_value_on_{$status}", true, $this );
1441 $decrease_donation_count = apply_filters( "give_decrease_donors_donation_count_on_{$status}", true, $this );
1442
1443 $this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1444 $this->delete_sales_logs();
1445
1446 // @todo: Refresh only range related stat cache
1447 give_delete_donation_stats();
1448
1449 /**
1450 * Fires after processing donation status.
1451 *
1452 * @param Give_Payment $this Payment object.
1453 *
1454 * @since 1.5
1455 */
1456 do_action( "give_post_{$status}_payment", $this );
1457 }
1458
1459 /**
1460 * Used during the process of moving to refunded or pending, to decrement stats
1461 *
1462 * @since 1.5
1463 * @access private
1464 *
1465 * @param bool $alter_store_earnings If the method should alter the store earnings.
1466 * @param bool $alter_customer_value If the method should reduce the donor value.
1467 * @param bool $alter_customer_purchase_count If the method should reduce the donor's purchase count.
1468 *
1469 * @return void
1470 */
1471 private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1472
1473 give_undo_donation( $this->ID );
1474
1475 // Decrease store earnings.
1476 if ( true === $alter_store_earnings ) {
1477 give_decrease_total_earnings( $this->total );
1478 }
1479
1480 // Decrement the stats for the donor.
1481 if ( ! empty( $this->customer_id ) ) {
1482
1483 $donor = new Give_Donor( $this->customer_id );
1484
1485 if ( true === $alter_customer_value ) {
1486 $donor->decrease_value( $this->total );
1487 }
1488
1489 if ( true === $alter_customer_purchase_count ) {
1490 $donor->decrease_donation_count();
1491 }
1492 }
1493
1494 }
1495
1496 /**
1497 * Delete sales logs for this donation
1498 *
1499 * @since 1.5
1500 * @access private
1501 *
1502 * @return void
1503 */
1504 private function delete_sales_logs() {
1505 // Remove related sale log entries.
1506 Give()->logs->delete_logs( $this->ID );
1507 }
1508
1509 /**
1510 * Setup functions only, these are not to be used by developers.
1511 * These functions exist only to allow the setup routine to be backwards compatible with our old
1512 * helper functions.
1513 *
1514 * These will run whenever setup_payment is called, which should only be called once.
1515 * To update an attribute, update it directly instead of re-running the setup routine
1516 */
1517
1518 /**
1519 * Setup the payment completed date
1520 *
1521 * @since 1.5
1522 * @access private
1523 *
1524 * @return string The date the payment was completed
1525 */
1526 private function setup_completed_date() {
1527 $payment = get_post( $this->ID );
1528
1529 if ( 'pending' === $payment->post_status || 'preapproved' === $payment->post_status ) {
1530 return false; // This payment was never completed.
1531 }
1532
1533 $date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1534
1535 return $date;
1536 }
1537
1538 /**
1539 * Setup the payment mode
1540 *
1541 * @since 1.5
1542 * @access private
1543 *
1544 * @return string The payment mode
1545 */
1546 private function setup_mode() {
1547 return $this->get_meta( '_give_payment_mode' );
1548 }
1549
1550 /**
1551 * Setup the payment import data
1552 *
1553 * @since 1.8.13
1554 * @access private
1555 *
1556 * @return bool The payment import
1557 */
1558 private function setup_import() {
1559 return (bool) $this->get_meta( '_give_payment_import' );
1560 }
1561
1562 /**
1563 * Setup the payment total
1564 *
1565 * @since 1.5
1566 * @access private
1567 *
1568 * @return float The payment total
1569 */
1570 private function setup_total() {
1571 $amount = $this->get_meta( '_give_payment_total', true );
1572
1573 return round( floatval( $amount ), give_get_price_decimals( $this->ID ) );
1574 }
1575
1576 /**
1577 * Setup the payment subtotal
1578 *
1579 * @since 1.5
1580 * @access private
1581 *
1582 * @return float The subtotal of the payment
1583 */
1584 private function setup_subtotal() {
1585 $subtotal = $this->total;
1586
1587 return $subtotal;
1588 }
1589
1590 /**
1591 * Setup the currency code
1592 *
1593 * @since 1.5
1594 * @since 2.0 Set currency from _give_payment_currency meta key
1595 * @access private
1596 *
1597 * @return string The currency for the payment
1598 */
1599 private function setup_currency() {
1600 $currency = $this->get_meta( '_give_payment_currency', true );
1601 $currency = ! empty( $currency ) ?
1602 $currency :
1603 /**
1604 * Filter the default donation currency
1605 *
1606 * @since 1.5
1607 */
1608 apply_filters(
1609 'give_payment_currency_default',
1610 give_get_currency( $this->form_id, $this ),
1611 $this
1612 );
1613
1614 return $currency;
1615 }
1616
1617 /**
1618 * Setup the gateway used for the payment
1619 *
1620 * @since 1.5
1621 * @access private
1622 *
1623 * @return string The gateway
1624 */
1625 private function setup_gateway() {
1626 $gateway = $this->get_meta( '_give_payment_gateway', true );
1627
1628 return $gateway;
1629 }
1630
1631 /**
1632 * Setup the donation ID
1633 *
1634 * @since 1.5
1635 * @access private
1636 *
1637 * @return string The donation ID
1638 */
1639 private function setup_transaction_id() {
1640 $transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1641
1642 if ( empty( $transaction_id ) ) {
1643 $gateway = $this->gateway;
1644 $transaction_id = apply_filters( "give_get_payment_transaction_id-{$gateway}", $this->ID );
1645 }
1646
1647 return $transaction_id;
1648 }
1649
1650 /**
1651 * Setup the IP Address for the payment
1652 *
1653 * @since 1.5
1654 * @since 2.0 Set ip address from _give_payment_donor_ip meta key
1655 * @access private
1656 *
1657 * @return string The IP address for the payment
1658 */
1659 private function setup_ip() {
1660 $ip = $this->get_meta( '_give_payment_donor_ip', true );
1661
1662 return $ip;
1663 }
1664
1665 /**
1666 * Setup the donor ID.
1667 *
1668 * @since 1.5
1669 * @since 2.0 Set id from _give_payment_donor_id meta key
1670 * @access private
1671 *
1672 * @return int The Donor ID.
1673 */
1674 private function setup_donor_id() {
1675 $donor_id = $this->get_meta( '_give_payment_donor_id', true );
1676
1677 return $donor_id;
1678 }
1679
1680 /**
1681 * Setup the User ID associated with the donation
1682 *
1683 * @since 1.5
1684 * @since 2.0 Get user id connect to donor from donor table instead of payment meta.
1685 *
1686 * @access private
1687 *
1688 * @return int The User ID
1689 */
1690 private function setup_user_id() {
1691
1692 $donor = Give()->customers->get_customer_by( 'id', $this->customer_id );
1693 $user_id = $donor ? absint( $donor->user_id ) : 0;
1694
1695
1696 return $user_id;
1697 }
1698
1699 /**
1700 * Setup the email address for the donation.
1701 *
1702 * @since 1.5
1703 * @since 2.0 Set email from _give_payment_donor_email meta key
1704 *
1705 * @access private
1706 *
1707 * @return string The email address for the payment.
1708 */
1709 private function setup_email() {
1710 $email = $this->get_meta( '_give_payment_donor_email', true );
1711
1712 if ( empty( $email ) && $this->customer_id ) {
1713 $email = Give()->donors->get_column( 'email', $this->customer_id );
1714 }
1715
1716 return $email;
1717 }
1718
1719 /**
1720 * Setup the user info.
1721 *
1722 * @since 1.5
1723 * @access private
1724 *
1725 * @return array The user info associated with the payment.
1726 */
1727 private function setup_user_info() {
1728 $defaults = array(
1729 'title' => $this->title_prefix,
1730 'first_name' => $this->first_name,
1731 'last_name' => $this->last_name,
1732 );
1733
1734 $user_info = isset( $this->payment_meta['user_info'] ) ? $this->payment_meta['user_info'] : array();
1735
1736 if ( is_serialized( $user_info ) ) {
1737 preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $user_info, $matches );
1738 if ( ! empty( $matches ) ) {
1739 $user_info = array();
1740 }
1741 }
1742
1743 $user_info = wp_parse_args( $user_info, $defaults );
1744
1745 if ( empty( $user_info ) ) {
1746 // Get the donor, but only if it's been created.
1747 $donor = new Give_Donor( $this->customer_id );
1748
1749 if ( $donor->id > 0 ) {
1750 $user_info = array(
1751 'first_name' => $donor->get_first_name(),
1752 'last_name' => $donor->get_last_name(),
1753 'email' => $donor->email,
1754 'discount' => 'none',
1755 );
1756 }
1757 } else {
1758 // Get the donor, but only if it's been created.
1759 $donor = new Give_Donor( $this->customer_id );
1760
1761 if ( $donor->id > 0 ) {
1762 foreach ( $user_info as $key => $value ) {
1763 if ( ! empty( $value ) ) {
1764 continue;
1765 }
1766
1767 switch ( $key ) {
1768 case 'title':
1769 $user_info[ $key ] = Give()->donor_meta->get_meta( $donor->id, '_give_donor_title_prefix', true );
1770 break;
1771
1772 case 'first_name':
1773 $user_info[ $key ] = $donor->get_first_name();
1774 break;
1775
1776 case 'last_name':
1777 $user_info[ $key ] = $donor->get_last_name();
1778 break;
1779
1780 case 'email':
1781 $user_info[ $key ] = $donor->email;
1782 break;
1783 }
1784 }
1785 }
1786 }// End if().
1787
1788 return $user_info;
1789
1790 }
1791
1792 /**
1793 * Setup the Address for the payment.
1794 *
1795 * @since 1.5
1796 * @access private
1797 *
1798 * @return array The Address information for the payment.
1799 */
1800 private function setup_address() {
1801 $address['line1'] = give_get_meta( $this->ID, '_give_donor_billing_address1', true, '' );
1802 $address['line2'] = give_get_meta( $this->ID, '_give_donor_billing_address2', true, '' );
1803 $address['city'] = give_get_meta( $this->ID, '_give_donor_billing_city', true, '' );
1804 $address['state'] = give_get_meta( $this->ID, '_give_donor_billing_state', true, '' );
1805 $address['zip'] = give_get_meta( $this->ID, '_give_donor_billing_zip', true, '' );
1806 $address['country'] = give_get_meta( $this->ID, '_give_donor_billing_country', true, '' );
1807
1808 return $address;
1809 }
1810
1811 /**
1812 * Setup the form title.
1813 *
1814 * @since 1.5
1815 * @access private
1816 *
1817 * @return string The Form Title.
1818 */
1819 private function setup_form_title() {
1820
1821 $form_id = $this->get_meta( '_give_payment_form_title', true );
1822
1823 return $form_id;
1824 }
1825
1826 /**
1827 * Setup the form ID.
1828 *
1829 * @since 1.5
1830 * @access private
1831 *
1832 * @return int The Form ID
1833 */
1834 private function setup_form_id() {
1835
1836 $form_id = $this->get_meta( '_give_payment_form_id', true );
1837
1838 return $form_id;
1839 }
1840
1841 /**
1842 * Setup the price ID.
1843 *
1844 * @since 1.5
1845 * @access private
1846 *
1847 * @return int The Form Price ID.
1848 */
1849 private function setup_price_id() {
1850 $price_id = $this->get_meta( '_give_payment_price_id', true );
1851
1852 return $price_id;
1853 }
1854
1855 /**
1856 * Setup the payment key.
1857 *
1858 * @since 1.5
1859 * @access private
1860 *
1861 * @return string The Payment Key.
1862 */
1863 private function setup_payment_key() {
1864 $key = $this->get_meta( '_give_payment_purchase_key', true );
1865
1866 return $key;
1867 }
1868
1869 /**
1870 * Setup the payment number.
1871 *
1872 * @since 1.5
1873 * @access private
1874 *
1875 * @return int|string Integer by default, or string if sequential order numbers is enabled.
1876 */
1877 private function setup_payment_number() {
1878 return $this->get_serial_code();
1879 }
1880
1881 /**
1882 * Converts this object into an array for special cases.
1883 *
1884 * @access public
1885 *
1886 * @return array The payment object as an array.
1887 */
1888 public function array_convert() {
1889 return get_object_vars( $this );
1890 }
1891
1892
1893 /**
1894 * Flag to check if donation is completed or not.
1895 *
1896 * @since 1.8
1897 * @access public
1898 *
1899 * @return bool
1900 */
1901 public function is_completed() {
1902 return ( 'publish' === $this->status && $this->completed_date );
1903 }
1904
1905 /**
1906 * Retrieve payment completion date.
1907 *
1908 * @since 1.5
1909 * @access private
1910 *
1911 * @return string Date payment was completed.
1912 */
1913 private function get_completed_date() {
1914 return apply_filters( 'give_payment_completed_date', $this->completed_date, $this->ID, $this );
1915 }
1916
1917 /**
1918 * Retrieve payment subtotal.
1919 *
1920 * @since 1.5
1921 * @access private
1922 *
1923 * @return float Payment subtotal.
1924 */
1925 private function get_subtotal() {
1926 return apply_filters( 'give_get_payment_subtotal', $this->subtotal, $this->ID, $this );
1927 }
1928
1929 /**
1930 * Retrieve payment currency.
1931 *
1932 * @since 1.5
1933 * @access private
1934 *
1935 * @return string Payment currency code.
1936 */
1937 private function get_currency() {
1938 return apply_filters( 'give_payment_currency_code', $this->currency, $this->ID, $this );
1939 }
1940
1941 /**
1942 * Retrieve payment gateway.
1943 *
1944 * @since 1.5
1945 * @access private
1946 *
1947 * @return string Gateway used.
1948 */
1949 private function get_gateway() {
1950 return apply_filters( 'give_payment_gateway', $this->gateway, $this->ID, $this );
1951 }
1952
1953 /**
1954 * Retrieve donation ID.
1955 *
1956 * @since 1.5
1957 * @access private
1958 *
1959 * @return string Donation ID from merchant processor.
1960 */
1961 private function get_transaction_id() {
1962 return apply_filters( 'give_get_payment_transaction_id', $this->transaction_id, $this->ID, $this );
1963 }
1964
1965 /**
1966 * Retrieve payment IP
1967 *
1968 * @since 1.5
1969 * @access private
1970 *
1971 * @return string Payment IP address
1972 */
1973 private function get_ip() {
1974 return apply_filters( 'give_payment_user_ip', $this->ip, $this->ID, $this );
1975 }
1976
1977 /**
1978 * Retrieve payment donor ID.
1979 *
1980 * @since 1.5
1981 * @access private
1982 *
1983 * @return int Payment donor ID.
1984 */
1985 private function get_donor_id() {
1986 return apply_filters( 'give_payment_customer_id', $this->customer_id, $this->ID, $this );
1987 }
1988
1989 /**
1990 * Retrieve payment user ID.
1991 *
1992 * @since 1.5
1993 * @access private
1994 *
1995 * @return int Payment user ID.
1996 */
1997 private function get_user_id() {
1998 return apply_filters( 'give_payment_user_id', $this->user_id, $this->ID, $this );
1999 }
2000
2001 /**
2002 * Retrieve payment email.
2003 *
2004 * @since 1.5
2005 * @access private
2006 *
2007 * @return string Payment donor email.
2008 */
2009 private function get_email() {
2010 return apply_filters( 'give_payment_user_email', $this->email, $this->ID, $this );
2011 }
2012
2013 /**
2014 * Retrieve payment user info.
2015 *
2016 * @since 1.5
2017 * @access private
2018 *
2019 * @return array Payment user info.
2020 */
2021 private function get_user_info() {
2022 return apply_filters( 'give_payment_meta_user_info', $this->user_info, $this->ID, $this );
2023 }
2024
2025 /**
2026 * Retrieve payment billing address.
2027 *
2028 * @since 1.5
2029 * @access private
2030 *
2031 * @return array Payment billing address.
2032 */
2033 private function get_address() {
2034 return apply_filters( 'give_payment_address', $this->address, $this->ID, $this );
2035 }
2036
2037 /**
2038 * Retrieve payment key.
2039 *
2040 * @since 1.5
2041 * @access private
2042 *
2043 * @return string Payment key.
2044 */
2045 private function get_key() {
2046 return apply_filters( 'give_payment_key', $this->key, $this->ID, $this );
2047 }
2048
2049 /**
2050 * Retrieve payment form id
2051 *
2052 * @since 1.5
2053 * @access private
2054 *
2055 * @return string Payment form id
2056 */
2057 private function get_form_id() {
2058 return apply_filters( 'give_payment_form_id', $this->form_id, $this->ID, $this );
2059 }
2060
2061 /**
2062 * Retrieve payment number
2063 *
2064 * @since 1.5
2065 * @access private
2066 *
2067 * @return int|string Payment number
2068 */
2069 private function get_number() {
2070 return apply_filters( 'give_payment_number', $this->number, $this->ID, $this );
2071 }
2072
2073 /**
2074 * Get serial code
2075 *
2076 * @since 2.1
2077 *
2078 * @param array $args List of arguments.
2079 *
2080 * @return string
2081 */
2082 public function get_serial_code( $args = array() ) {
2083 return Give()->seq_donation_number->get_serial_code( $this, $args );
2084 }
2085 }
2086