Completed
Branch FET/recalculate-line-items (43485e)
by
unknown
18:22 queued 08:59
created

Transactions_Admin_Page::getActionButtons()   D

Complexity

Conditions 14
Paths 225

Size

Total Lines 90

Duplication

Lines 39
Ratio 43.33 %

Importance

Changes 0
Metric Value
cc 14
nc 225
nop 1
dl 39
loc 90
rs 4.3148
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use EventEspresso\core\exceptions\InvalidDataTypeException;
4
use EventEspresso\core\exceptions\InvalidInterfaceException;
5
6
/**
7
 * EE_Admin_Transactions class
8
 *
9
 * @package               Event Espresso
10
 * @subpackage            includes/core/admin/transactions/Transactions_Admin_Page.core.php
11
 * @author                Brent Christensen
12
 * ------------------------------------------------------------------------
13
 */
14
class Transactions_Admin_Page extends EE_Admin_Page
15
{
16
17
    /**
18
     * @var EE_Transaction
19
     */
20
    private $_transaction;
21
22
    /**
23
     * @var EE_Session
24
     */
25
    private $_session;
26
27
    /**
28
     * @var array $_txn_status
29
     */
30
    private static $_txn_status;
31
32
    /**
33
     * @var array $_pay_status
34
     */
35
    private static $_pay_status;
36
37
    /**
38
     * @var array $_existing_reg_payment_REG_IDs
39
     */
40
    protected $_existing_reg_payment_REG_IDs = null;
41
42
43
    /**
44
     * @Constructor
45
     * @access public
46
     * @param bool $routing
47
     * @throws EE_Error
48
     * @throws InvalidArgumentException
49
     * @throws ReflectionException
50
     * @throws InvalidDataTypeException
51
     * @throws InvalidInterfaceException
52
     */
53
    public function __construct($routing = true)
54
    {
55
        parent::__construct($routing);
56
    }
57
58
59
    /**
60
     *    _init_page_props
61
     *
62
     * @return void
63
     */
64 View Code Duplication
    protected function _init_page_props()
65
    {
66
        $this->page_slug = TXN_PG_SLUG;
67
        $this->page_label = esc_html__('Transactions', 'event_espresso');
68
        $this->_admin_base_url = TXN_ADMIN_URL;
69
        $this->_admin_base_path = TXN_ADMIN;
70
    }
71
72
73
    /**
74
     *    _ajax_hooks
75
     *
76
     * @return void
77
     */
78
    protected function _ajax_hooks()
79
    {
80
        add_action('wp_ajax_espresso_apply_payment', array($this, 'apply_payments_or_refunds'));
81
        add_action('wp_ajax_espresso_apply_refund', array($this, 'apply_payments_or_refunds'));
82
        add_action('wp_ajax_espresso_delete_payment', array($this, 'delete_payment'));
83
    }
84
85
86
    /**
87
     *    _define_page_props
88
     *
89
     * @return void
90
     */
91 View Code Duplication
    protected function _define_page_props()
92
    {
93
        $this->_admin_page_title = $this->page_label;
94
        $this->_labels = array(
95
            'buttons' => array(
96
                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
97
                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
98
                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
99
            ),
100
        );
101
    }
102
103
104
    /**
105
     *        grab url requests and route them
106
     *
107
     * @access private
108
     * @return void
109
     * @throws EE_Error
110
     * @throws InvalidArgumentException
111
     * @throws InvalidDataTypeException
112
     * @throws InvalidInterfaceException
113
     */
114
    public function _set_page_routes()
115
    {
116
117
        $this->_set_transaction_status_array();
118
119
        $txn_id = ! empty($this->_req_data['TXN_ID'])
120
                  && ! is_array($this->_req_data['TXN_ID'])
121
            ? $this->_req_data['TXN_ID']
122
            : 0;
123
124
        $this->_page_routes = array(
125
126
            'default' => array(
127
                'func'       => '_transactions_overview_list_table',
128
                'capability' => 'ee_read_transactions',
129
            ),
130
131
            'view_transaction' => array(
132
                'func'       => '_transaction_details',
133
                'capability' => 'ee_read_transaction',
134
                'obj_id'     => $txn_id,
135
            ),
136
137
            'send_payment_reminder' => array(
138
                'func'       => '_send_payment_reminder',
139
                'noheader'   => true,
140
                'capability' => 'ee_send_message',
141
            ),
142
143
            'espresso_apply_payment' => array(
144
                'func'       => 'apply_payments_or_refunds',
145
                'noheader'   => true,
146
                'capability' => 'ee_edit_payments',
147
            ),
148
149
            'espresso_apply_refund' => array(
150
                'func'       => 'apply_payments_or_refunds',
151
                'noheader'   => true,
152
                'capability' => 'ee_edit_payments',
153
            ),
154
155
            'espresso_delete_payment' => array(
156
                'func'       => 'delete_payment',
157
                'noheader'   => true,
158
                'capability' => 'ee_delete_payments',
159
            ),
160
161
            'espresso_recalculate_line_items' => array(
162
                'func'       => 'recalculateLineItems',
163
                'noheader'   => true,
164
                'capability' => 'ee_edit_payments',
165
            ),
166
167
        );
168
    }
169
170
171
    protected function _set_page_config()
172
    {
173
        $this->_page_config = array(
174
            'default'          => array(
175
                'nav'           => array(
176
                    'label' => esc_html__('Overview', 'event_espresso'),
177
                    'order' => 10,
178
                ),
179
                'list_table'    => 'EE_Admin_Transactions_List_Table',
180
                'help_tabs'     => array(
181
                    'transactions_overview_help_tab'                       => array(
182
                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
183
                        'filename' => 'transactions_overview',
184
                    ),
185
                    'transactions_overview_table_column_headings_help_tab' => array(
186
                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
187
                        'filename' => 'transactions_overview_table_column_headings',
188
                    ),
189
                    'transactions_overview_views_filters_help_tab'         => array(
190
                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
191
                        'filename' => 'transactions_overview_views_filters_search',
192
                    ),
193
                ),
194
                'help_tour'     => array('Transactions_Overview_Help_Tour'),
195
                /**
196
                 * commented out because currently we are not displaying tips for transaction list table status but this
197
                 * may change in a later iteration so want to keep the code for then.
198
                 */
199
                // 'qtips' => array( 'Transactions_List_Table_Tips' ),
200
                'require_nonce' => false,
201
            ),
202
            'view_transaction' => array(
203
                'nav'       => array(
204
                    'label'      => esc_html__('View Transaction', 'event_espresso'),
205
                    'order'      => 5,
206
                    'url'        => isset($this->_req_data['TXN_ID'])
207
                        ? add_query_arg(array('TXN_ID' => $this->_req_data['TXN_ID']), $this->_current_page_view_url)
208
                        : $this->_admin_base_url,
209
                    'persistent' => false,
210
                ),
211
                'help_tabs' => array(
212
                    'transactions_view_transaction_help_tab'                                              => array(
213
                        'title'    => esc_html__('View Transaction', 'event_espresso'),
214
                        'filename' => 'transactions_view_transaction',
215
                    ),
216
                    'transactions_view_transaction_transaction_details_table_help_tab'                    => array(
217
                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
218
                        'filename' => 'transactions_view_transaction_transaction_details_table',
219
                    ),
220
                    'transactions_view_transaction_attendees_registered_help_tab'                         => array(
221
                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
222
                        'filename' => 'transactions_view_transaction_attendees_registered',
223
                    ),
224
                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => array(
225
                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
226
                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
227
                    ),
228
                ),
229
                'qtips'     => array('Transaction_Details_Tips'),
230
                'help_tour' => array('Transaction_Details_Help_Tour'),
231
                'metaboxes' => array('_transaction_details_metaboxes'),
232
233
                'require_nonce' => false,
234
            ),
235
        );
236
    }
237
238
239
    /**
240
     * The below methods aren't used by this class currently
241
     */
242
    protected function _add_screen_options()
243
    {
244
        // noop
245
    }
246
247
    protected function _add_feature_pointers()
248
    {
249
        // noop
250
    }
251
252
    public function admin_init()
253
    {
254
        // IF a registration was JUST added via the admin...
255
        if (isset(
256
            $this->_req_data['redirect_from'],
257
            $this->_req_data['EVT_ID'],
258
            $this->_req_data['event_name']
259
        )) {
260
            // then set a cookie so that we can block any attempts to use
261
            // the back button as a way to enter another registration.
262
            setcookie(
263
                'ee_registration_added',
264
                $this->_req_data['EVT_ID'],
265
                time() + WEEK_IN_SECONDS,
266
                '/'
267
            );
268
            // and update the global
269
            $_COOKIE['ee_registration_added'] = $this->_req_data['EVT_ID'];
270
        }
271
        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
272
            'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
273
            'event_espresso'
274
        );
275
        EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
276
            'An error occurred! Please refresh the page and try again.',
277
            'event_espresso'
278
        );
279
        EE_Registry::$i18n_js_strings['txn_status_array'] = self::$_txn_status;
280
        EE_Registry::$i18n_js_strings['pay_status_array'] = self::$_pay_status;
281
        EE_Registry::$i18n_js_strings['payments_total'] = esc_html__('Payments Total', 'event_espresso');
282
        EE_Registry::$i18n_js_strings['transaction_overpaid'] = esc_html__(
283
            'This transaction has been overpaid ! Payments Total',
284
            'event_espresso'
285
        );
286
    }
287
288
    public function admin_notices()
289
    {
290
        // noop
291
    }
292
293
    public function admin_footer_scripts()
294
    {
295
        // noop
296
    }
297
298
299
    /**
300
     * _set_transaction_status_array
301
     * sets list of transaction statuses
302
     *
303
     * @access private
304
     * @return void
305
     * @throws EE_Error
306
     * @throws InvalidArgumentException
307
     * @throws InvalidDataTypeException
308
     * @throws InvalidInterfaceException
309
     */
310
    private function _set_transaction_status_array()
311
    {
312
        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
313
    }
314
315
316
    /**
317
     * get_transaction_status_array
318
     * return the transaction status array for wp_list_table
319
     *
320
     * @access public
321
     * @return array
322
     */
323
    public function get_transaction_status_array()
324
    {
325
        return self::$_txn_status;
326
    }
327
328
329
    /**
330
     *    get list of payment statuses
331
     *
332
     * @access private
333
     * @return void
334
     * @throws EE_Error
335
     * @throws InvalidArgumentException
336
     * @throws InvalidDataTypeException
337
     * @throws InvalidInterfaceException
338
     */
339
    private function _get_payment_status_array()
340
    {
341
        self::$_pay_status = EEM_Payment::instance()->status_array(true);
342
        $this->_template_args['payment_status'] = self::$_pay_status;
343
    }
