Completed
Branch master (5b0dd6)
by
unknown
38:45 queued 30:24
created

EE_Payment::get_pretty()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Payment class
4
 *
5
 * @package        Event Espresso
6
 * @subpackage     includes/classes/EE_Payment.class.php
7
 * @author         Brent Christensen
8
 */
9
class EE_Payment extends EE_Base_Class implements EEI_Payment
10
{
11
12
    /**
13
     * @param array  $props_n_values          incoming values
14
     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
15
     *                                        used.)
16
     * @param array  $date_formats            incoming date_formats in an array where the first value is the
17
     *                                        date_format and the second value is the time format
18
     * @return EE_Payment
19
     * @throws \EE_Error
20
     */
21
    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
22
    {
23
        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
24
        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
25
    }
26
27
28
    /**
29
     * @param array  $props_n_values  incoming values from the database
30
     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
31
     *                                the website will be used.
32
     * @return EE_Payment
33
     * @throws \EE_Error
34
     */
35
    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
36
    {
37
        return new self($props_n_values, true, $timezone);
38
    }
39
40
41
    /**
42
     * Set Transaction ID
43
     *
44
     * @access public
45
     * @param int $TXN_ID
46
     * @throws \EE_Error
47
     */
48
    public function set_transaction_id($TXN_ID = 0)
49
    {
50
        $this->set('TXN_ID', $TXN_ID);
51
    }
52
53
54
    /**
55
     * Gets the transaction related to this payment
56
     *
57
     * @return EE_Transaction
58
     * @throws \EE_Error
59
     */
60
    public function transaction()
61
    {
62
        return $this->get_first_related('Transaction');
63
    }
64
65
66
    /**
67
     * Set Status
68
     *
69
     * @access public
70
     * @param string $STS_ID
71
     * @throws \EE_Error
72
     */
73
    public function set_status($STS_ID = '')
74
    {
75
        $this->set('STS_ID', $STS_ID);
76
    }
77
78
79
    /**
80
     * Set Payment Timestamp
81
     *
82
     * @access public
83
     * @param int $timestamp
84
     * @throws \EE_Error
85
     */
86
    public function set_timestamp($timestamp = 0)
87
    {
88
        $this->set('PAY_timestamp', $timestamp);
89
    }
90
91
92
    /**
93
     * Set Payment Method
94
     *
95
     * @access public
96
     * @param string $PAY_source
97
     * @throws \EE_Error
98
     */
99
    public function set_source($PAY_source = '')
100
    {
101
        $this->set('PAY_source', $PAY_source);
102
    }
103
104
105
    /**
106
     * Set Payment Amount
107
     *
108
     * @access public
109
     * @param float $amount
110
     * @throws \EE_Error
111
     */
112
    public function set_amount($amount = 0.00)
113
    {
114
        $this->set('PAY_amount', (float) $amount);
115
    }
116
117
118
    /**
119
     * Set Payment Gateway Response
120
     *
121
     * @access public
122
     * @param string $gateway_response
123
     * @throws \EE_Error
124
     */
125
    public function set_gateway_response($gateway_response = '')
126
    {
127
        $this->set('PAY_gateway_response', $gateway_response);
128
    }
129
130
131
    /**
132
     * Returns the name of the payment method used on this payment (previously known merely as 'gateway')
133
     * but since 4.6.0, payment methods are models and the payment keeps a foreign key to the payment method
134
     * used on it
135
     *
136
     * @deprecated
137
     * @return string
138
     * @throws \EE_Error
139
     */
140
    public function gateway()
141
    {
142
        EE_Error::doing_it_wrong(
143
            'EE_Payment::gateway',
144
            __(
145
                'The method EE_Payment::gateway() has been deprecated. Consider instead using EE_Payment::payment_method()->name()',
146
                'event_espresso'
147
            ),
148
            '4.6.0'
149
        );
150
        return $this->payment_method() ? $this->payment_method()->name() : __('Unknown', 'event_espresso');
151
    }
152
153
154
    /**
155
     * Set Gateway Transaction ID
156
     *
157
     * @access public
158
     * @param string $txn_id_chq_nmbr
159
     * @throws \EE_Error
160
     */
161
    public function set_txn_id_chq_nmbr($txn_id_chq_nmbr = '')
162
    {
163
        $this->set('PAY_txn_id_chq_nmbr', $txn_id_chq_nmbr);
164
    }
165
166
167
    /**
168
     * Set Purchase Order Number
169
     *
170
     * @access public
171
     * @param string $po_number
172
     * @throws \EE_Error
173
     */
174
    public function set_po_number($po_number = '')
175
    {
176
        $this->set('PAY_po_number', $po_number);
177
    }
178
179
180
    /**
181
     * Set Extra Accounting Field
182
     *
183
     * @access public
184
     * @param string $extra_accntng
185
     * @throws \EE_Error
186
     */
187
    public function set_extra_accntng($extra_accntng = '')
188
    {
189
        $this->set('PAY_extra_accntng', $extra_accntng);
190
    }
191
192
193
    /**
194
     * Set Payment made via admin flag
195
     *
196
     * @access public
197
     * @param bool $via_admin
198
     * @throws \EE_Error
199
     */
200
    public function set_payment_made_via_admin($via_admin = false)
201
    {
202
        if ($via_admin) {
203
            $this->set('PAY_source', EEM_Payment_Method::scope_admin);
204
        } else {
205
            $this->set('PAY_source', EEM_Payment_Method::scope_cart);
206
        }
207
    }
208
209
210
    /**
211
     * Set Payment Details
212
     *
213
     * @access public
214
     * @param string|array $details
215
     * @throws \EE_Error
216
     */
217
    public function set_details($details = '')
218
    {
219 View Code Duplication
        if (is_array($details)) {
220
            array_walk_recursive($details, array($this, '_strip_all_tags_within_array'));
221
        } else {
222
            $details = wp_strip_all_tags($details);
223
        }
224
        $this->set('PAY_details', $details);
225
    }
226
227
228
    /**
229
     * Sets redirect_url
230
     *
231
     * @param string $redirect_url
232
     * @throws \EE_Error
233
     */
234
    public function set_redirect_url($redirect_url)
235
    {
236
        $this->set('PAY_redirect_url', $redirect_url);
237
    }
238
239
240
    /**
241
     * Sets redirect_args
242
     *
243
     * @param array $redirect_args
244
     * @throws \EE_Error
245
     */
246
    public function set_redirect_args($redirect_args)
247
    {
248
        $this->set('PAY_redirect_args', $redirect_args);
249
    }
250
251
252
    /**
253
     * get Payment Transaction ID
254
     *
255
     * @access public
256
     * @throws \EE_Error
257
     */
258
    public function TXN_ID()
259
    {
260
        return $this->get('TXN_ID');
261
    }
262
263
264
    /**
265
     * get Payment Status
266
     *
267
     * @access public
268
     * @throws \EE_Error
269
     */
270
    public function status()
271
    {
272
        return $this->get('STS_ID');
273
    }
274
275
276
    /**
277
     * get Payment Status
278
     *
279
     * @access public
280
     * @throws \EE_Error
281
     */
282
    public function STS_ID()
283
    {
284
        return $this->get('STS_ID');
285
    }
286
287
288
    /**
289
     * get Payment Timestamp
290
     *
291
     * @access public
292
     * @param string $dt_frmt
293
     * @param string $tm_frmt
294
     * @return string
295
     * @throws \EE_Error
296
     */
297
    public function timestamp($dt_frmt = '', $tm_frmt = '')
298
    {
299
        return $this->get_i18n_datetime('PAY_timestamp', trim($dt_frmt . ' ' . $tm_frmt));
300
    }
301
302
303
    /**
304
     * get Payment Source
305
     *
306
     * @access public
307
     * @throws \EE_Error
308
     */
309
    public function source()
310
    {
311
        return $this->get('PAY_source');
312
    }
313
314
315
    /**
316
     * get Payment Amount
317
     *
318
     * @access public
319
     * @return float
320
     * @throws \EE_Error
321
     */
322
    public function amount()
323
    {
324
        return (float) $this->get('PAY_amount');
325
    }
326
327
328
    /**
329
     * @return mixed
330
     * @throws \EE_Error
331
     */
332
    public function amount_no_code()
333
    {
334
        return $this->get_pretty('PAY_amount', 'no_currency_code');
335
    }
336
337
338
    /**
339
     * get Payment Gateway Response
340
     *
341
     * @access public
342
     * @throws \EE_Error
343
     */
344
    public function gateway_response()
345
    {
346
        return $this->get('PAY_gateway_response');
347
    }
348
349
350
    /**
351
     * get Payment Gateway Transaction ID
352
     *
353
     * @access public
354
     * @throws \EE_Error
355
     */
356
    public function txn_id_chq_nmbr()
357
    {
358
        return $this->get('PAY_txn_id_chq_nmbr');
359
    }
360
361
362
    /**
363
     * get Purchase Order Number
364
     *
365
     * @access public
366
     * @throws \EE_Error
367
     */
368
    public function po_number()
369
    {
370
        return $this->get('PAY_po_number');
371
    }
372
373
374
    /**
375
     * get Extra Accounting Field
376
     *
377
     * @access public
378
     * @throws \EE_Error
379
     */
380
    public function extra_accntng()
381
    {
382
        return $this->get('PAY_extra_accntng');
383
    }
384
385
386
    /**
387
     * get Payment made via admin source
388
     *
389
     * @access public
390
     * @throws \EE_Error
391
     */
392
    public function payment_made_via_admin()
393
    {
394
        return ($this->get('PAY_source') === EEM_Payment_Method::scope_admin);
395
    }
396
397
398
    /**
399
     * get Payment Details
400
     *
401
     * @access public
402
     * @throws \EE_Error
403
     */
404
    public function details()
405
    {
406
        return $this->get('PAY_details');
407
    }
408
409
410
    /**
411
     * Gets redirect_url
412
     *
413
     * @return string
414
     * @throws \EE_Error
415
     */
416
    public function redirect_url()
417
    {
418
        return $this->get('PAY_redirect_url');
419
    }
420
421
422
    /**
423
     * Gets redirect_args
424
     *
425
     * @return array
426
     * @throws \EE_Error
427
     */
428
    public function redirect_args()
429
    {
430
        return $this->get('PAY_redirect_args');
431
    }
432
433
434
    /**
435
     * echoes $this->pretty_status()
436
     *
437
     * @param bool $show_icons
438
     * @return void
439
     * @throws \EE_Error
440
     */
441
    public function e_pretty_status($show_icons = false)
442
    {
443
        echo $this->pretty_status($show_icons);
444
    }
445
446
447
    /**
448
     * returns a pretty version of the status, good for displaying to users
449
     *
450
     * @param bool $show_icons
451
     * @return string
452
     * @throws \EE_Error
453
     */
454
    public function pretty_status($show_icons = false)
455
    {
456
        $status = EEM_Status::instance()->localized_status(
457
            array($this->STS_ID() => __('unknown', 'event_espresso')),
458
            false,
459
            'sentence'
460
        );
461
        $icon = '';
462
        switch ($this->STS_ID()) {
463
            case EEM_Payment::status_id_approved:
464
                $icon = $show_icons
465
                    ? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>'
466
                    : '';
467
                break;
468
            case EEM_Payment::status_id_pending:
469
                $icon = $show_icons
470
                    ? '<span class="dashicons dashicons-clock ee-icon-size-16 orange-text"></span>'
471
                    : '';
472
                break;
473
            case EEM_Payment::status_id_cancelled:
474
                $icon = $show_icons
475
                    ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
476
                    : '';
477
                break;
478
            case EEM_Payment::status_id_declined:
479
                $icon = $show_icons
480
                    ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
481
                    : '';
482
                break;
483
        }
484
        return $icon . $status[ $this->STS_ID() ];
485
    }
486
487
488
    /**
489
     * For determining the status of the payment
490
     *
491
     * @return boolean whether the payment is approved or not
492
     * @throws \EE_Error
493
     */
494
    public function is_approved()
495
    {
496
        return $this->status_is(EEM_Payment::status_id_approved);
497
    }
498
499
500
    /**
501
     * Generally determines if the status of this payment equals
502
     * the $STS_ID string
503
     *
504
     * @param string $STS_ID an ID from the esp_status table/
505
     *                       one of the status_id_* on the EEM_Payment model
506
     * @return boolean whether the status of this payment equals the status id
507
     * @throws \EE_Error
508
     */
509
    protected function status_is($STS_ID)
510
    {
511
        return $STS_ID === $this->STS_ID() ? true : false;
512
    }
513
514
515
    /**
516
     * For determining the status of the payment
517
     *
518
     * @return boolean whether the payment is pending or not
519
     * @throws \EE_Error
520
     */
521
    public function is_pending()
522
    {
523
        return $this->status_is(EEM_Payment::status_id_pending);
524
    }
525
526
527
    /**
528
     * For determining the status of the payment
529
     *
530
     * @return boolean
531
     * @throws \EE_Error
532
     */
533
    public function is_cancelled()
534
    {
535
        return $this->status_is(EEM_Payment::status_id_cancelled);
536
    }
537
538
539
    /**
540
     * For determining the status of the payment
541
     *
542
     * @return boolean
543
     * @throws \EE_Error
544
     */
545
    public function is_declined()
546
    {
547
        return $this->status_is(EEM_Payment::status_id_declined);
548
    }
549
550
551
    /**
552
     * For determining the status of the payment
553
     *
554
     * @return boolean
555
     * @throws \EE_Error
556
     */
557
    public function is_failed()
558
    {
559
        return $this->status_is(EEM_Payment::status_id_failed);
560
    }
561
562
563
    /**
564
     * For determining if the payment is actually a refund ( ie: has a negative value )
565
     *
566
     * @return boolean
567
     * @throws \EE_Error
568
     */
569
    public function is_a_refund()
570
    {
571
        return $this->amount() < 0 ? true : false;
572
    }
573
574
575
    /**
576
     * Get the status object of this object
577
     *
578
     * @return EE_Status
579
     * @throws \EE_Error
580
     */
581
    public function status_obj()
582
    {
583
        return $this->get_first_related('Status');
584
    }
585
586
587
    /**
588
     * Gets all the extra meta info on this payment
589
     *
590
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
591
     * @return EE_Extra_Meta
592
     * @throws \EE_Error
593
     */
594
    public function extra_meta($query_params = array())
595
    {
596
        return $this->get_many_related('Extra_Meta', $query_params);
597
    }
598
599
600
    /**
601
     * Gets the last-used payment method on this transaction
602
     * (we COULD just use the last-made payment, but some payment methods, namely
603
     * offline ones, dont' create payments)
604
     *
605
     * @return EE_Payment_Method
606
     * @throws \EE_Error
607
     */
608
    public function payment_method()
609
    {
610
        return $this->get_first_related('Payment_Method');
611
    }
612
613
614
    /**
615
     * Gets the HTML for redirecting the user to an offsite gateway
616
     * You can pass it special content to put inside the form, or use
617
     * the default inner content (or possibly generate this all yourself using
618
     * redirect_url() and redirect_args() or redirect_args_as_inputs()).
619
     * Creates a POST request by default, but if no redirect args are specified, creates a GET request instead
620
     * (and any querystring variables in the redirect_url are converted into html inputs
621
     * so browsers submit them properly)
622
     *
623
     * @param string $inside_form_html
624
     * @return string html
625
     * @throws \EE_Error
626
     */
627
    public function redirect_form($inside_form_html = null)
628
    {
629
        $redirect_url = $this->redirect_url();
630
        if (! empty($redirect_url)) {
631
            // what ? no inner form content?
632
            if ($inside_form_html === null) {
633
                $inside_form_html = EEH_HTML::p(
634
                    sprintf(
635
                        __(
636
                            'If you are not automatically redirected to the payment website within 10 seconds... %1$s %2$s Click Here %3$s',
637
                            'event_espresso'
638
                        ),
639
                        EEH_HTML::br(2),
640
                        '<input type="submit" value="',
641
                        '">'
642
                    ),
643
                    '',
644
                    '',
645
                    'text-align:center;'
646
                );
647
            }
648
            $method = apply_filters(
649
                'FHEE__EE_Payment__redirect_form__method',
650
                $this->redirect_args() ? 'POST' : 'GET',
651
                $this
652
            );
653
            // if it's a GET request, we need to remove all the GET params in the querystring
654
            // and put them into the form instead
655
            if ($method === 'GET') {
656
                $querystring = parse_url($redirect_url, PHP_URL_QUERY);
657
                $get_params = null;
658
                parse_str($querystring, $get_params);
659
                $inside_form_html .= $this->_args_as_inputs($get_params);
660
                $redirect_url = str_replace('?' . $querystring, '', $redirect_url);
661
            }
662
            $form = EEH_HTML::nl(1)
663
                    . '<form method="'
664
                    . $method
665
                    . '" name="gateway_form" action="'
666
                    . $redirect_url
667
                    . '">';
668
            $form .= EEH_HTML::nl(1) . $this->redirect_args_as_inputs();
669
            $form .= $inside_form_html;
670
            $form .= EEH_HTML::nl(-1) . '</form>' . EEH_HTML::nl(-1);
671
            return $form;
672
        } else {
673
            return null;
674
        }
675
    }
676
677
678
    /**
679
     * Changes all the name-value pairs of the redirect args into html inputs
680
     * and returns the html as a string
681
     *
682
     * @return string
683
     * @throws \EE_Error
684
     */
685
    public function redirect_args_as_inputs()
686
    {
687
        return $this->_args_as_inputs($this->redirect_args());
688
    }
689
690
691
    /**
692
     * Converts a 2d array of key-value pairs into html hidden inputs
693
     * and returns the string of html
694
     *
695
     * @param array $args key-value pairs
696
     * @return string
697
     */
698
    protected function _args_as_inputs($args)
699
    {
700
        $html = '';
701
        if ($args !== null && is_array($args)) {
702
            foreach ($args as $name => $value) {
703
                $html .= $this->generateInput($name, $value);
704
            }
705
        }
706
        return $html;
707
    }
708
709
    /**
710
     * Converts either a single name and value or array of values into html hidden inputs
711
     * and returns the string of html
712
     *
713
     * @param string $name
714
     * @param string|array $value
715
     * @return string
716
     */
717
    private function generateInput($name, $value)
718
    {
719
        if (is_array($value)) {
720
            $html = '';
721
            $name = "{$name}[]";
722
            foreach ($value as $array_value) {
723
                $html .= $this->generateInput($name, $array_value);
724
            }
725
            return $html;
726
        }
727
        return EEH_HTML::nl()
728
            . '<input type="hidden" name="' . $name . '"'
729
            . ' value="' . esc_attr($value) . '"/>';
730
    }
731
732
733
    /**
734
     * Returns the currency of the payment.
735
     * (At the time of writing, this will always be the currency in the configuration;
736
     * however in the future it is anticipated that this will be stored on the payment
737
     * object itself)
738
     *
739
     * @return string for the currency code
740
     */
741
    public function currency_code()
742
    {
743
        return EE_Config::instance()->currency->code;
744
    }
745
746
747
    /**
748
     * apply wp_strip_all_tags to all elements within an array
749
     *
750
     * @access private
751
     * @param mixed $item
752
     */
753
    private function _strip_all_tags_within_array(&$item)
754
    {
755
        if (is_object($item)) {
756
            $item = (array) $item;
757
        }
758 View Code Duplication
        if (is_array($item)) {
759
            array_walk_recursive($item, array($this, '_strip_all_tags_within_array'));
760
        } else {
761
            $item = wp_strip_all_tags($item);
762
        }
763
    }
764
765
766
    /**
767
     * Returns TRUE is this payment was set to approved during this request (or
768
     * is approved and was created during this request). False otherwise.
769
     *
770
     * @return boolean
771
     * @throws \EE_Error
772
     */
773
    public function just_approved()
774
    {
775
        $original_status = EEH_Array::is_set(
776
            $this->_props_n_values_provided_in_constructor,
777
            'STS_ID',
778
            $this->get_model()->field_settings_for('STS_ID')->get_default_value()
779
        );
780
        $current_status = $this->status();
781
        if ($original_status !== EEM_Payment::status_id_approved
782
            && $current_status === EEM_Payment::status_id_approved
783
        ) {
784
            return true;
785
        } else {
786
            return false;
787
        }
788
    }
789
790
791
    /**
792
     * Overrides parents' get_pretty() function just for legacy reasons
793
     * (to allow ticket https://events.codebasehq.com/projects/event-espresso/tickets/7420)
794
     *
795
     * @param string $field_name
796
     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
797
     *                                (in cases where the same property may be used for different outputs
798
     *                                - i.e. datetime, money etc.)
799
     * @return mixed
800
     * @throws \EE_Error
801
     */
802
    public function get_pretty($field_name, $extra_cache_ref = null)
803
    {
804
        if ($field_name === 'PAY_gateway') {
805
            return $this->payment_method() ? $this->payment_method()->name() : __('Unknown', 'event_espresso');
806
        }
807
        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
808
    }
809
810
811
    /**
812
     * Gets details regarding which registrations this payment was applied to
813
     *
814
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
815
     * @return EE_Registration_Payment[]
816
     * @throws \EE_Error
817
     */
818
    public function registration_payments($query_params = array())
819
    {
820
        return $this->get_many_related('Registration_Payment', $query_params);
821
    }
822
823
824
    /**
825
     * Gets the first event for this payment (it's possible that it could be for multiple)
826
     *
827
     * @return EE_Event|null
828
     */
829
    public function get_first_event()
830
    {
831
        $transaction = $this->transaction();
832
        if ($transaction instanceof EE_Transaction) {
833
            $primary_registrant = $transaction->primary_registration();
834
            if ($primary_registrant instanceof EE_Registration) {
835
                return $primary_registrant->event_obj();
836
            }
837
        }
838
        return null;
839
    }
840
841
842
    /**
843
     * Gets the name of the first event for which is being paid
844
     *
845
     * @return string
846
     */
847
    public function get_first_event_name()
848
    {
849
        $event = $this->get_first_event();
850
        return $event instanceof EE_Event ? $event->name() : __('Event', 'event_espresso');
851
    }
852
853
854
    /**
855
     * Returns the payment's transaction's primary registration
856
     *
857
     * @return EE_Registration|null
858
     */
859
    public function get_primary_registration()
860
    {
861
        if ($this->transaction() instanceof EE_Transaction) {
862
            return $this->transaction()->primary_registration();
863
        }
864
        return null;
865
    }
866
867
868
    /**
869
     * Gets the payment's transaction's primary registration's attendee, or null
870
     *
871
     * @return EE_Attendee|null
872
     */
873
    public function get_primary_attendee()
874
    {
875
        $primary_reg = $this->get_primary_registration();
876
        if ($primary_reg instanceof EE_Registration) {
877
            return $primary_reg->attendee();
878
        }
879
        return null;
880
    }
881
}
882