344
345
346
    /**
347
     *    _add_screen_options_default
348
     *
349
     * @access protected
350
     * @return void
351
     * @throws InvalidArgumentException
352
     * @throws InvalidDataTypeException
353
     * @throws InvalidInterfaceException
354
     */
355
    protected function _add_screen_options_default()
356
    {
357
        $this->_per_page_screen_option();
358
    }
359
360
361
    /**
362
     * load_scripts_styles
363
     *
364
     * @access public
365
     * @return void
366
     */
367
    public function load_scripts_styles()
368
    {
369
        // enqueue style
370
        wp_register_style(
371
            'espresso_txn',
372
            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
373
            array(),
374
            EVENT_ESPRESSO_VERSION
375
        );
376
        wp_enqueue_style('espresso_txn');
377
        // scripts
378
        wp_register_script(
379
            'espresso_txn',
380
            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
381
            array(
382
                'ee_admin_js',
383
                'ee-datepicker',
384
                'jquery-ui-datepicker',
385
                'jquery-ui-draggable',
386
                'ee-dialog',
387
                'ee-accounting',
388
                'ee-serialize-full-array',
389
            ),
390
            EVENT_ESPRESSO_VERSION,
391
            true
392
        );
393
        wp_enqueue_script('espresso_txn');
394
    }
395
396
397
    /**
398
     *    load_scripts_styles_view_transaction
399
     *
400
     * @access public
401
     * @return void
402
     */
403
    public function load_scripts_styles_view_transaction()
404
    {
405
        // styles
406
        wp_enqueue_style('espresso-ui-theme');
407
    }
408
409
410
    /**
411
     *    load_scripts_styles_default
412
     *
413
     * @access public
414
     * @return void
415
     */
416
    public function load_scripts_styles_default()
417
    {
418
        // styles
419
        wp_enqueue_style('espresso-ui-theme');
420
    }
421
422
423
    /**
424
     *    _set_list_table_views_default
425
     *
426
     * @access protected
427
     * @return void
428
     */
429
    protected function _set_list_table_views_default()
430
    {
431
        $this->_views = array(
432
            'all'       => array(
433
                'slug'  => 'all',
434
                'label' => esc_html__('View All Transactions', 'event_espresso'),
435
                'count' => 0,
436
            ),
437
            'abandoned' => array(
438
                'slug'  => 'abandoned',
439
                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
440
                'count' => 0,
441
            ),
442
            'incomplete' => array(
443
                'slug'  => 'incomplete',
444
                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
445
                'count' => 0,
446
            )
447
        );
448
        if (/**
449
             * Filters whether a link to the "Failed Transactions" list table
450
             * appears on the Transactions Admin Page list table.
451
             * List display can be turned back on via the following:
452
             * add_filter(
453
             *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
454
             *     '__return_true'
455
             * );
456
             *
457
             * @since 4.9.70.p
458
             * @param boolean                 $display_failed_txns_list
459
             * @param Transactions_Admin_Page $this
460
             */
461
            apply_filters(
462
                'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
463
                false,
464
                $this
465
            )
466
        ) {
467
            $this->_views['failed'] = array(
468
                'slug'  => 'failed',
469
                'label' => esc_html__('Failed Transactions', 'event_espresso'),
470
                'count' => 0,
471
            );
472
        }
473
    }
474
475
476
    /**
477
     * _set_transaction_object
478
     * This sets the _transaction property for the transaction details screen
479
     *
480
     * @access private
481
     * @return void
482
     * @throws EE_Error
483
     * @throws InvalidArgumentException
484
     * @throws RuntimeException
485
     * @throws InvalidDataTypeException
486
     * @throws InvalidInterfaceException
487
     * @throws ReflectionException
488
     */
489
    private function _set_transaction_object()
490
    {
491
        if ($this->_transaction instanceof EE_Transaction) {
492
            return;
493
        } //get out we've already set the object
494
495
        $TXN_ID = ! empty($this->_req_data['TXN_ID'])
496
            ? absint($this->_req_data['TXN_ID'])
497
            : false;
498
499
        // get transaction object
500
        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
501
        $this->_session = $this->_transaction instanceof EE_Transaction
502
            ? $this->_transaction->get('TXN_session_data')
503
            : null;
504
        if ($this->_transaction instanceof EE_Transaction) {
505
            $this->_transaction->verify_abandoned_transaction_status();
506
        }
507
508 View Code Duplication
        if (! $this->_transaction instanceof EE_Transaction) {
509
            $error_msg = sprintf(
510
                esc_html__(
511
                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
512
                    'event_espresso'
513
                ),
514
                $TXN_ID
515
            );
516
            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
517
        }
518
    }
519
520
521
    /**
522
     *    _transaction_legend_items
523
     *
524
     * @access protected
525
     * @return array
526
     * @throws EE_Error
527
     * @throws InvalidArgumentException
528
     * @throws ReflectionException
529
     * @throws InvalidDataTypeException
530
     * @throws InvalidInterfaceException
531
     */
532
    protected function _transaction_legend_items()
533
    {
534
        EE_Registry::instance()->load_helper('MSG_Template');
535
        $items = array();
536
537 View Code Duplication
        if (EE_Registry::instance()->CAP->current_user_can(
538
            'ee_read_global_messages',
539
            'view_filtered_messages'
540
        )) {
541
            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
542
            if (is_array($related_for_icon)
543
                && isset($related_for_icon['css_class'], $related_for_icon['label'])
544
            ) {
545
                $items['view_related_messages'] = array(
546
                    'class' => $related_for_icon['css_class'],
547
                    'desc'  => $related_for_icon['label'],
548
                );
549
            }
550
        }
551
552
        $items = apply_filters(
553
            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
554
            array_merge(
555
                $items,
556
                array(
557
                    'view_details'          => array(
558
                        'class' => 'dashicons dashicons-cart',
559
                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
560
                    ),
561
                    'view_invoice'          => array(
562
                        'class' => 'dashicons dashicons-media-spreadsheet',
563
                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
564
                    ),
565
                    'view_receipt'          => array(
566
                        'class' => 'dashicons dashicons-media-default',
567
                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
568
                    ),
569
                    'view_registration'     => array(
570
                        'class' => 'dashicons dashicons-clipboard',
571
                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
572
                    ),
573
                    'payment_overview_link' => array(
574
                        'class' => 'dashicons dashicons-money',
575
                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
576
                    ),
577
                )
578
            )
579
        );
580
581
        if (EE_Registry::instance()->CAP->current_user_can(
582
            'ee_send_message',
583
            'espresso_transactions_send_payment_reminder'
584
        )) {
585
            if (EEH_MSG_Template::is_mt_active('payment_reminder')) {
586
                $items['send_payment_reminder'] = array(
587
                    'class' => 'dashicons dashicons-email-alt',
588
                    'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
589
                );
590
            } else {
591
                $items['blank*'] = array(
592
                    'class' => '',
593
                    'desc'  => '',
594
                );
595
            }
596
        } else {
597
            $items['blank*'] = array(
598
                'class' => '',
599
                'desc'  => '',
600
            );
601
        }
602
        $more_items = apply_filters(
603
            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
604
            array(
605
                'overpaid'   => array(
606
                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
607
                    'desc'  => EEH_Template::pretty_status(
608
                        EEM_Transaction::overpaid_status_code,
609
                        false,
610
                        'sentence'
611
                    ),
612
                ),
613
                'complete'   => array(
614
                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
615
                    'desc'  => EEH_Template::pretty_status(
616
                        EEM_Transaction::complete_status_code,
617
                        false,
618
                        'sentence'
619
                    ),
620
                ),
621
                'incomplete' => array(
622
                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
623
                    'desc'  => EEH_Template::pretty_status(
624
                        EEM_Transaction::incomplete_status_code,
625
                        false,
626
                        'sentence'
627
                    ),
628
                ),
629
                'abandoned'  => array(
630
                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
631
                    'desc'  => EEH_Template::pretty_status(
632
                        EEM_Transaction::abandoned_status_code,
633
                        false,
634
                        'sentence'
635
                    ),
636
                ),
637
                'failed'     => array(
638
                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
639
                    'desc'  => EEH_Template::pretty_status(
640
                        EEM_Transaction::failed_status_code,
641
                        false,
642
                        'sentence'
643
                    ),
644
                ),
645
            )
646
        );
647
648
        return array_merge($items, $more_items);
649
    }
650
651
652
    /**
653
     *    _transactions_overview_list_table
654
     *
655
     * @access protected
656
     * @return void
657
     * @throws DomainException
658
     * @throws EE_Error
659
     * @throws InvalidArgumentException
660
     * @throws InvalidDataTypeException
661
     * @throws InvalidInterfaceException
662
     * @throws ReflectionException
663
     */
664
    protected function _transactions_overview_list_table()
665
    {
666
        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
667
        $event = isset($this->_req_data['EVT_ID'])
668
            ? EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID'])
669
            : null;
670
        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
671
            ? sprintf(
672
                esc_html__(
673
                    '%sViewing Transactions for the Event: %s%s',
674
                    'event_espresso'
675
                ),
676
                '<h3>',
677
                '<a href="'
678
                . EE_Admin_Page::add_query_args_and_nonce(
679
                    array('action' => 'edit', 'post' => $event->ID()),
680
                    EVENTS_ADMIN_URL
681
                )
682
                . '" title="'
683
                . esc_attr__(
684
                    'Click to Edit event',
685
                    'event_espresso'
686
                )
687
                . '">' . $event->get('EVT_name') . '</a>',
688
                '</h3>'
689
            )
690
            : '';
691
        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
692
        $this->display_admin_list_table_page_with_no_sidebar();
693
    }
694
695
696
    /**
697
     *    _transaction_details
698
     * generates HTML for the View Transaction Details Admin page
699
     *
700
     * @access protected
701
     * @return void
702
     * @throws DomainException
703
     * @throws EE_Error
704
     * @throws InvalidArgumentException
705
     * @throws InvalidDataTypeException
706
     * @throws InvalidInterfaceException
707
     * @throws RuntimeException
708
     * @throws ReflectionException
709
     */
710
    protected function _transaction_details()
711
    {
712
        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
713
714
        $this->_set_transaction_status_array();
715
716
        $this->_template_args = array();
717
        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
718
719
        $this->_set_transaction_object();
720
721
        if (! $this->_transaction instanceof EE_Transaction) {
722
            return;
723
        }
724
        $primary_registration = $this->_transaction->primary_registration();
725
        $attendee = $primary_registration instanceof EE_Registration
0 ignored issues
show
Unused Code introduced by
$attendee is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
726
            ? $primary_registration->attendee()
727
            : null;
728
729
        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
730
        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
731
732
        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
733
        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
734
735
        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->get('STS_ID') ];
736
        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
737
        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->get('STS_ID');
738
739
        $this->_template_args['grand_total'] = $this->_transaction->get('TXN_total');
740
        $this->_template_args['total_paid'] = $this->_transaction->get('TXN_paid');
741
742
        $amount_due = $this->_transaction->get('TXN_total') - $this->_transaction->get('TXN_paid');
743
        $this->_template_args['amount_due'] = EEH_Template::format_currency(
744
            $amount_due,
745
            true
746
        );
747
        if (EE_Registry::instance()->CFG->currency->sign_b4) {
748
            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
749
                                                  . $this->_template_args['amount_due'];
750
        } else {
751
            $this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
752
        }
753
        $this->_template_args['amount_due_class'] = '';
754
755
        if ($this->_transaction->get('TXN_paid') == $this->_transaction->get('TXN_total')) {
756
            // paid in full
757
            $this->_template_args['amount_due'] = false;
758 View Code Duplication
        } elseif ($this->_transaction->get('TXN_paid') > $this->_transaction->get('TXN_total')) {
759
            // overpaid
760
            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
761
        } elseif ($this->_transaction->get('TXN_total') > 0
762
                  && $this->_transaction->get('TXN_paid') > 0
763
        ) {
764
            // monies owing
765
            $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
766 View Code Duplication
        } elseif ($this->_transaction->get('TXN_total') > 0
767
                  && $this->_transaction->get('TXN_paid') == 0
768
        ) {
769
            // no payments made yet
770
            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
771
        } elseif ($this->_transaction->get('TXN_total') == 0) {
772
            // free event
773
            $this->_template_args['amount_due'] = false;
774
        }
775
776
        $payment_method = $this->_transaction->payment_method();
777
778
        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
779
            ? $payment_method->admin_name()
780
            : esc_html__('Unknown', 'event_espresso');
781
782
        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
783
        // link back to overview
784
        $this->_template_args['txn_overview_url'] = ! empty($_SERVER['HTTP_REFERER'])
785
            ? $_SERVER['HTTP_REFERER']
786
            : TXN_ADMIN_URL;
787
788
789
        // next link
790
        $next_txn = $this->_transaction->next(
791
            null,
792
            array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
793
            'TXN_ID'
794
        );
795
        $this->_template_args['next_transaction'] = $next_txn
796
            ? $this->_next_link(
797
                EE_Admin_Page::add_query_args_and_nonce(
798
                    array('action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']),
799
                    TXN_ADMIN_URL
800
                ),
801
                'dashicons dashicons-arrow-right ee-icon-size-22'
802
            )
803
            : '';
804
        // previous link
805
        $previous_txn = $this->_transaction->previous(
806
            null,
807
            array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
808
            'TXN_ID'
809
        );
810
        $this->_template_args['previous_transaction'] = $previous_txn
811
            ? $this->_previous_link(
812
                EE_Admin_Page::add_query_args_and_nonce(
813
                    array('action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']),
814
                    TXN_ADMIN_URL
815
                ),
816
                'dashicons dashicons-arrow-left ee-icon-size-22'
817
            )
818
            : '';
819
820
        // were we just redirected here after adding a new registration ???
821
        if (isset(
822
            $this->_req_data['redirect_from'],
823
            $this->_req_data['EVT_ID'],
824
            $this->_req_data['event_name']
825
        )) {
826
            if (EE_Registry::instance()->CAP->current_user_can(
827
                'ee_edit_registrations',
828
                'espresso_registrations_new_registration',
829
                $this->_req_data['EVT_ID']
830
            )) {
831
                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
832
                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
833
                    array(
834
                        'page'     => 'espresso_registrations',
835
                        'action'   => 'new_registration',
836
                        'return'   => 'default',
837
                        'TXN_ID'   => $this->_transaction->ID(),
838
                        'event_id' => $this->_req_data['EVT_ID'],
839
                    ),
840
                    REG_ADMIN_URL
841
                );
842
                $this->_admin_page_title .= '">';
843
844
                $this->_admin_page_title .= sprintf(
845
                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
846
                    htmlentities(urldecode($this->_req_data['event_name']), ENT_QUOTES, 'UTF-8')
847
                );
848
                $this->_admin_page_title .= '</a>';
849
            }
850
            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
851
        }
852
        // grab messages at the last second
853
        $this->_template_args['notices'] = EE_Error::get_notices();
854
        // path to template
855
        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
856
        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
857
            $template_path,
858
            $this->_template_args,
859
            true
860
        );
861
862
        // the details template wrapper
863
        $this->display_admin_page_with_sidebar();
864
    }
865
866
867
    /**
868
     *        _transaction_details_metaboxes
869
     *
870
     * @access protected
871
     * @return void
872
     * @throws EE_Error
873
     * @throws InvalidArgumentException
874
     * @throws InvalidDataTypeException
875
     * @throws InvalidInterfaceException
876
     * @throws RuntimeException
877
     * @throws ReflectionException
878
     */
879
    protected function _transaction_details_metaboxes()
880
    {
881
882
        $this->_set_transaction_object();
883
884
        if (! $this->_transaction instanceof EE_Transaction) {
885
            return;
886
        }
887
        add_meta_box(
888
            'edit-txn-details-mbox',
889
            esc_html__('Transaction Details', 'event_espresso'),
890
            array($this, 'txn_details_meta_box'),
891
            $this->_wp_page_slug,
892
            'normal',
893
            'high'
894
        );
895
        add_meta_box(
896
            'edit-txn-attendees-mbox',
897
            esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
898
            array($this, 'txn_attendees_meta_box'),
899
            $this->_wp_page_slug,
900
            'normal',
901
            'high',
902
            array('TXN_ID' => $this->_transaction->ID())
903
        );
904
        add_meta_box(
905
            'edit-txn-registrant-mbox',
906
            esc_html__('Primary Contact', 'event_espresso'),
907
            array($this, 'txn_registrant_side_meta_box'),
908
            $this->_wp_page_slug,
909
            'side',
910
            'high'
911
        );
912
        add_meta_box(
913
            'edit-txn-billing-info-mbox',
914
            esc_html__('Billing Information', 'event_espresso'),
915
            array($this, 'txn_billing_info_side_meta_box'),
916
            $this->_wp_page_slug,
917
            'side',
918
            'high'
919
        );
920
    }
921
922
923
    /**
924
     * Callback for transaction actions metabox.
925
     *
926
     * @param EE_Transaction|null $transaction
927
     * @throws DomainException
928
     * @throws EE_Error
929
     * @throws InvalidArgumentException
930
     * @throws InvalidDataTypeException
931
     * @throws InvalidInterfaceException
932
     * @throws ReflectionException
933
     * @throws RuntimeException
934
     */
935
    public function getActionButtons(EE_Transaction $transaction = null)
936
    {
937
        $content = '';
938
        $actions = array();
939
        if (! $transaction instanceof EE_Transaction) {
940
            return $content;
941
        }
942
        /** @var EE_Registration $primary_registration */
943
        $primary_registration = $transaction->primary_registration();
944
        $attendee = $primary_registration instanceof EE_Registration
945
            ? $primary_registration->attendee()
946
            : null;
947
948
        if ($attendee instanceof EE_Attendee
949
            && EE_Registry::instance()->CAP->current_user_can(
950
                'ee_send_message',
951
                'espresso_transactions_send_payment_reminder'
952
            )
953
        ) {
954
            $actions['payment_reminder'] =
955
                EEH_MSG_Template::is_mt_active('payment_reminder')
956
                && $this->_transaction->get('STS_ID') !== EEM_Transaction::complete_status_code
957
                && $this->_transaction->get('STS_ID') !== EEM_Transaction::overpaid_status_code
958
                    ? EEH_Template::get_button_or_link(
959
                        EE_Admin_Page::add_query_args_and_nonce(
960
                            array(
961
                                'action'      => 'send_payment_reminder',
962
                                'TXN_ID'      => $this->_transaction->ID(),
963
                                'redirect_to' => 'view_transaction',
964
                            ),
965
                            TXN_ADMIN_URL
966
                        ),
967
                        esc_html__(' Send Payment Reminder', 'event_espresso'),
968
                        'button secondary-button',
969
                        'dashicons dashicons-email-alt'
970
                    )
971
                    : '';
972
        }
973
974 View Code Duplication
        if (EE_Registry::instance()->CAP->current_user_can(
975
            'ee_edit_payments',
976
            'espresso_transactions_recalculate_line_items'
977
        )
978
        ) {
979
            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
980
                EE_Admin_Page::add_query_args_and_nonce(
981
                    array(
982
                        'action'      => 'espresso_recalculate_line_items',
983
                        'TXN_ID'      => $this->_transaction->ID(),
984
                        'redirect_to' => 'view_transaction',
985
                    ),
986
                    TXN_ADMIN_URL
987
                ),
988
                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
989
                'button secondary-button',
990
                'dashicons dashicons-update'
991
            );
992
        }
993
994 View Code Duplication
        if ($primary_registration instanceof EE_Registration
995
            && EEH_MSG_Template::is_mt_active('receipt')
996
        ) {
997
            $actions['receipt'] = EEH_Template::get_button_or_link(
998
                $primary_registration->receipt_url(),
999
                esc_html__('View Receipt', 'event_espresso'),
1000
                'button secondary-button',
1001
                'dashicons dashicons-media-default'
1002
            );
1003
        }
1004
1005 View Code Duplication
        if ($primary_registration instanceof EE_Registration
1006
            && EEH_MSG_Template::is_mt_active('invoice')
1007
        ) {
1008
            $actions['invoice'] = EEH_Template::get_button_or_link(
1009
                $primary_registration->invoice_url(),
1010
                esc_html__('View Invoice', 'event_espresso'),
1011
                'button secondary-button',
1012
                'dashicons dashicons-media-spreadsheet'
1013
            );
1014
        }
1015
        $actions = array_filter(
1016
            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
1017
        );
1018
        if ($actions) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $actions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1019
            $content = '<ul>';
1020
            $content .= '<li>' . implode('</li><li>', $actions) . '</li>';
1021
            $content .= '</uL>';
1022
        }
1023
        return $content;
1024
    }
1025
1026
1027
    /**
1028
     * txn_details_meta_box
1029
     * generates HTML for the Transaction main meta box
1030
     *
1031
     * @return void
1032
     * @throws DomainException
1033
     * @throws EE_Error
1034
     * @throws InvalidArgumentException
1035
     * @throws InvalidDataTypeException
1036
     * @throws InvalidInterfaceException
1037
     * @throws RuntimeException
1038
     * @throws ReflectionException
1039
     */
1040
    public function txn_details_meta_box()
1041
    {
1042
        $this->_set_transaction_object();
1043
        $this->_template_args['TXN_ID'] = $this->_transaction->ID();
1044
        $this->_template_args['attendee'] = $this->_transaction->primary_registration() instanceof EE_Registration
1045
            ? $this->_transaction->primary_registration()->attendee()
1046
            : null;
1047
        $this->_template_args['can_edit_payments'] = EE_Registry::instance()->CAP->current_user_can(
1048
            'ee_edit_payments',
1049
            'apply_payment_or_refund_from_registration_details'
1050
        );
1051
        $this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1052
            'ee_delete_payments',
1053
            'delete_payment_from_registration_details'
1054
        );
1055
1056
        // get line table
1057
        EEH_Autoloader::register_line_item_display_autoloaders();
1058
        $Line_Item_Display = new EE_Line_Item_Display(
1059
            'admin_table',
1060
            'EE_Admin_Table_Line_Item_Display_Strategy'
1061
        );
1062
        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1063
            $this->_transaction->total_line_item()
1064
        );
1065
        $this->_template_args['REG_code'] = $this->_transaction->get_first_related('Registration')
1066
                                                               ->get('REG_code');
1067
1068
        // process taxes
1069
        $taxes = $this->_transaction->get_many_related(
1070
            'Line_Item',
1071
            array(array('LIN_type' => EEM_Line_Item::type_tax))
1072
        );
1073
        $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1074
1075
        $this->_template_args['grand_total'] = EEH_Template::format_currency(
1076
            $this->_transaction->get('TXN_total'),
1077
            false,
1078
            false
1079
        );
1080
        $this->_template_args['grand_raw_total'] = $this->_transaction->get('TXN_total');
1081
        $this->_template_args['TXN_status'] = $this->_transaction->get('STS_ID');
1082
1083
        // process payment details
1084
        $payments = $this->_transaction->get_many_related('Payment');
1085
        if (! empty($payments)) {
1086
            $this->_template_args['payments'] = $payments;
1087
            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1088
        } else {
1089
            $this->_template_args['payments'] = false;
1090
            $this->_template_args['existing_reg_payments'] = array();
1091
        }
1092
1093
        $this->_template_args['edit_payment_url'] = add_query_arg(array('action' => 'edit_payment'), TXN_ADMIN_URL);
1094
        $this->_template_args['delete_payment_url'] = add_query_arg(
1095
            array('action' => 'espresso_delete_payment'),
1096
            TXN_ADMIN_URL
1097
        );
1098
1099
        if (isset($txn_details['invoice_number'])) {
0 ignored issues
show
Bug introduced by
The variable $txn_details seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
1100
            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1101
            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1102
                'Invoice Number',
1103
                'event_espresso'
1104
            );
1105
        }
1106
1107
        $this->_template_args['txn_details']['registration_session']['value'] = $this->_transaction
1108
            ->get_first_related('Registration')
1109
            ->get('REG_session');
1110
        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1111
            'Registration Session',
1112
            'event_espresso'
1113
        );
1114
1115
        $this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1116
            ? $this->_session['ip_address']
1117
            : '';
1118
        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1119
            'Transaction placed from IP',
1120
            'event_espresso'
1121
        );
1122
1123
        $this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1124
            ? $this->_session['user_agent']
1125
            : '';
1126
        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1127
            'Registrant User Agent',
1128
            'event_espresso'
1129
        );
1130
1131
        $reg_steps = '<ul>';
1132
        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1133
            if ($reg_step_status === true) {
1134
                $reg_steps .= '<li style="color:#70cc50">'
1135
                              . sprintf(
1136
                                  esc_html__('%1$s : Completed', 'event_espresso'),
1137
                                  ucwords(str_replace('_', ' ', $reg_step))
1138
                              )
1139
                              . '</li>';
1140
            } elseif (is_numeric($reg_step_status) && $reg_step_status !== false) {
1141
                $reg_steps .= '<li style="color:#2EA2CC">'
1142
                              . sprintf(
1143
                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1144
                                  ucwords(str_replace('_', ' ', $reg_step)),
1145
                                  date(
1146
                                      get_option('date_format') . ' ' . get_option('time_format'),
1147
                                      ($reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS))
1148
                                  )
1149
                              )
1150
                              . '</li>';
1151
            } else {
1152
                $reg_steps .= '<li style="color:#E76700">'
1153
                              . sprintf(
1154
                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1155
                                  ucwords(str_replace('_', ' ', $reg_step))
1156
                              )
1157
                              . '</li>';
1158
            }
1159
        }
1160
        $reg_steps .= '</ul>';
1161
        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1162
        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1163
            'Registration Step Progress',
1164
            'event_espresso'
1165
        );
1166
1167
1168
        $this->_get_registrations_to_apply_payment_to();
1169
        $this->_get_payment_methods($payments);
1170
        $this->_get_payment_status_array();
1171
        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1172
1173
        $this->_template_args['transaction_form_url'] = add_query_arg(
1174
            array(
1175
                'action'  => 'edit_transaction',
1176
                'process' => 'transaction',
1177
            ),
1178
            TXN_ADMIN_URL
1179
        );
1180
        $this->_template_args['apply_payment_form_url'] = add_query_arg(
1181
            array(
1182
                'page'   => 'espresso_transactions',
1183
                'action' => 'espresso_apply_payment',
1184
            ),
1185
            WP_AJAX_URL
1186
        );
1187
        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1188
            array(
1189
                'page'   => 'espresso_transactions',
1190
                'action' => 'espresso_delete_payment',
1191
            ),
1192
            WP_AJAX_URL
1193
        );
1194
1195
        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1196
1197
        // 'espresso_delete_payment_nonce'
1198
1199
        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1200
        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1201
    }
1202
1203
1204
    /**
1205
     * _get_registration_payment_IDs
1206
     *    generates an array of Payment IDs and their corresponding Registration IDs
1207
     *
1208
     * @access protected
1209
     * @param EE_Payment[] $payments
1210
     * @return array
1211
     * @throws EE_Error
1212
     * @throws InvalidArgumentException
1213
     * @throws InvalidDataTypeException
1214
     * @throws InvalidInterfaceException
1215
     * @throws ReflectionException
1216
     */
1217
    protected function _get_registration_payment_IDs($payments = array())
1218
    {
1219
        $existing_reg_payments = array();
1220
        // get all reg payments for these payments
1221
        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1222
            array(
1223
                array(
1224
                    'PAY_ID' => array(
1225
                        'IN',
1226
                        array_keys($payments),
1227
                    ),
1228
                ),
1229
            )
1230
        );
1231
        if (! empty($reg_payments)) {
1232
            foreach ($payments as $payment) {
1233
                if (! $payment instanceof EE_Payment) {
1234
                    continue;
1235
                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1236
                    $existing_reg_payments[ $payment->ID() ] = array();
1237
                }
1238
                foreach ($reg_payments as $reg_payment) {
1239
                    if ($reg_payment instanceof EE_Registration_Payment
1240
                        && $reg_payment->payment_ID() === $payment->ID()
1241
                    ) {
1242
                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1243
                    }
1244
                }
1245
            }
1246
        }
1247
1248
        return $existing_reg_payments;
1249
    }
1250
1251
1252
    /**
1253
     * _get_registrations_to_apply_payment_to
1254
     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1255
     * which allows the admin to only apply the payment to the specific registrations
1256
     *
1257
     * @access protected
1258
     * @return void
1259
     * @throws \EE_Error
1260
     */
1261
    protected function _get_registrations_to_apply_payment_to()
1262
    {
1263
        // we want any registration with an active status (ie: not deleted or cancelled)
1264
        $query_params = array(
1265
            array(
1266
                'STS_ID' => array(
1267
                    'IN',
1268
                    array(
1269
                        EEM_Registration::status_id_approved,
1270
                        EEM_Registration::status_id_pending_payment,
1271
                        EEM_Registration::status_id_not_approved,
1272
                    ),
1273
                ),
1274
            ),
1275
        );
1276
        $registrations_to_apply_payment_to = EEH_HTML::br()
1277
                                             . EEH_HTML::div(
1278
                                                 '',
1279
                                                 'txn-admin-apply-payment-to-registrations-dv',
1280
                                                 '',
1281
                                                 'clear: both; margin: 1.5em 0 0; display: none;'
1282
                                             );
1283
        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1284
        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
1285
        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1286
            EEH_HTML::tr(
1287
                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1288
                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1289
                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1290
                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1291
                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1292
                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1293
                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1294
            )
1295
        );
1296
        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1297
        // get registrations for TXN
1298
        $registrations = $this->_transaction->registrations($query_params);
1299
        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1300
        foreach ($registrations as $registration) {
1301
            if ($registration instanceof EE_Registration) {
1302
                $attendee_name = $registration->attendee() instanceof EE_Attendee
1303
                    ? $registration->attendee()->full_name()
1304
                    : esc_html__('Unknown Attendee', 'event_espresso');
1305
                $owing = $registration->final_price() - $registration->paid();
1306
                $taxable = $registration->ticket()->taxable()
1307
                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1308
                    : '';
1309
                $checked = empty($existing_reg_payments) || in_array($registration->ID(), $existing_reg_payments)
1310
                    ? ' checked="checked"'
1311
                    : '';
1312
                $disabled = $registration->final_price() > 0 ? '' : ' disabled';
1313
                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1314
                    EEH_HTML::td($registration->ID()) .
1315
                    EEH_HTML::td($attendee_name) .
1316
                    EEH_HTML::td(
1317
                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1318
                    ) .
1319
                    EEH_HTML::td($registration->event_name()) .
1320
                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1321
                    EEH_HTML::td(EEH_Template::format_currency($owing), '', 'txn-admin-payment-owing-td jst-cntr') .
1322
                    EEH_HTML::td(
1323
                        '<input type="checkbox" value="' . $registration->ID()
1324
                        . '" name="txn_admin_payment[registrations]"'
1325
                        . $checked . $disabled . '>',
1326
                        '',
1327
                        'jst-cntr'
1328
                    ),
1329
                    'apply-payment-registration-row-' . $registration->ID()
1330
                );
1331
            }
1332
        }
1333
        $registrations_to_apply_payment_to .= EEH_HTML::tbodyx();
1334
        $registrations_to_apply_payment_to .= EEH_HTML::tablex();
1335
        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1336
        $registrations_to_apply_payment_to .= EEH_HTML::p(
1337
            esc_html__(
1338
                'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1339
                'event_espresso'
1340
            ),
1341
            '',
1342
            'clear description'
1343
        );
1344
        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1345
        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1346
    }
1347
1348
1349
    /**
1350
     * _get_reg_status_selection
1351
     *
1352
     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1353
     *         instead of events.
1354
     * @access protected
1355
     * @return void
1356
     * @throws EE_Error
1357
     */
1358
    protected function _get_reg_status_selection()
1359
    {
1360
        // first get all possible statuses
1361
        $statuses = EEM_Registration::reg_status_array(array(), true);
1362
        // let's add a "don't change" option.
1363
        $status_array['NAN'] = esc_html__('Leave the Same', 'event_espresso');
0 ignored issues
show
Coding Style Comprehensibility introduced by
$status_array was never initialized. Although not strictly required by PHP, it is generally a good practice to add $status_array = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1364
        $status_array = array_merge($status_array, $statuses);
1365
        $this->_template_args['status_change_select'] = EEH_Form_Fields::select_input(
1366
            'txn_reg_status_change[reg_status]',
1367
            $status_array,
1368
            'NAN',
1369
            'id="txn-admin-payment-reg-status-inp"',
1370
            'txn-reg-status-change-reg-status'
1371
        );
1372
        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1373
            'delete_txn_reg_status_change[reg_status]',
1374
            $status_array,
1375
            'NAN',
1376
            'delete-txn-admin-payment-reg-status-inp',
1377
            'delete-txn-reg-status-change-reg-status'
1378
        );
1379
    }
1380
1381
1382
    /**
1383
     *    _get_payment_methods
1384
     * Gets all the payment methods available generally, or the ones that are already
1385
     * selected on these payments (in case their payment methods are no longer active).
1386
     * Has the side-effect of updating the template args' payment_methods item
1387
     *
1388
     * @access private
1389
     * @param EE_Payment[] to show on this page
1390
     * @return void
1391
     * @throws EE_Error
1392
     * @throws InvalidArgumentException
1393
     * @throws InvalidDataTypeException
1394
     * @throws InvalidInterfaceException
1395
     * @throws ReflectionException
1396
     */
1397
    private function _get_payment_methods($payments = array())
1398
    {
1399
        $payment_methods_of_payments = array();
1400
        foreach ($payments as $payment) {
1401
            if ($payment instanceof EE_Payment) {
1402
                $payment_methods_of_payments[] = $payment->get('PMD_ID');
1403
            }
1404
        }
1405
        if ($payment_methods_of_payments) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment_methods_of_payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1406
            $query_args = array(
1407
                array(
1408
                    'OR*payment_method_for_payment' => array(
1409
                        'PMD_ID'    => array('IN', $payment_methods_of_payments),
1410
                        'PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%'),
1411
                    ),
1412
                ),
1413
            );
1414
        } else {
1415
            $query_args = array(array('PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%')));
1416
        }
1417
        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1418
    }
1419
1420
1421
    /**
1422
     * txn_attendees_meta_box
1423
     *    generates HTML for the Attendees Transaction main meta box
1424
     *
1425
     * @access public
1426
     * @param WP_Post $post
1427
     * @param array   $metabox
1428
     * @return void
1429
     * @throws DomainException
1430
     * @throws EE_Error
1431
     */
1432
    public function txn_attendees_meta_box($post, $metabox = array('args' => array()))
1433
    {
1434
1435
        /** @noinspection NonSecureExtractUsageInspection */
1436
        extract($metabox['args']);
1437
        $this->_template_args['post'] = $post;
1438
        $this->_template_args['event_attendees'] = array();
1439
        // process items in cart
1440
        $line_items = $this->_transaction->get_many_related(
1441
            'Line_Item',
1442
            array(array('LIN_type' => 'line-item'))
1443
        );
1444
        if (! empty($line_items)) {
1445
            foreach ($line_items as $item) {
1446
                if ($item instanceof EE_Line_Item) {
1447
                    switch ($item->OBJ_type()) {
1448
                        case 'Event':
1449
                            break;
1450
                        case 'Ticket':
1451
                            $ticket = $item->ticket();
1452
                            // right now we're only handling tickets here.
1453
                            // Cause its expected that only tickets will have attendees right?
1454
                            if (! $ticket instanceof EE_Ticket) {
1455
                                continue;
1456
                            }
1457
                            try {
1458
                                $event_name = $ticket->get_event_name();
1459
                            } catch (Exception $e) {
1460
                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1461
                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1462
                            }
1463
                            $event_name .= ' - ' . $item->get('LIN_name');
1464
                            $ticket_price = EEH_Template::format_currency($item->get('LIN_unit_price'));
1465
                            // now get all of the registrations for this transaction that use this ticket
1466
                            $registrations = $ticket->get_many_related(
1467
                                'Registration',
1468
                                array(array('TXN_ID' => $this->_transaction->ID()))
1469
                            );
1470
                            foreach ($registrations as $registration) {
1471
                                if (! $registration instanceof EE_Registration) {
1472
                                    continue;
1473
                                }
1474
                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1475
                                    = $registration->status_ID();
1476
                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1477
                                    = $registration->count();
1478
                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1479
                                    = $event_name;
1480
                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1481
                                    = $ticket_price;
1482
                                // attendee info
1483
                                $attendee = $registration->get_first_related('Attendee');
1484
                                if ($attendee instanceof EE_Attendee) {
1485
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1486
                                        = $attendee->ID();
1487
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1488
                                        = $attendee->full_name();
1489
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1490
                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1491
                                          . esc_html__(
1492
                                              ' Event',
1493
                                              'event_espresso'
1494
                                          )
1495
                                          . '">' . $attendee->email() . '</a>';
1496
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1497
                                        = EEH_Address::format($attendee, 'inline', false, false);
1498
                                } else {
1499
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id'] = '';
1500
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1501
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email'] = '';
1502
                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address'] = '';
1503
                                }
1504
                            }
1505
                            break;
1506
                    }
1507
                }
1508
            }
1509
1510
            $this->_template_args['transaction_form_url'] = add_query_arg(
1511
                array(
1512
                    'action'  => 'edit_transaction',
1513
                    'process' => 'attendees',
1514
                ),
1515
                TXN_ADMIN_URL
1516
            );
1517
            echo EEH_Template::display_template(
1518
                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1519
                $this->_template_args,
1520
                true
1521
            );
1522
        } else {
1523
            echo sprintf(
1524
                esc_html__(
1525
                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1526
                    'event_espresso'
1527
                ),
1528
                '<p class="important-notice">',
1529
                '</p>'
1530
            );
1531
        }
1532
    }
1533
1534
1535
    /**
1536
     * txn_registrant_side_meta_box
1537
     * generates HTML for the Edit Transaction side meta box
1538
     *
1539
     * @access public
1540
     * @return void
1541
     * @throws DomainException
1542
     * @throws EE_Error
1543
     * @throws InvalidArgumentException
1544
     * @throws InvalidDataTypeException
1545
     * @throws InvalidInterfaceException
1546
     * @throws ReflectionException
1547
     */
1548
    public function txn_registrant_side_meta_box()
1549
    {
1550
        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1551
            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1552
            : null;
1553
        if (! $primary_att instanceof EE_Attendee) {
1554
            $this->_template_args['no_attendee_message'] = esc_html__(
1555
                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1556
                'event_espresso'
1557
            );
1558
            $primary_att = EEM_Attendee::instance()->create_default_object();
1559
        }
1560
        $this->_template_args['ATT_ID'] = $primary_att->ID();
1561
        $this->_template_args['prime_reg_fname'] = $primary_att->fname();
1562
        $this->_template_args['prime_reg_lname'] = $primary_att->lname();
1563
        $this->_template_args['prime_reg_email'] = $primary_att->email();
1564
        $this->_template_args['prime_reg_phone'] = $primary_att->phone();
1565
        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1566
            array(
1567
                'action' => 'edit_attendee',
1568
                'post'   => $primary_att->ID(),
1569
            ),
1570
            REG_ADMIN_URL
1571
        );
1572
        // get formatted address for registrant
1573
        $this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1574
        echo EEH_Template::display_template(
1575
            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1576
            $this->_template_args,
1577
            true
1578
        );
1579
    }
1580
1581
1582
    /**
1583
     * txn_billing_info_side_meta_box
1584
     *    generates HTML for the Edit Transaction side meta box
1585
     *
1586
     * @access public
1587
     * @return void
1588
     * @throws DomainException
1589
     * @throws EE_Error
1590
     */
1591
    public function txn_billing_info_side_meta_box()
1592
    {
1593
1594
        $this->_template_args['billing_form'] = $this->_transaction->billing_info();
1595
        $this->_template_args['billing_form_url'] = add_query_arg(
1596
            array('action' => 'edit_transaction', 'process' => 'billing'),
1597
            TXN_ADMIN_URL
1598
        );
1599
1600
        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1601
        echo EEH_Template::display_template($template_path, $this->_template_args, true);/**/
1602
    }
1603
1604
1605
    /**
1606
     * apply_payments_or_refunds
1607
     *    registers a payment or refund made towards a transaction
1608
     *
1609
     * @access public
1610
     * @return void
1611
     * @throws EE_Error
1612
     * @throws InvalidArgumentException
1613
     * @throws ReflectionException
1614
     * @throws RuntimeException
1615
     * @throws InvalidDataTypeException
1616
     * @throws InvalidInterfaceException
1617
     */
1618
    public function apply_payments_or_refunds()
1619
    {
1620
        $json_response_data = array('return_data' => false);
1621
        $valid_data = $this->_validate_payment_request_data();
1622
        $has_access = EE_Registry::instance()->CAP->current_user_can(
1623
            'ee_edit_payments',
1624
            'apply_payment_or_refund_from_registration_details'
1625
        );
1626
        if (! empty($valid_data) && $has_access) {
1627
            $PAY_ID = $valid_data['PAY_ID'];
1628
            // save  the new payment
1629
            $payment = $this->_create_payment_from_request_data($valid_data);
1630
            // get the TXN for this payment
1631
            $transaction = $payment->transaction();
1632
            // verify transaction
1633
            if ($transaction instanceof EE_Transaction) {
1634
                // calculate_total_payments_and_update_status
1635
                $this->_process_transaction_payments($transaction);
1636
                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1637
                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1638
                // apply payment to registrations (if applicable)
1639
                if (! empty($REG_IDs)) {
1640
                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1641
                    $this->_maybe_send_notifications();
1642
                    // now process status changes for the same registrations
1643
                    $this->_process_registration_status_change($transaction, $REG_IDs);
1644
                }
1645
                $this->_maybe_send_notifications($payment);
1646
                // prepare to render page
1647
                $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1648
                do_action(
1649
                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1650
                    $transaction,
1651
                    $payment
1652
                );
1653
            } else {
1654
                EE_Error::add_error(
1655
                    esc_html__(
1656
                        'A valid Transaction for this payment could not be retrieved.',
1657
                        'event_espresso'
1658
                    ),
1659
                    __FILE__,
1660
                    __FUNCTION__,
1661
                    __LINE__
1662
                );
1663
            }
1664 View Code Duplication
        } else {
1665
            if ($has_access) {
1666
                EE_Error::add_error(
1667
                    esc_html__(
1668
                        'The payment form data could not be processed. Please try again.',
1669
                        'event_espresso'
1670
                    ),
1671
                    __FILE__,
1672
                    __FUNCTION__,
1673
                    __LINE__
1674
                );
1675
            } else {
1676
                EE_Error::add_error(
1677
                    esc_html__(
1678
                        'You do not have access to apply payments or refunds to a registration.',
1679
                        'event_espresso'
1680
                    ),
1681
                    __FILE__,
1682
                    __FUNCTION__,
1683
                    __LINE__
1684
                );
1685
            }
1686
        }
1687
        $notices = EE_Error::get_notices(
1688
            false,
1689
            false,
1690
            false
1691
        );
1692
        $this->_template_args = array(
1693
            'data'    => $json_response_data,
1694
            'error'   => $notices['errors'],
1695
            'success' => $notices['success'],
1696
        );
1697
        $this->_return_json();
1698
    }
1699
1700
1701
    /**
1702
     * _validate_payment_request_data
1703
     *
1704
     * @return array
1705
     * @throws EE_Error
1706
     */
1707
    protected function _validate_payment_request_data()
1708
    {
1709
        if (! isset($this->_req_data['txn_admin_payment'])) {
1710
            return false;
1711
        }
1712
        $payment_form = $this->_generate_payment_form_section();
1713
        try {
1714
            if ($payment_form->was_submitted()) {
1715
                $payment_form->receive_form_submission();
1716
                if (! $payment_form->is_valid()) {
1717
                    $submission_error_messages = array();
1718
                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1719
                        if ($validation_error instanceof EE_Validation_Error) {
1720
                            $submission_error_messages[] = sprintf(
1721
                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1722
                                $validation_error->get_form_section()->html_label_text(),
1723
                                $validation_error->getMessage()
1724
                            );
1725
                        }
1726
                    }
1727
                    EE_Error::add_error(
1728
                        implode('<br />', $submission_error_messages),
1729
                        __FILE__,
1730
                        __FUNCTION__,
1731
                        __LINE__
1732
                    );
1733
1734
                    return array();
1735
                }
1736
            }
1737
        } catch (EE_Error $e) {
1738
            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1739
1740
            return array();
1741
        }
1742
1743
        return $payment_form->valid_data();
1744
    }
1745
1746
1747
    /**
1748
     * _generate_payment_form_section
1749
     *
1750
     * @return EE_Form_Section_Proper
1751
     * @throws EE_Error
1752
     */
1753
    protected function _generate_payment_form_section()
1754
    {
1755
        return new EE_Form_Section_Proper(
1756
            array(
1757
                'name'        => 'txn_admin_payment',
1758
                'subsections' => array(
1759
                    'PAY_ID'          => new EE_Text_Input(
1760
                        array(
1761
                            'default'               => 0,
1762
                            'required'              => false,
1763
                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1764
                            'validation_strategies' => array(new EE_Int_Normalization()),
1765
                        )
1766
                    ),
1767
                    'TXN_ID'          => new EE_Text_Input(
1768
                        array(
1769
                            'default'               => 0,
1770
                            'required'              => true,
1771
                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1772
                            'validation_strategies' => array(new EE_Int_Normalization()),
1773
                        )
1774
                    ),
1775
                    'type'            => new EE_Text_Input(
1776
                        array(
1777
                            'default'               => 1,
1778
                            'required'              => true,
1779
                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1780
                            'validation_strategies' => array(new EE_Int_Normalization()),
1781
                        )
1782
                    ),
1783
                    'amount'          => new EE_Text_Input(
1784
                        array(
1785
                            'default'               => 0,
1786
                            'required'              => true,
1787
                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1788
                            'validation_strategies' => array(new EE_Float_Normalization()),
1789
                        )
1790
                    ),
1791
                    'status'          => new EE_Text_Input(
1792
                        array(
1793
                            'default'         => EEM_Payment::status_id_approved,
1794
                            'required'        => true,
1795
                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1796
                        )
1797
                    ),
1798
                    'PMD_ID'          => new EE_Text_Input(
1799
                        array(
1800
                            'default'               => 2,
1801
                            'required'              => true,
1802
                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1803
                            'validation_strategies' => array(new EE_Int_Normalization()),
1804
                        )
1805
                    ),
1806
                    'date'            => new EE_Text_Input(
1807
                        array(
1808
                            'default'         => time(),
1809
                            'required'        => true,
1810
                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1811
                        )
1812
                    ),
1813
                    'txn_id_chq_nmbr' => new EE_Text_Input(
1814
                        array(
1815
                            'default'               => '',
1816
                            'required'              => false,
1817
                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1818
                            'validation_strategies' => array(
1819
                                new EE_Max_Length_Validation_Strategy(
1820
                                    esc_html__('Input too long', 'event_espresso'),
1821
                                    100
1822
                                ),
1823
                            ),
1824
                        )
1825
                    ),
1826
                    'po_number'       => new EE_Text_Input(
1827
                        array(
1828
                            'default'               => '',
1829
                            'required'              => false,
1830
                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1831
                            'validation_strategies' => array(
1832
                                new EE_Max_Length_Validation_Strategy(
1833
                                    esc_html__('Input too long', 'event_espresso'),
1834
                                    100
1835
                                ),
1836
                            ),
1837
                        )
1838
                    ),
1839
                    'accounting'      => new EE_Text_Input(
1840
                        array(
1841
                            'default'               => '',
1842
                            'required'              => false,
1843
                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1844
                            'validation_strategies' => array(
1845
                                new EE_Max_Length_Validation_Strategy(
1846
                                    esc_html__('Input too long', 'event_espresso'),
1847
                                    100
1848
                                ),
1849
                            ),
1850
                        )
1851
                    ),
1852
                ),
1853
            )
1854
        );
1855
    }
1856
1857
1858
    /**
1859
     * _create_payment_from_request_data
1860
     *
1861
     * @param array $valid_data
1862
     * @return EE_Payment
1863
     * @throws EE_Error
1864
     */
1865
    protected function _create_payment_from_request_data($valid_data)
1866
    {
1867
        $PAY_ID = $valid_data['PAY_ID'];
1868
        // get payment amount
1869
        $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1870
        // payments have a type value of 1 and refunds have a type value of -1
1871
        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1872
        $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1873
        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1874
        $date = $valid_data['date']
1875
            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1876
            : date('Y-m-d g:i a', current_time('timestamp'));
1877
        $payment = EE_Payment::new_instance(
1878
            array(
1879
                'TXN_ID'              => $valid_data['TXN_ID'],
1880
                'STS_ID'              => $valid_data['status'],
1881
                'PAY_timestamp'       => $date,
1882
                'PAY_source'          => EEM_Payment_Method::scope_admin,
1883
                'PMD_ID'              => $valid_data['PMD_ID'],
1884
                'PAY_amount'          => $amount,
1885
                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1886
                'PAY_po_number'       => $valid_data['po_number'],
1887
                'PAY_extra_accntng'   => $valid_data['accounting'],
1888
                'PAY_details'         => $valid_data,
1889
                'PAY_ID'              => $PAY_ID,
1890
            ),
1891
            '',
1892
            array('Y-m-d', 'g:i a')
1893
        );
1894
1895
        if (! $payment->save()) {
1896
            EE_Error::add_error(
1897
                sprintf(
1898
                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1899
                    $payment->ID()
1900
                ),
1901
                __FILE__,
1902
                __FUNCTION__,
1903
                __LINE__
1904
            );
1905
        }
1906
1907
        return $payment;
1908
    }
1909
1910
1911
    /**
1912
     * _process_transaction_payments
1913
     *
1914
     * @param \EE_Transaction $transaction
1915
     * @return void
1916
     * @throws EE_Error
1917
     * @throws InvalidArgumentException
1918
     * @throws ReflectionException
1919
     * @throws InvalidDataTypeException
1920
     * @throws InvalidInterfaceException
1921
     */
1922
    protected function _process_transaction_payments(EE_Transaction $transaction)
1923
    {
1924
        /** @type EE_Transaction_Payments $transaction_payments */
1925
        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1926
        // update the transaction with this payment
1927 View Code Duplication
        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1928
            EE_Error::add_success(
1929
                esc_html__(
1930
                    'The payment has been processed successfully.',
1931
                    'event_espresso'
1932
                ),
1933
                __FILE__,
1934
                __FUNCTION__,
1935
                __LINE__
1936
            );
1937
        } else {
1938
            EE_Error::add_error(
1939
                esc_html__(
1940
                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1941
                    'event_espresso'
1942
                ),
1943
                __FILE__,
1944
                __FUNCTION__,
1945
                __LINE__
1946
            );
1947
        }
1948
    }
1949
1950
1951
    /**
1952
     * _get_REG_IDs_to_apply_payment_to
1953
     * returns a list of registration IDs that the payment will apply to
1954
     *
1955
     * @param \EE_Payment $payment
1956
     * @return array
1957
     * @throws EE_Error
1958
     */
1959
    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1960
    {
1961
        $REG_IDs = array();
1962
        // grab array of IDs for specific registrations to apply changes to
1963
        if (isset($this->_req_data['txn_admin_payment']['registrations'])) {
1964
            $REG_IDs = (array) $this->_req_data['txn_admin_payment']['registrations'];
1965
        }
1966
        // nothing specified ? then get all reg IDs
1967
        if (empty($REG_IDs)) {
1968
            $registrations = $payment->transaction()->registrations();
1969
            $REG_IDs = ! empty($registrations)
1970
                ? array_keys($registrations)
1971
                : $this->_get_existing_reg_payment_REG_IDs($payment);
1972
        }
1973
1974
        // ensure that REG_IDs are integers and NOT strings
1975
        return array_map('intval', $REG_IDs);
1976
    }
1977
1978
1979
    /**
1980
     * @return array
1981
     */
1982
    public function existing_reg_payment_REG_IDs()
1983
    {
1984
        return $this->_existing_reg_payment_REG_IDs;
1985
    }
1986
1987
1988
    /**
1989
     * @param array $existing_reg_payment_REG_IDs
1990
     */
1991
    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1992
    {
1993
        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
0 ignored issues
show
Documentation Bug introduced by
It seems like $existing_reg_payment_REG_IDs can be null. However, the property $_existing_reg_payment_REG_IDs is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
1994
    }
1995
1996
1997
    /**
1998
     * _get_existing_reg_payment_REG_IDs
1999
     * returns a list of registration IDs that the payment is currently related to
2000
     * as recorded in the database
2001
     *
2002
     * @param \EE_Payment $payment
2003
     * @return array
2004
     * @throws EE_Error
2005
     */
2006
    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2007
    {
2008
        if ($this->existing_reg_payment_REG_IDs() === null) {
2009
            // let's get any existing reg payment records for this payment
2010
            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2011
            // but we only want the REG IDs, so grab the array keys
2012
            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2013
                ? array_keys($existing_reg_payment_REG_IDs)
2014
                : array();
2015
            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2016
        }
2017
2018
        return $this->existing_reg_payment_REG_IDs();
2019
    }
2020
2021
2022
    /**
2023
     * _remove_existing_registration_payments
2024
     * this calculates the difference between existing relations
2025
     * to the supplied payment and the new list registration IDs,
2026
     * removes any related registrations that no longer apply,
2027
     * and then updates the registration paid fields
2028
     *
2029
     * @param \EE_Payment $payment
2030
     * @param int         $PAY_ID
2031
     * @return bool;
2032
     * @throws EE_Error
2033
     * @throws InvalidArgumentException
2034
     * @throws ReflectionException
2035
     * @throws InvalidDataTypeException
2036
     * @throws InvalidInterfaceException
2037
     */
2038
    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2039
    {
2040
        // newly created payments will have nothing recorded for $PAY_ID
2041
        if ($PAY_ID == 0) {
2042
            return false;
2043
        }
2044
        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2045
        if (empty($existing_reg_payment_REG_IDs)) {
2046
            return false;
2047
        }
2048
        /** @type EE_Transaction_Payments $transaction_payments */
2049
        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2050
2051
        return $transaction_payments->delete_registration_payments_and_update_registrations(
2052
            $payment,
2053
            array(
2054
                array(
2055
                    'PAY_ID' => $payment->ID(),
2056
                    'REG_ID' => array('IN', $existing_reg_payment_REG_IDs),
2057
                ),
2058
            )
2059
        );
2060
    }
2061
2062
2063
    /**
2064
     * _update_registration_payments
2065
     * this applies the payments to the selected registrations
2066
     * but only if they have not already been paid for
2067
     *
2068
     * @param  EE_Transaction $transaction
2069
     * @param \EE_Payment     $payment
2070
     * @param array           $REG_IDs
2071
     * @return void
2072
     * @throws EE_Error
2073
     * @throws InvalidArgumentException
2074
     * @throws ReflectionException
2075
     * @throws RuntimeException
2076
     * @throws InvalidDataTypeException
2077
     * @throws InvalidInterfaceException
2078
     */
2079
    protected function _update_registration_payments(
2080
        EE_Transaction $transaction,
2081
        EE_Payment $payment,
2082
        $REG_IDs = array()
2083
    ) {
2084
        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2085
        // so let's do that using our set of REG_IDs from the form
2086
        $registration_query_where_params = array(
2087
            'REG_ID' => array('IN', $REG_IDs),
2088
        );
2089
        // but add in some conditions regarding payment,
2090
        // so that we don't apply payments to registrations that are free or have already been paid for
2091
        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2092
        if (! $payment->is_a_refund()) {
2093
            $registration_query_where_params['REG_final_price'] = array('!=', 0);
2094
            $registration_query_where_params['REG_final_price*'] = array('!=', 'REG_paid', true);
2095
        }
2096
        $registrations = $transaction->registrations(array($registration_query_where_params));
2097
        if (! empty($registrations)) {
2098
            /** @type EE_Payment_Processor $payment_processor */
2099
            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2100
            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2101
        }
2102
    }
2103
2104
2105
    /**
2106
     * _process_registration_status_change
2107
     * This processes requested registration status changes for all the registrations
2108
     * on a given transaction and (optionally) sends out notifications for the changes.
2109
     *
2110
     * @param  EE_Transaction $transaction
2111
     * @param array           $REG_IDs
2112
     * @return bool
2113
     * @throws EE_Error
2114
     * @throws InvalidArgumentException
2115
     * @throws ReflectionException
2116
     * @throws InvalidDataTypeException
2117
     * @throws InvalidInterfaceException
2118
     */
2119
    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = array())
2120
    {
2121
        // first if there is no change in status then we get out.
2122
        if (! isset($this->_req_data['txn_reg_status_change']['reg_status'])
2123
            || $this->_req_data['txn_reg_status_change']['reg_status'] === 'NAN'
2124
        ) {
2125
            // no error message, no change requested, just nothing to do man.
2126
            return false;
2127
        }
2128
        /** @type EE_Transaction_Processor $transaction_processor */
2129
        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2130
2131
        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2132
        return $transaction_processor->manually_update_registration_statuses(
2133
            $transaction,
2134
            sanitize_text_field($this->_req_data['txn_reg_status_change']['reg_status']),
2135
            array(array('REG_ID' => array('IN', $REG_IDs)))
2136
        );
2137
    }
2138
2139
2140
    /**
2141
     * _build_payment_json_response
2142
     *
2143
     * @access public
2144
     * @param \EE_Payment $payment
2145
     * @param array       $REG_IDs
2146
     * @param bool | null $delete_txn_reg_status_change
2147
     * @return array
2148
     * @throws EE_Error
2149
     * @throws InvalidArgumentException
2150
     * @throws InvalidDataTypeException
2151
     * @throws InvalidInterfaceException
2152
     * @throws ReflectionException
2153
     */
2154
    protected function _build_payment_json_response(
2155
        EE_Payment $payment,
2156
        $REG_IDs = array(),
2157
        $delete_txn_reg_status_change = null
2158
    ) {
2159
        // was the payment deleted ?
2160
        if (is_bool($delete_txn_reg_status_change)) {
2161
            return array(
2162
                'PAY_ID'                       => $payment->ID(),
2163
                'amount'                       => $payment->amount(),
2164
                'total_paid'                   => $payment->transaction()->paid(),
2165
                'txn_status'                   => $payment->transaction()->status_ID(),
2166
                'pay_status'                   => $payment->STS_ID(),
2167
                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2168
                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2169
            );
2170
        } else {
2171
            $this->_get_payment_status_array();
2172
2173
            return array(
2174
                'amount'           => $payment->amount(),
2175
                'total_paid'       => $payment->transaction()->paid(),
2176
                'txn_status'       => $payment->transaction()->status_ID(),
2177
                'pay_status'       => $payment->STS_ID(),
2178
                'PAY_ID'           => $payment->ID(),
2179
                'STS_ID'           => $payment->STS_ID(),
2180
                'status'           => self::$_pay_status[ $payment->STS_ID() ],
2181
                'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2182
                'method'           => strtoupper($payment->source()),
2183
                'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2184
                'gateway'          => $payment->payment_method()
2185
                    ? $payment->payment_method()->admin_name()
2186
                    : esc_html__("Unknown", 'event_espresso'),
2187
                'gateway_response' => $payment->gateway_response(),
2188
                'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2189
                'po_number'        => $payment->po_number(),
2190
                'extra_accntng'    => $payment->extra_accntng(),
2191
                'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2192
            );
2193
        }
2194
    }
2195
2196
2197
    /**
2198
     * delete_payment
2199
     *    delete a payment or refund made towards a transaction
2200
     *
2201
     * @access public
2202
     * @return void
2203
     * @throws EE_Error
2204
     * @throws InvalidArgumentException
2205
     * @throws ReflectionException
2206
     * @throws InvalidDataTypeException
2207
     * @throws InvalidInterfaceException
2208
     */
2209
    public function delete_payment()
2210
    {
2211
        $json_response_data = array('return_data' => false);
2212
        $PAY_ID = isset($this->_req_data['delete_txn_admin_payment']['PAY_ID'])
2213
            ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID'])
2214
            : 0;
2215
        $can_delete = EE_Registry::instance()->CAP->current_user_can(
2216
            'ee_delete_payments',
2217
            'delete_payment_from_registration_details'
2218
        );
2219
        if ($PAY_ID && $can_delete) {
2220
            $delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change'])
2221
                ? $this->_req_data['delete_txn_reg_status_change']
2222
                : false;
2223
            $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2224
            if ($payment instanceof EE_Payment) {
2225
                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2226
                /** @type EE_Transaction_Payments $transaction_payments */
2227
                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2228
                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2229
                    $json_response_data['return_data'] = $this->_build_payment_json_response(
2230
                        $payment,
2231
                        $REG_IDs,
2232
                        $delete_txn_reg_status_change
2233
                    );
2234
                    if ($delete_txn_reg_status_change) {
2235
                        $this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
2236
                        // MAKE sure we also add the delete_txn_req_status_change to the
2237
                        // $_REQUEST global because that's how messages will be looking for it.
2238
                        $_REQUEST['txn_reg_status_change'] = $delete_txn_reg_status_change;
2239
                        $this->_maybe_send_notifications();
2240
                        $this->_process_registration_status_change($payment->transaction(), $REG_IDs);
0 ignored issues
show
Bug introduced by
It seems like $payment->transaction() can be null; however, _process_registration_status_change() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2241
                    }
2242
                }
2243
            } else {
2244
                EE_Error::add_error(
2245
                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2246
                    __FILE__,
2247
                    __FUNCTION__,
2248
                    __LINE__
2249
                );
2250
            }
2251 View Code Duplication
        } else {
2252
            if ($can_delete) {
2253
                EE_Error::add_error(
2254
                    esc_html__(
2255
                        'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2256
                        'event_espresso'
2257
                    ),
2258
                    __FILE__,
2259
                    __FUNCTION__,
2260
                    __LINE__
2261
                );
2262
            } else {
2263
                EE_Error::add_error(
2264
                    esc_html__(
2265
                        'You do not have access to delete a payment.',
2266
                        'event_espresso'
2267
                    ),
2268
                    __FILE__,
2269
                    __FUNCTION__,
2270
                    __LINE__
2271
                );
2272
            }
2273
        }
2274
        $notices = EE_Error::get_notices(false, false, false);
2275
        $this->_template_args = array(
2276
            'data'      => $json_response_data,
2277
            'success'   => $notices['success'],
2278
            'error'     => $notices['errors'],
2279
            'attention' => $notices['attention'],
2280
        );
2281
        $this->_return_json();
2282
    }
2283
2284
2285
    /**
2286
     * _registration_payment_data_array
2287
     * adds info for 'owing' and 'paid' for each registration to the json response
2288
     *
2289
     * @access protected
2290
     * @param array $REG_IDs
2291
     * @return array
2292
     * @throws EE_Error
2293
     * @throws InvalidArgumentException
2294
     * @throws InvalidDataTypeException
2295
     * @throws InvalidInterfaceException
2296
     * @throws ReflectionException
2297
     */
2298
    protected function _registration_payment_data_array($REG_IDs)
2299
    {
2300
        $registration_payment_data = array();
2301
        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2302
        if (! empty($REG_IDs)) {
2303
            $registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
2304
            foreach ($registrations as $registration) {
2305
                if ($registration instanceof EE_Registration) {
2306
                    $registration_payment_data[ $registration->ID() ] = array(
2307
                        'paid'  => $registration->pretty_paid(),
2308
                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2309
                    );
2310
                }
2311
            }
2312
        }
2313
2314
        return $registration_payment_data;
2315
    }
2316
2317
2318
    /**
2319
     * _maybe_send_notifications
2320
     * determines whether or not the admin has indicated that notifications should be sent.
2321
     * If so, will toggle a filter switch for delivering registration notices.
2322
     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2323
     *
2324
     * @access protected
2325
     * @param \EE_Payment | null $payment
2326
     */
2327
    protected function _maybe_send_notifications($payment = null)
2328
    {
2329
        switch ($payment instanceof EE_Payment) {
2330
            // payment notifications
2331 View Code Duplication
            case true:
2332
                if (isset(
2333
                    $this->_req_data['txn_payments'],
2334
                    $this->_req_data['txn_payments']['send_notifications']
2335
                )
2336
                    && filter_var($this->_req_data['txn_payments']['send_notifications'], FILTER_VALIDATE_BOOLEAN)
2337
                ) {
2338
                    $this->_process_payment_notification($payment);
2339
                }
2340
                break;
2341
            // registration notifications
2342 View Code Duplication
            case false:
2343
                if (isset(
2344
                    $this->_req_data['txn_reg_status_change'],
2345
                    $this->_req_data['txn_reg_status_change']['send_notifications']
2346
                )
2347
                    && filter_var($this->_req_data['txn_reg_status_change']['send_notifications'], FILTER_VALIDATE_BOOLEAN)
2348
                ) {
2349
                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2350
                }
2351
                break;
2352
        }
2353
    }
2354
2355
2356
    /**
2357
     * _send_payment_reminder
2358
     *    generates HTML for the View Transaction Details Admin page
2359
     *
2360
     * @access protected
2361
     * @return void
2362
     * @throws EE_Error
2363
     * @throws InvalidArgumentException
2364
     * @throws InvalidDataTypeException
2365
     * @throws InvalidInterfaceException
2366
     */
2367
    protected function _send_payment_reminder()
2368
    {
2369
        $TXN_ID = ! empty($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : false;
2370
        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2371
        $query_args = isset($this->_req_data['redirect_to']) ? array(
2372
            'action' => $this->_req_data['redirect_to'],
2373
            'TXN_ID' => $this->_req_data['TXN_ID'],
2374
        ) : array();
2375
        do_action(
2376
            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2377
            $transaction
2378
        );
2379
        $this->_redirect_after_action(
2380
            false,
2381
            esc_html__('payment reminder', 'event_espresso'),
2382
            esc_html__('sent', 'event_espresso'),
2383
            $query_args,
2384
            true
2385
        );
2386
    }
2387
2388
2389
    /**
2390
     *  get_transactions
2391
     *    get transactions for given parameters (used by list table)
2392
     *
2393
     * @param  int     $perpage how many transactions displayed per page
2394
     * @param  boolean $count   return the count or objects
2395
     * @param string   $view
2396
     * @return mixed int = count || array of transaction objects
2397
     * @throws EE_Error
2398
     * @throws InvalidArgumentException
2399
     * @throws InvalidDataTypeException
2400
     * @throws InvalidInterfaceException
2401
     */
2402
    public function get_transactions($perpage, $count = false, $view = '')
2403
    {
2404
2405
        $TXN = EEM_Transaction::instance();
2406
2407
        $start_date = isset($this->_req_data['txn-filter-start-date'])
2408
            ? wp_strip_all_tags($this->_req_data['txn-filter-start-date'])
2409
            : date(
2410
                'm/d/Y',
2411
                strtotime('-10 year')
2412
            );
2413
        $end_date = isset($this->_req_data['txn-filter-end-date'])
2414
            ? wp_strip_all_tags($this->_req_data['txn-filter-end-date'])
2415
            : date('m/d/Y');
2416
2417
        // make sure our timestamps start and end right at the boundaries for each day
2418
        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2419
        $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2420
2421
2422
        // convert to timestamps
2423
        $start_date = strtotime($start_date);
2424
        $end_date = strtotime($end_date);
2425
2426
        // makes sure start date is the lowest value and vice versa
2427
        $start_date = min($start_date, $end_date);
2428
        $end_date = max($start_date, $end_date);
2429
2430
        // convert to correct format for query
2431
        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2432
            'TXN_timestamp',
2433
            date('Y-m-d H:i:s', $start_date),
2434
            'Y-m-d H:i:s'
2435
        );
2436
        $end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2437
            'TXN_timestamp',
2438
            date('Y-m-d H:i:s', $end_date),
2439
            'Y-m-d H:i:s'
2440
        );
2441
2442
2443
        // set orderby
2444
        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
2445
2446
        switch ($this->_req_data['orderby']) {
2447
            case 'TXN_ID':
2448
                $orderby = 'TXN_ID';
2449
                break;
2450
            case 'ATT_fname':
2451
                $orderby = 'Registration.Attendee.ATT_fname';
2452
                break;
2453
            case 'event_name':
2454
                $orderby = 'Registration.Event.EVT_name';
2455
                break;
2456
            default: // 'TXN_timestamp'
2457
                $orderby = 'TXN_timestamp';
2458
        }
2459
2460
        $sort = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2461
        $current_page = ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
2462
        $per_page = ! empty($perpage) ? $perpage : 10;
2463
        $per_page = ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $per_page;
2464
2465
        $offset = ($current_page - 1) * $per_page;
2466
        $limit = array($offset, $per_page);
2467
2468
        $_where = array(
2469
            'TXN_timestamp'          => array('BETWEEN', array($start_date, $end_date)),
2470
            'Registration.REG_count' => 1,
2471
        );
2472
2473
        if (isset($this->_req_data['EVT_ID'])) {
2474
            $_where['Registration.EVT_ID'] = $this->_req_data['EVT_ID'];
2475
        }
2476
2477
        if (isset($this->_req_data['s'])) {
2478
            $search_string = '%' . $this->_req_data['s'] . '%';
2479
            $_where['OR'] = array(
2480
                'Registration.Event.EVT_name'         => array('LIKE', $search_string),
2481
                'Registration.Event.EVT_desc'         => array('LIKE', $search_string),
2482
                'Registration.Event.EVT_short_desc'   => array('LIKE', $search_string),
2483
                'Registration.Attendee.ATT_full_name' => array('LIKE', $search_string),
2484
                'Registration.Attendee.ATT_fname'     => array('LIKE', $search_string),
2485
                'Registration.Attendee.ATT_lname'     => array('LIKE', $search_string),
2486
                'Registration.Attendee.ATT_short_bio' => array('LIKE', $search_string),
2487
                'Registration.Attendee.ATT_email'     => array('LIKE', $search_string),
2488
                'Registration.Attendee.ATT_address'   => array('LIKE', $search_string),
2489
                'Registration.Attendee.ATT_address2'  => array('LIKE', $search_string),
2490
                'Registration.Attendee.ATT_city'      => array('LIKE', $search_string),
2491
                'Registration.REG_final_price'        => array('LIKE', $search_string),
2492
                'Registration.REG_code'               => array('LIKE', $search_string),
2493
                'Registration.REG_count'              => array('LIKE', $search_string),
2494
                'Registration.REG_group_size'         => array('LIKE', $search_string),
2495
                'Registration.Ticket.TKT_name'        => array('LIKE', $search_string),
2496
                'Registration.Ticket.TKT_description' => array('LIKE', $search_string),
2497
                'Payment.PAY_source'                  => array('LIKE', $search_string),
2498
                'Payment.Payment_Method.PMD_name'     => array('LIKE', $search_string),
2499
                'TXN_session_data'                    => array('LIKE', $search_string),
2500
                'Payment.PAY_txn_id_chq_nmbr'         => array('LIKE', $search_string),
2501
            );
2502
        }
2503
2504
        // failed transactions
2505
        $failed = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'failed' && ! $count)
2506
                  || ($count && $view === 'failed');
2507
        $abandoned = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'abandoned' && ! $count)
2508
                     || ($count && $view === 'abandoned');
2509
        $incomplete = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'incomplete' && ! $count)
2510
                      || ($count && $view === 'incomplete');
2511
2512
        if ($failed) {
2513
            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2514
        } elseif ($abandoned) {
2515
            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2516
        } elseif ($incomplete) {
2517
            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2518
        } else {
2519
            $_where['STS_ID'] = array('!=', EEM_Transaction::failed_status_code);
2520
            $_where['STS_ID*'] = array('!=', EEM_Transaction::abandoned_status_code);
2521
        }
2522
2523
        $query_params = apply_filters(
2524
            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2525
            array(
2526
                $_where,
2527
                'order_by'                 => array($orderby => $sort),
2528
                'limit'                    => $limit,
2529
                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2530
            ),
2531
            $this->_req_data,
2532
            $view,
2533
            $count
2534
        );
2535
2536
        $transactions = $count
2537
            ? $TXN->count(array($query_params[0]), 'TXN_ID', true)
2538
            : $TXN->get_all($query_params);
2539
2540
        return $transactions;
2541
    }
2542
2543
2544
    /**
2545
     * @since $VID:$
2546
     * @throws EE_Error
2547
     * @throws InvalidArgumentException
2548
     * @throws InvalidDataTypeException
2549
     * @throws InvalidInterfaceException
2550
     */
2551
    public function recalculateLineItems()
2552
    {
2553
        $TXN_ID = ! empty($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : false;
2554
        /** @var EE_Transaction $transaction */
2555
        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2556
        $total_line_item = $transaction->total_line_item(false);
2557
        if ($total_line_item instanceof EE_Line_Item) {
2558
            EEH_Line_Item::apply_taxes($total_line_item);
2559
        }
2560
        $this->_redirect_after_action(
2561
            false,
2562
            esc_html__('Transaction taxes and totals', 'event_espresso'),
2563
            esc_html__('recalculated', 'event_espresso'),
2564
            isset($this->_req_data['redirect_to'])
2565
                ? array(
2566
                'action' => $this->_req_data['redirect_to'],
2567
                'TXN_ID' => $this->_req_data['TXN_ID'],
2568
            )
2569
                : array(),
2570
            true
2571
        );
2572
    }
2573
}
2574