Completed
Branch FET/replace-legacy-request-for... (2862ab)
by
unknown
08:37 queued 06:31
created
caffeinated/admin/new/pricing/Pricing_Admin_Page.core.php 2 patches
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
         wp_enqueue_style('espresso-ui-theme');
342 342
         wp_register_style(
343 343
             'espresso_PRICING',
344
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.css',
344
+            PRICING_ASSETS_URL.'espresso_pricing_admin.css',
345 345
             [],
346 346
             EVENT_ESPRESSO_VERSION
347 347
         );
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
         wp_enqueue_script('jquery-ui-widget');
354 354
         wp_register_script(
355 355
             'espresso_PRICING',
356
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.js',
356
+            PRICING_ASSETS_URL.'espresso_pricing_admin.js',
357 357
             ['jquery'],
358 358
             EVENT_ESPRESSO_VERSION,
359 359
             true
@@ -450,7 +450,7 @@  discard block
 block discarded – undo
450 450
      */
451 451
     protected function _price_overview_list_table()
452 452
     {
453
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
453
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
454 454
             'add_new_price',
455 455
             'add',
456 456
             [],
@@ -477,7 +477,7 @@  discard block
 block discarded – undo
477 477
         // start with an empty array
478 478
         $event_pricing = [];
479 479
 
480
-        require_once(PRICING_ADMIN . 'Prices_List_Table.class.php');
480
+        require_once(PRICING_ADMIN.'Prices_List_Table.class.php');
481 481
 
482 482
         $orderby = $this->request->getRequestParam('orderby', '');
483 483
         $order   = $this->request->getRequestParam('order', 'ASC');
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
                 $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
556 556
         }
557 557
         // add PRC_ID to title if editing
558
-        $this->_admin_page_title = $PRC_ID ? $this->_admin_page_title . ' # ' . $PRC_ID : $this->_admin_page_title;
558
+        $this->_admin_page_title = $PRC_ID ? $this->_admin_page_title.' # '.$PRC_ID : $this->_admin_page_title;
559 559
 
560 560
         if ($PRC_ID) {
561 561
             $price                    = EEM_Price::instance()->get_one_by_ID($PRC_ID);
@@ -568,7 +568,7 @@  discard block
 block discarded – undo
568 568
             $this->_set_add_edit_form_tags('insert_price');
569 569
         }
570 570
 
571
-        if (! $price instanceof EE_Price) {
571
+        if ( ! $price instanceof EE_Price) {
572 572
             throw new RuntimeException(
573 573
                 sprintf(
574 574
                     esc_html__(
@@ -626,7 +626,7 @@  discard block
 block discarded – undo
626 626
     public function _edit_price_details_meta_box(): string
627 627
     {
628 628
         return EEH_Template::display_template(
629
-            PRICING_TEMPLATE_PATH . 'pricing_details_main_meta_box.template.php',
629
+            PRICING_TEMPLATE_PATH.'pricing_details_main_meta_box.template.php',
630 630
             $this->_template_args,
631 631
             true
632 632
         );
@@ -789,19 +789,19 @@  discard block
 block discarded – undo
789 789
      */
790 790
     public function adjustTicketRelations(EEM_Base $entity_model, $entity_ID, string $action, int $result)
791 791
     {
792
-        if (! $entity_ID || (float) $result < 1) {
792
+        if ( ! $entity_ID || (float) $result < 1) {
793 793
             return;
794 794
         }
795 795
 
796 796
         $entity = $entity_model->get_one_by_ID($entity_ID);
797
-        if (! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
797
+        if ( ! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
798 798
             return;
799 799
         }
800 800
 
801 801
         // get default tickets for updating
802 802
         $default_tickets = EEM_Ticket::instance()->get_all_default_tickets();
803 803
         foreach ($default_tickets as $default_ticket) {
804
-            if (! $default_ticket instanceof EE_Ticket) {
804
+            if ( ! $default_ticket instanceof EE_Ticket) {
805 805
                 continue;
806 806
             }
807 807
             switch ($action) {
@@ -876,7 +876,7 @@  discard block
 block discarded – undo
876 876
      */
877 877
     protected function _price_types_overview_list_table()
878 878
     {
879
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
879
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
880 880
             'add_new_price_type',
881 881
             'add_type',
882 882
             [],
@@ -901,7 +901,7 @@  discard block
 block discarded – undo
901 901
     public function get_price_types_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
902 902
     {
903 903
         // start with an empty array
904
-        require_once(PRICING_ADMIN . 'Price_Types_List_Table.class.php');
904
+        require_once(PRICING_ADMIN.'Price_Types_List_Table.class.php');
905 905
 
906 906
         $orderby = $this->request->getRequestParam('orderby', '');
907 907
         $order   = $this->request->getRequestParam('order', 'ASC');
@@ -962,7 +962,7 @@  discard block
 block discarded – undo
962 962
                 $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
963 963
         }
964 964
         // add PRT_ID to title if editing
965
-        $this->_admin_page_title = $PRT_ID ? $this->_admin_page_title . ' # ' . $PRT_ID : $this->_admin_page_title;
965
+        $this->_admin_page_title = $PRT_ID ? $this->_admin_page_title.' # '.$PRT_ID : $this->_admin_page_title;
966 966
 
967 967
         if ($PRT_ID) {
968 968
             $price_type               = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
@@ -973,7 +973,7 @@  discard block
 block discarded – undo
973 973
             $this->_set_add_edit_form_tags('insert_price_type');
974 974
         }
975 975
 
976
-        if (! $price_type instanceof EE_Price_Type) {
976
+        if ( ! $price_type instanceof EE_Price_Type) {
977 977
             throw new RuntimeException(
978 978
                 sprintf(
979 979
                     esc_html__(
@@ -1023,7 +1023,7 @@  discard block
 block discarded – undo
1023 1023
     public function _edit_price_type_details_meta_box(): string
1024 1024
     {
1025 1025
         return EEH_Template::display_template(
1026
-            PRICING_TEMPLATE_PATH . 'pricing_type_details_main_meta_box.template.php',
1026
+            PRICING_TEMPLATE_PATH.'pricing_type_details_main_meta_box.template.php',
1027 1027
             $this->_template_args,
1028 1028
             true
1029 1029
         );
@@ -1035,7 +1035,7 @@  discard block
 block discarded – undo
1035 1035
      */
1036 1036
     protected function set_price_type_column_values(): array
1037 1037
     {
1038
-        $base_type  = $this->request->getRequestParam(
1038
+        $base_type = $this->request->getRequestParam(
1039 1039
             'base_type',
1040 1040
             EEM_Price_Type::base_type_base_price,
1041 1041
             DataType::INTEGER
@@ -1161,7 +1161,7 @@  discard block
 block discarded – undo
1161 1161
     {
1162 1162
         return '
1163 1163
             <a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >
1164
-                ' . esc_html__('learn more about how pricing works', 'event_espresso') . '
1164
+                ' . esc_html__('learn more about how pricing works', 'event_espresso').'
1165 1165
             </a>';
1166 1166
     }
1167 1167
 
@@ -1237,7 +1237,7 @@  discard block
 block discarded – undo
1237 1237
     public function _update_tax_settings()
1238 1238
     {
1239 1239
         $tax_settings = EE_Config::instance()->tax_settings;
1240
-        if (! $tax_settings instanceof EE_Tax_Config) {
1240
+        if ( ! $tax_settings instanceof EE_Tax_Config) {
1241 1241
             $tax_settings = new EE_Tax_Config();
1242 1242
         }
1243 1243
         try {
Please login to merge, or discard this patch.
Indentation   +1259 added lines, -1259 removed lines patch added patch discarded remove patch
@@ -12,1270 +12,1270 @@
 block discarded – undo
12 12
 class Pricing_Admin_Page extends EE_Admin_Page
13 13
 {
14 14
 
15
-    protected function _init_page_props()
16
-    {
17
-        $this->page_slug        = PRICING_PG_SLUG;
18
-        $this->page_label       = PRICING_LABEL;
19
-        $this->_admin_base_url  = PRICING_ADMIN_URL;
20
-        $this->_admin_base_path = PRICING_ADMIN;
21
-    }
22
-
23
-
24
-    protected function _ajax_hooks()
25
-    {
26
-        add_action('wp_ajax_espresso_update_prices_order', [$this, 'update_price_order']);
27
-    }
28
-
29
-
30
-    protected function _define_page_props()
31
-    {
32
-        $this->_admin_page_title = PRICING_LABEL;
33
-        $this->_labels           = [
34
-            'buttons' => [
35
-                'add'         => esc_html__('Add New Default Price', 'event_espresso'),
36
-                'edit'        => esc_html__('Edit Default Price', 'event_espresso'),
37
-                'delete'      => esc_html__('Delete Default Price', 'event_espresso'),
38
-                'add_type'    => esc_html__('Add New Default Price Type', 'event_espresso'),
39
-                'edit_type'   => esc_html__('Edit Price Type', 'event_espresso'),
40
-                'delete_type' => esc_html__('Delete Price Type', 'event_espresso'),
41
-            ],
42
-        ];
43
-    }
44
-
45
-
46
-    /**
47
-     * an array for storing request actions and their corresponding methods
48
-     *
49
-     * @return void
50
-     */
51
-    protected function _set_page_routes()
52
-    {
53
-        $PRC_ID             = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
54
-        $PRT_ID             = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
55
-        $this->_page_routes = [
56
-            'default'                     => [
57
-                'func'       => '_price_overview_list_table',
58
-                'capability' => 'ee_read_default_prices',
59
-            ],
60
-            'add_new_price'               => [
61
-                'func'       => '_edit_price_details',
62
-                'args'       => ['new_price' => true],
63
-                'capability' => 'ee_edit_default_prices',
64
-            ],
65
-            'edit_price'                  => [
66
-                'func'       => '_edit_price_details',
67
-                'args'       => ['new_price' => false],
68
-                'capability' => 'ee_edit_default_price',
69
-                'obj_id'     => $PRC_ID,
70
-            ],
71
-            'insert_price'                => [
72
-                'func'       => '_insert_or_update_price',
73
-                'args'       => ['new_price' => true],
74
-                'noheader'   => true,
75
-                'capability' => 'ee_edit_default_prices',
76
-            ],
77
-            'update_price'                => [
78
-                'func'       => '_insert_or_update_price',
79
-                'args'       => ['new_price' => false],
80
-                'noheader'   => true,
81
-                'capability' => 'ee_edit_default_price',
82
-                'obj_id'     => $PRC_ID,
83
-            ],
84
-            'trash_price'                 => [
85
-                'func'       => '_trash_or_restore_price',
86
-                'args'       => ['trash' => true],
87
-                'noheader'   => true,
88
-                'capability' => 'ee_delete_default_price',
89
-                'obj_id'     => $PRC_ID,
90
-            ],
91
-            'restore_price'               => [
92
-                'func'       => '_trash_or_restore_price',
93
-                'args'       => ['trash' => false],
94
-                'noheader'   => true,
95
-                'capability' => 'ee_delete_default_price',
96
-                'obj_id'     => $PRC_ID,
97
-            ],
98
-            'delete_price'                => [
99
-                'func'       => '_delete_price',
100
-                'noheader'   => true,
101
-                'capability' => 'ee_delete_default_price',
102
-                'obj_id'     => $PRC_ID,
103
-            ],
104
-            'espresso_update_price_order' => [
105
-                'func'       => 'update_price_order',
106
-                'noheader'   => true,
107
-                'capability' => 'ee_edit_default_prices',
108
-            ],
109
-            // price types
110
-            'price_types'                 => [
111
-                'func'       => '_price_types_overview_list_table',
112
-                'capability' => 'ee_read_default_price_types',
113
-            ],
114
-            'add_new_price_type'          => [
115
-                'func'       => '_edit_price_type_details',
116
-                'capability' => 'ee_edit_default_price_types',
117
-            ],
118
-            'edit_price_type'             => [
119
-                'func'       => '_edit_price_type_details',
120
-                'capability' => 'ee_edit_default_price_type',
121
-                'obj_id'     => $PRT_ID,
122
-            ],
123
-            'insert_price_type'           => [
124
-                'func'       => '_insert_or_update_price_type',
125
-                'args'       => ['new_price_type' => true],
126
-                'noheader'   => true,
127
-                'capability' => 'ee_edit_default_price_types',
128
-            ],
129
-            'update_price_type'           => [
130
-                'func'       => '_insert_or_update_price_type',
131
-                'args'       => ['new_price_type' => false],
132
-                'noheader'   => true,
133
-                'capability' => 'ee_edit_default_price_type',
134
-                'obj_id'     => $PRT_ID,
135
-            ],
136
-            'trash_price_type'            => [
137
-                'func'       => '_trash_or_restore_price_type',
138
-                'args'       => ['trash' => true],
139
-                'noheader'   => true,
140
-                'capability' => 'ee_delete_default_price_type',
141
-                'obj_id'     => $PRT_ID,
142
-            ],
143
-            'restore_price_type'          => [
144
-                'func'       => '_trash_or_restore_price_type',
145
-                'args'       => ['trash' => false],
146
-                'noheader'   => true,
147
-                'capability' => 'ee_delete_default_price_type',
148
-                'obj_id'     => $PRT_ID,
149
-            ],
150
-            'delete_price_type'           => [
151
-                'func'       => '_delete_price_type',
152
-                'noheader'   => true,
153
-                'capability' => 'ee_delete_default_price_type',
154
-                'obj_id'     => $PRT_ID,
155
-            ],
156
-            'tax_settings'                => [
157
-                'func'       => '_tax_settings',
158
-                'capability' => 'manage_options',
159
-            ],
160
-            'update_tax_settings'         => [
161
-                'func'       => '_update_tax_settings',
162
-                'capability' => 'manage_options',
163
-                'noheader'   => true,
164
-            ],
165
-        ];
166
-    }
167
-
168
-
169
-    protected function _set_page_config()
170
-    {
171
-        $PRC_ID             = $this->request->getRequestParam('id', 0, DataType::INTEGER);
172
-        $this->_page_config = [
173
-            'default'            => [
174
-                'nav'           => [
175
-                    'label' => esc_html__('Default Pricing', 'event_espresso'),
176
-                    'order' => 10,
177
-                ],
178
-                'list_table'    => 'Prices_List_Table',
179
-                'metaboxes'     => $this->_default_espresso_metaboxes,
180
-                'help_tabs'     => [
181
-                    'pricing_default_pricing_help_tab'                           => [
182
-                        'title'    => esc_html__('Default Pricing', 'event_espresso'),
183
-                        'filename' => 'pricing_default_pricing',
184
-                    ],
185
-                    'pricing_default_pricing_table_column_headings_help_tab'     => [
186
-                        'title'    => esc_html__('Default Pricing Table Column Headings', 'event_espresso'),
187
-                        'filename' => 'pricing_default_pricing_table_column_headings',
188
-                    ],
189
-                    'pricing_default_pricing_views_bulk_actions_search_help_tab' => [
190
-                        'title'    => esc_html__('Default Pricing Views & Bulk Actions & Search', 'event_espresso'),
191
-                        'filename' => 'pricing_default_pricing_views_bulk_actions_search',
192
-                    ],
193
-                ],
194
-                'require_nonce' => false,
195
-            ],
196
-            'add_new_price'      => [
197
-                'nav'           => [
198
-                    'label'      => esc_html__('Add New Default Price', 'event_espresso'),
199
-                    'order'      => 20,
200
-                    'persistent' => false,
201
-                ],
202
-                'help_tabs'     => [
203
-                    'add_new_default_price_help_tab' => [
204
-                        'title'    => esc_html__('Add New Default Price', 'event_espresso'),
205
-                        'filename' => 'pricing_add_new_default_price',
206
-                    ],
207
-                ],
208
-                'metaboxes'     => array_merge(
209
-                    ['_publish_post_box'],
210
-                    $this->_default_espresso_metaboxes
211
-                ),
212
-                'require_nonce' => false,
213
-            ],
214
-            'edit_price'         => [
215
-                'nav'           => [
216
-                    'label'      => esc_html__('Edit Default Price', 'event_espresso'),
217
-                    'order'      => 20,
218
-                    'url'        => $PRC_ID
219
-                        ? add_query_arg(['id' => $PRC_ID], $this->_current_page_view_url)
220
-                        : $this->_admin_base_url,
221
-                    'persistent' => false,
222
-                ],
223
-                'metaboxes'     => array_merge(
224
-                    ['_publish_post_box'],
225
-                    $this->_default_espresso_metaboxes
226
-                ),
227
-                'help_tabs'     => [
228
-                    'edit_default_price_help_tab' => [
229
-                        'title'    => esc_html__('Edit Default Price', 'event_espresso'),
230
-                        'filename' => 'pricing_edit_default_price',
231
-                    ],
232
-                ],
233
-                'require_nonce' => false,
234
-            ],
235
-            'price_types'        => [
236
-                'nav'           => [
237
-                    'label' => esc_html__('Price Types', 'event_espresso'),
238
-                    'order' => 30,
239
-                ],
240
-                'list_table'    => 'Price_Types_List_Table',
241
-                'help_tabs'     => [
242
-                    'pricing_price_types_help_tab'                           => [
243
-                        'title'    => esc_html__('Price Types', 'event_espresso'),
244
-                        'filename' => 'pricing_price_types',
245
-                    ],
246
-                    'pricing_price_types_table_column_headings_help_tab'     => [
247
-                        'title'    => esc_html__('Price Types Table Column Headings', 'event_espresso'),
248
-                        'filename' => 'pricing_price_types_table_column_headings',
249
-                    ],
250
-                    'pricing_price_types_views_bulk_actions_search_help_tab' => [
251
-                        'title'    => esc_html__('Price Types Views & Bulk Actions & Search', 'event_espresso'),
252
-                        'filename' => 'pricing_price_types_views_bulk_actions_search',
253
-                    ],
254
-                ],
255
-                'metaboxes'     => $this->_default_espresso_metaboxes,
256
-                'require_nonce' => false,
257
-            ],
258
-            'add_new_price_type' => [
259
-                'nav'           => [
260
-                    'label'      => esc_html__('Add New Price Type', 'event_espresso'),
261
-                    'order'      => 40,
262
-                    'persistent' => false,
263
-                ],
264
-                'help_tabs'     => [
265
-                    'add_new_price_type_help_tab' => [
266
-                        'title'    => esc_html__('Add New Price Type', 'event_espresso'),
267
-                        'filename' => 'pricing_add_new_price_type',
268
-                    ],
269
-                ],
270
-                'metaboxes'     => array_merge(
271
-                    ['_publish_post_box'],
272
-                    $this->_default_espresso_metaboxes
273
-                ),
274
-                'require_nonce' => false,
275
-            ],
276
-            'edit_price_type'    => [
277
-                'nav'           => [
278
-                    'label'      => esc_html__('Edit Price Type', 'event_espresso'),
279
-                    'order'      => 40,
280
-                    'persistent' => false,
281
-                ],
282
-                'help_tabs'     => [
283
-                    'edit_price_type_help_tab' => [
284
-                        'title'    => esc_html__('Edit Price Type', 'event_espresso'),
285
-                        'filename' => 'pricing_edit_price_type',
286
-                    ],
287
-                ],
288
-                'metaboxes'     => array_merge(
289
-                    ['_publish_post_box'],
290
-                    $this->_default_espresso_metaboxes
291
-                ),
292
-                'require_nonce' => false,
293
-            ],
294
-            'tax_settings'       => [
295
-                'nav'           => [
296
-                    'label' => esc_html__('Tax Settings', 'event_espresso'),
297
-                    'order' => 40,
298
-                ],
299
-                'labels'        => [
300
-                    'publishbox' => esc_html__('Update Tax Settings', 'event_espresso'),
301
-                ],
302
-                'metaboxes'     => array_merge(
303
-                    ['_publish_post_box'],
304
-                    $this->_default_espresso_metaboxes
305
-                ),
306
-                'require_nonce' => true,
307
-            ],
308
-        ];
309
-    }
310
-
311
-
312
-    protected function _add_screen_options()
313
-    {
314
-        // todo
315
-    }
316
-
317
-
318
-    protected function _add_screen_options_default()
319
-    {
320
-        $this->_per_page_screen_option();
321
-    }
322
-
323
-
324
-    protected function _add_screen_options_price_types()
325
-    {
326
-        $page_title              = $this->_admin_page_title;
327
-        $this->_admin_page_title = esc_html__('Price Types', 'event_espresso');
328
-        $this->_per_page_screen_option();
329
-        $this->_admin_page_title = $page_title;
330
-    }
331
-
332
-
333
-    protected function _add_feature_pointers()
334
-    {
335
-    }
336
-
337
-
338
-    public function load_scripts_styles()
339
-    {
340
-        // styles
341
-        wp_enqueue_style('espresso-ui-theme');
342
-        wp_register_style(
343
-            'espresso_PRICING',
344
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.css',
345
-            [],
346
-            EVENT_ESPRESSO_VERSION
347
-        );
348
-        wp_enqueue_style('espresso_PRICING');
349
-
350
-        // scripts
351
-        wp_enqueue_script('ee_admin_js');
352
-        wp_enqueue_script('jquery-ui-position');
353
-        wp_enqueue_script('jquery-ui-widget');
354
-        wp_register_script(
355
-            'espresso_PRICING',
356
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.js',
357
-            ['jquery'],
358
-            EVENT_ESPRESSO_VERSION,
359
-            true
360
-        );
361
-        wp_enqueue_script('espresso_PRICING');
362
-    }
363
-
364
-
365
-    public function load_scripts_styles_default()
366
-    {
367
-        wp_enqueue_script('espresso_ajax_table_sorting');
368
-    }
369
-
370
-
371
-    public function admin_footer_scripts()
372
-    {
373
-    }
374
-
375
-
376
-    public function admin_init()
377
-    {
378
-    }
379
-
380
-
381
-    public function admin_notices()
382
-    {
383
-    }
384
-
385
-
386
-    protected function _set_list_table_views_default()
387
-    {
388
-        $this->_views = [
389
-            'all' => [
390
-                'slug'        => 'all',
391
-                'label'       => esc_html__('View All Default Pricing', 'event_espresso'),
392
-                'count'       => 0,
393
-                'bulk_action' => [
394
-                    'trash_price' => esc_html__('Move to Trash', 'event_espresso'),
395
-                ],
396
-            ],
397
-        ];
398
-
399
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_default_prices', 'pricing_trash_price')) {
400
-            $this->_views['trashed'] = [
401
-                'slug'        => 'trashed',
402
-                'label'       => esc_html__('Trash', 'event_espresso'),
403
-                'count'       => 0,
404
-                'bulk_action' => [
405
-                    'restore_price' => esc_html__('Restore from Trash', 'event_espresso'),
406
-                    'delete_price'  => esc_html__('Delete Permanently', 'event_espresso'),
407
-                ],
408
-            ];
409
-        }
410
-    }
411
-
412
-
413
-    protected function _set_list_table_views_price_types()
414
-    {
415
-        $this->_views = [
416
-            'all' => [
417
-                'slug'        => 'all',
418
-                'label'       => esc_html__('All', 'event_espresso'),
419
-                'count'       => 0,
420
-                'bulk_action' => [
421
-                    'trash_price_type' => esc_html__('Move to Trash', 'event_espresso'),
422
-                ],
423
-            ],
424
-        ];
425
-
426
-        if (
427
-            EE_Registry::instance()->CAP->current_user_can(
428
-                'ee_delete_default_price_types',
429
-                'pricing_trash_price_type'
430
-            )
431
-        ) {
432
-            $this->_views['trashed'] = [
433
-                'slug'        => 'trashed',
434
-                'label'       => esc_html__('Trash', 'event_espresso'),
435
-                'count'       => 0,
436
-                'bulk_action' => [
437
-                    'restore_price_type' => esc_html__('Restore from Trash', 'event_espresso'),
438
-                    'delete_price_type'  => esc_html__('Delete Permanently', 'event_espresso'),
439
-                ],
440
-            ];
441
-        }
442
-    }
443
-
444
-
445
-    /**
446
-     * generates HTML for main Prices Admin page
447
-     *
448
-     * @return void
449
-     * @throws EE_Error
450
-     */
451
-    protected function _price_overview_list_table()
452
-    {
453
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
454
-            'add_new_price',
455
-            'add',
456
-            [],
457
-            'add-new-h2'
458
-        );
459
-        $this->_admin_page_title .= $this->_learn_more_about_pricing_link();
460
-        $this->_search_btn_label = esc_html__('Default Prices', 'event_espresso');
461
-        $this->display_admin_list_table_page_with_sidebar();
462
-    }
463
-
464
-
465
-    /**
466
-     * retrieve data for Prices List table
467
-     *
468
-     * @param int  $per_page how many prices displayed per page
469
-     * @param bool $count    return the count or objects
470
-     * @param bool $trashed  whether the current view is of the trash can - eww yuck!
471
-     * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
472
-     * @throws EE_Error
473
-     * @throws ReflectionException
474
-     */
475
-    public function get_prices_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
476
-    {
477
-        // start with an empty array
478
-        $event_pricing = [];
479
-
480
-        require_once(PRICING_ADMIN . 'Prices_List_Table.class.php');
481
-
482
-        $orderby = $this->request->getRequestParam('orderby', '');
483
-        $order   = $this->request->getRequestParam('order', 'ASC');
484
-
485
-        switch ($orderby) {
486
-            case 'name':
487
-                $orderby = ['PRC_name' => $order];
488
-                break;
489
-            case 'type':
490
-                $orderby = ['Price_Type.PRT_name' => $order];
491
-                break;
492
-            case 'amount':
493
-                $orderby = ['PRC_amount' => $order];
494
-                break;
495
-            default:
496
-                $orderby = ['PRC_order' => $order, 'Price_Type.PRT_order' => $order, 'PRC_ID' => $order];
497
-        }
498
-
499
-        $current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
500
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
501
-
502
-        $where = [
503
-            'PRC_is_default' => 1,
504
-            'PRC_deleted'    => $trashed,
505
-        ];
506
-
507
-        $offset = ($current_page - 1) * $per_page;
508
-        $limit  = [$offset, $per_page];
509
-
510
-        $search_term = $this->request->getRequestParam('s');
511
-        if ($search_term) {
512
-            $search_term = "%{$search_term}%";
513
-            $where['OR'] = [
514
-                'PRC_name'            => ['LIKE', $search_term],
515
-                'PRC_desc'            => ['LIKE', $search_term],
516
-                'PRC_amount'          => ['LIKE', $search_term],
517
-                'Price_Type.PRT_name' => ['LIKE', $search_term],
518
-            ];
519
-        }
520
-
521
-        $query_params = [
522
-            $where,
523
-            'order_by' => $orderby,
524
-            'limit'    => $limit,
525
-            'group_by' => 'PRC_ID',
526
-        ];
527
-
528
-        if ($count) {
529
-            return $trashed
530
-                ? EEM_Price::instance()->count([$where])
531
-                : EEM_Price::instance()->count_deleted_and_undeleted([$where]);
532
-        }
533
-        return EEM_Price::instance()->get_all_deleted_and_undeleted($query_params);
534
-    }
535
-
536
-
537
-    /**
538
-     * @return void
539
-     * @throws EE_Error
540
-     * @throws ReflectionException
541
-     */
542
-    protected function _edit_price_details()
543
-    {
544
-        // grab price ID
545
-        $PRC_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
546
-        // change page title based on request action
547
-        switch ($this->_req_action) {
548
-            case 'add_new_price':
549
-                $this->_admin_page_title = esc_html__('Add New Price', 'event_espresso');
550
-                break;
551
-            case 'edit_price':
552
-                $this->_admin_page_title = esc_html__('Edit Price', 'event_espresso');
553
-                break;
554
-            default:
555
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
556
-        }
557
-        // add PRC_ID to title if editing
558
-        $this->_admin_page_title = $PRC_ID ? $this->_admin_page_title . ' # ' . $PRC_ID : $this->_admin_page_title;
559
-
560
-        if ($PRC_ID) {
561
-            $price                    = EEM_Price::instance()->get_one_by_ID($PRC_ID);
562
-            $additional_hidden_fields = [
563
-                'PRC_ID' => ['type' => 'hidden', 'value' => $PRC_ID],
564
-            ];
565
-            $this->_set_add_edit_form_tags('update_price', $additional_hidden_fields);
566
-        } else {
567
-            $price = EEM_Price::instance()->get_new_price();
568
-            $this->_set_add_edit_form_tags('insert_price');
569
-        }
570
-
571
-        if (! $price instanceof EE_Price) {
572
-            throw new RuntimeException(
573
-                sprintf(
574
-                    esc_html__(
575
-                        'A valid Price could not be retrieved from the database with ID: %1$s',
576
-                        'event_espresso'
577
-                    ),
578
-                    $PRC_ID
579
-                )
580
-            );
581
-        }
582
-
583
-        $this->_template_args['PRC_ID'] = $PRC_ID;
584
-        $this->_template_args['price']  = $price;
585
-
586
-        $default_base_price = $price->type_obj() && $price->type_obj()->base_type() === 1;
587
-
588
-        $this->_template_args['default_base_price'] = $default_base_price;
589
-
590
-        // get price types
591
-        $price_types = EEM_Price_Type::instance()->get_all([['PBT_ID' => ['!=', 1]]]);
592
-        if (empty($price_types)) {
593
-            $msg = esc_html__(
594
-                'You have no price types defined. Please add a price type before adding a price.',
595
-                'event_espresso'
596
-            );
597
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
598
-            $this->display_admin_page_with_sidebar();
599
-        }
600
-        $attributes       = [];
601
-        $price_type_names = [];
602
-        $attributes[]     = 'id="PRT_ID"';
603
-        if ($default_base_price) {
604
-            $attributes[]       = 'disabled="disabled"';
605
-            $price_type_names[] = ['id' => 1, 'text' => esc_html__('Base Price', 'event_espresso')];
606
-        }
607
-        foreach ($price_types as $type) {
608
-            $price_type_names[] = ['id' => $type->ID(), 'text' => $type->name()];
609
-        }
610
-        $this->_template_args['attributes']  = implode(' ', $attributes);
611
-        $this->_template_args['price_types'] = $price_type_names;
612
-
613
-        $this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
614
-        $this->_template_args['admin_page_content']            = $this->_edit_price_details_meta_box();
615
-
616
-        $this->_set_publish_post_box_vars('id', $PRC_ID);
617
-        // the details template wrapper
618
-        $this->display_admin_page_with_sidebar();
619
-    }
620
-
621
-
622
-    /**
623
-     *
624
-     * @return string
625
-     */
626
-    public function _edit_price_details_meta_box(): string
627
-    {
628
-        return EEH_Template::display_template(
629
-            PRICING_TEMPLATE_PATH . 'pricing_details_main_meta_box.template.php',
630
-            $this->_template_args,
631
-            true
632
-        );
633
-    }
634
-
635
-
636
-    /**
637
-     * @return array
638
-     * @throws EE_Error
639
-     * @throws ReflectionException
640
-     */
641
-    protected function set_price_column_values(): array
642
-    {
643
-        $PRC_order = 0;
644
-        $PRT_ID    = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
645
-        if ($PRT_ID) {
646
-            /** @var EE_Price_Type $price_type */
647
-            $price_type = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
648
-            if ($price_type instanceof EE_Price_Type) {
649
-                $PRC_order = $price_type->order();
650
-            }
651
-        }
652
-        return [
653
-            'PRT_ID'         => $PRT_ID,
654
-            'PRC_amount'     => $this->request->getRequestParam('PRC_amount', 0, DataType::FLOAT),
655
-            'PRC_name'       => $this->request->getRequestParam('PRC_name'),
656
-            'PRC_desc'       => $this->request->getRequestParam('PRC_desc'),
657
-            'PRC_is_default' => 1,
658
-            'PRC_overrides'  => null,
659
-            'PRC_order'      => $PRC_order,
660
-            'PRC_deleted'    => 0,
661
-            'PRC_parent'     => 0,
662
-        ];
663
-    }
664
-
665
-
666
-    /**
667
-     * @param bool $insert - whether to insert or update
668
-     * @return void
669
-     * @throws EE_Error
670
-     * @throws ReflectionException
671
-     */
672
-    protected function _insert_or_update_price(bool $insert = false)
673
-    {
674
-        // why be so pessimistic ???  : (
675
-        $updated = 0;
676
-
677
-        $set_column_values = $this->set_price_column_values();
678
-        // is this a new Price ?
679
-        if ($insert) {
680
-            // run the insert
681
-            $PRC_ID = EEM_Price::instance()->insert($set_column_values);
682
-            if ($PRC_ID) {
683
-                // make sure this new price modifier is attached to the ticket but ONLY if it is not a tax type
684
-                $price = EEM_price::instance()->get_one_by_ID($PRC_ID);
685
-                if (
686
-                    $price instanceof EE_Price
687
-                    && $price->type_obj() instanceof EE_Price_type
688
-                    && $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax
689
-                ) {
690
-                    $ticket = EEM_Ticket::instance()->get_one_by_ID(1);
691
-                    $ticket->_add_relation_to($price, 'Price');
692
-                    $ticket->save();
693
-                }
694
-                $updated = 1;
695
-            }
696
-            $action_desc = 'created';
697
-        } else {
698
-            $PRC_ID = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
699
-            // run the update
700
-            $where_cols_n_values = ['PRC_ID' => $PRC_ID];
701
-            $updated             = EEM_Price::instance()->update($set_column_values, [$where_cols_n_values]);
702
-
703
-            $price = EEM_Price::instance()->get_one_by_ID($PRC_ID);
704
-            if ($price instanceof EE_Price && $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax) {
705
-                // if this is $PRC_ID == 1,
706
-                // then we need to update the default ticket attached to this price so the TKT_price value is updated.
707
-                if ($PRC_ID === 1) {
708
-                    $ticket = $price->get_first_related('Ticket');
709
-                    if ($ticket) {
710
-                        $ticket->set('TKT_price', $price->get('PRC_amount'));
711
-                        $ticket->set('TKT_name', $price->get('PRC_name'));
712
-                        $ticket->set('TKT_description', $price->get('PRC_desc'));
713
-                        $ticket->save();
714
-                    }
715
-                } else {
716
-                    // we make sure this price is attached to base ticket. but ONLY if its not a tax ticket type.
717
-                    $ticket = EEM_Ticket::instance()->get_one_by_ID(1);
718
-                    $ticket->_add_relation_to($PRC_ID, 'Price');
719
-                    $ticket->save();
720
-                }
721
-            }
722
-
723
-            $action_desc = 'updated';
724
-        }
725
-
726
-        $query_args = ['action' => 'edit_price', 'id' => $PRC_ID];
727
-
728
-        $this->_redirect_after_action($updated, 'Prices', $action_desc, $query_args);
729
-    }
730
-
731
-
732
-    /**
733
-     * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
734
-     * @return void
735
-     * @throws EE_Error
736
-     * @throws ReflectionException
737
-     */
738
-    protected function _trash_or_restore_price(bool $trash = true)
739
-    {
740
-        $entity_model = EEM_Price::instance();
741
-        $action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
742
-        $result       = $this->trashRestoreDeleteEntities(
743
-            $entity_model,
744
-            'id',
745
-            $action,
746
-            'PRC_deleted',
747
-            [$this, 'adjustTicketRelations']
748
-        );
749
-
750
-        if ($result) {
751
-            $msg = $trash
752
-                ? esc_html(
753
-                    _n(
754
-                        'The Price has been trashed',
755
-                        'The Prices have been trashed',
756
-                        $result,
757
-                        'event_espresso'
758
-                    )
759
-                )
760
-                : esc_html(
761
-                    _n(
762
-                        'The Price has been restored',
763
-                        'The Prices have been restored',
764
-                        $result,
765
-                        'event_espresso'
766
-                    )
767
-                );
768
-            EE_Error::add_success($msg);
769
-        }
770
-
771
-        $this->_redirect_after_action(
772
-            $result,
773
-            _n('Price', 'Prices', $result, 'event_espresso'),
774
-            $trash ? 'trashed' : 'restored',
775
-            ['action' => 'default'],
776
-            true
777
-        );
778
-    }
779
-
780
-
781
-    /**
782
-     * @param EEM_Base   $entity_model
783
-     * @param int|string $entity_ID
784
-     * @param string     $action
785
-     * @param int        $result
786
-     * @throws EE_Error
787
-     * @throws ReflectionException
788
-     * @since $VID:$
789
-     */
790
-    public function adjustTicketRelations(EEM_Base $entity_model, $entity_ID, string $action, int $result)
791
-    {
792
-        if (! $entity_ID || (float) $result < 1) {
793
-            return;
794
-        }
795
-
796
-        $entity = $entity_model->get_one_by_ID($entity_ID);
797
-        if (! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
798
-            return;
799
-        }
800
-
801
-        // get default tickets for updating
802
-        $default_tickets = EEM_Ticket::instance()->get_all_default_tickets();
803
-        foreach ($default_tickets as $default_ticket) {
804
-            if (! $default_ticket instanceof EE_Ticket) {
805
-                continue;
806
-            }
807
-            switch ($action) {
808
-                case EE_Admin_List_Table::ACTION_DELETE:
809
-                case EE_Admin_List_Table::ACTION_TRASH:
810
-                    // if trashing then remove relations to base default ticket.
811
-                    $default_ticket->_remove_relation_to($entity_ID, 'Price');
812
-                    break;
813
-                case EE_Admin_List_Table::ACTION_RESTORE:
814
-                    // if restoring then add back to base default ticket
815
-                    $default_ticket->_add_relation_to($entity_ID, 'Price');
816
-                    break;
817
-            }
818
-            $default_ticket->save();
819
-        }
820
-    }
821
-
822
-
823
-    /**
824
-     * @return void
825
-     * @throws EE_Error
826
-     * @throws ReflectionException
827
-     */
828
-    protected function _delete_price()
829
-    {
830
-        $entity_model = EEM_Price::instance();
831
-        $deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
832
-        $entity       = $entity_model->item_name($deleted);
833
-        $this->_redirect_after_action($deleted, $entity, 'deleted', ['action' => 'default']);
834
-    }
835
-
836
-
837
-    /**
838
-     * @throws EE_Error
839
-     * @throws ReflectionException
840
-     */
841
-    public function update_price_order()
842
-    {
843
-        // grab our row IDs
844
-        $row_ids = $this->request->getRequestParam('row_ids', '');
845
-        $row_ids = explode(',', rtrim($row_ids, ','));
846
-
847
-        $all_updated = true;
848
-        foreach ($row_ids as $i => $row_id) {
849
-            // Update the prices when re-ordering
850
-            $fields_n_values = ['PRC_order' => $i + 1];
851
-            $query_params    = [['PRC_ID' => absint($row_id)]];
852
-            // any failure will toggle $all_updated to false
853
-            $all_updated = $row_id && EEM_Price::instance()->update($fields_n_values, $query_params) !== false
854
-                ? $all_updated
855
-                : false;
856
-        }
857
-        $success = $all_updated ? esc_html__('Price order was updated successfully.', 'event_espresso') : false;
858
-        $errors  = ! $all_updated ? esc_html__('An error occurred. The price order was not updated.', 'event_espresso')
859
-            : false;
860
-
861
-        echo wp_json_encode(['return_data' => false, 'success' => $success, 'errors' => $errors]);
862
-        die();
863
-    }
864
-
865
-
866
-    /******************************************************************************************************************
15
+	protected function _init_page_props()
16
+	{
17
+		$this->page_slug        = PRICING_PG_SLUG;
18
+		$this->page_label       = PRICING_LABEL;
19
+		$this->_admin_base_url  = PRICING_ADMIN_URL;
20
+		$this->_admin_base_path = PRICING_ADMIN;
21
+	}
22
+
23
+
24
+	protected function _ajax_hooks()
25
+	{
26
+		add_action('wp_ajax_espresso_update_prices_order', [$this, 'update_price_order']);
27
+	}
28
+
29
+
30
+	protected function _define_page_props()
31
+	{
32
+		$this->_admin_page_title = PRICING_LABEL;
33
+		$this->_labels           = [
34
+			'buttons' => [
35
+				'add'         => esc_html__('Add New Default Price', 'event_espresso'),
36
+				'edit'        => esc_html__('Edit Default Price', 'event_espresso'),
37
+				'delete'      => esc_html__('Delete Default Price', 'event_espresso'),
38
+				'add_type'    => esc_html__('Add New Default Price Type', 'event_espresso'),
39
+				'edit_type'   => esc_html__('Edit Price Type', 'event_espresso'),
40
+				'delete_type' => esc_html__('Delete Price Type', 'event_espresso'),
41
+			],
42
+		];
43
+	}
44
+
45
+
46
+	/**
47
+	 * an array for storing request actions and their corresponding methods
48
+	 *
49
+	 * @return void
50
+	 */
51
+	protected function _set_page_routes()
52
+	{
53
+		$PRC_ID             = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
54
+		$PRT_ID             = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
55
+		$this->_page_routes = [
56
+			'default'                     => [
57
+				'func'       => '_price_overview_list_table',
58
+				'capability' => 'ee_read_default_prices',
59
+			],
60
+			'add_new_price'               => [
61
+				'func'       => '_edit_price_details',
62
+				'args'       => ['new_price' => true],
63
+				'capability' => 'ee_edit_default_prices',
64
+			],
65
+			'edit_price'                  => [
66
+				'func'       => '_edit_price_details',
67
+				'args'       => ['new_price' => false],
68
+				'capability' => 'ee_edit_default_price',
69
+				'obj_id'     => $PRC_ID,
70
+			],
71
+			'insert_price'                => [
72
+				'func'       => '_insert_or_update_price',
73
+				'args'       => ['new_price' => true],
74
+				'noheader'   => true,
75
+				'capability' => 'ee_edit_default_prices',
76
+			],
77
+			'update_price'                => [
78
+				'func'       => '_insert_or_update_price',
79
+				'args'       => ['new_price' => false],
80
+				'noheader'   => true,
81
+				'capability' => 'ee_edit_default_price',
82
+				'obj_id'     => $PRC_ID,
83
+			],
84
+			'trash_price'                 => [
85
+				'func'       => '_trash_or_restore_price',
86
+				'args'       => ['trash' => true],
87
+				'noheader'   => true,
88
+				'capability' => 'ee_delete_default_price',
89
+				'obj_id'     => $PRC_ID,
90
+			],
91
+			'restore_price'               => [
92
+				'func'       => '_trash_or_restore_price',
93
+				'args'       => ['trash' => false],
94
+				'noheader'   => true,
95
+				'capability' => 'ee_delete_default_price',
96
+				'obj_id'     => $PRC_ID,
97
+			],
98
+			'delete_price'                => [
99
+				'func'       => '_delete_price',
100
+				'noheader'   => true,
101
+				'capability' => 'ee_delete_default_price',
102
+				'obj_id'     => $PRC_ID,
103
+			],
104
+			'espresso_update_price_order' => [
105
+				'func'       => 'update_price_order',
106
+				'noheader'   => true,
107
+				'capability' => 'ee_edit_default_prices',
108
+			],
109
+			// price types
110
+			'price_types'                 => [
111
+				'func'       => '_price_types_overview_list_table',
112
+				'capability' => 'ee_read_default_price_types',
113
+			],
114
+			'add_new_price_type'          => [
115
+				'func'       => '_edit_price_type_details',
116
+				'capability' => 'ee_edit_default_price_types',
117
+			],
118
+			'edit_price_type'             => [
119
+				'func'       => '_edit_price_type_details',
120
+				'capability' => 'ee_edit_default_price_type',
121
+				'obj_id'     => $PRT_ID,
122
+			],
123
+			'insert_price_type'           => [
124
+				'func'       => '_insert_or_update_price_type',
125
+				'args'       => ['new_price_type' => true],
126
+				'noheader'   => true,
127
+				'capability' => 'ee_edit_default_price_types',
128
+			],
129
+			'update_price_type'           => [
130
+				'func'       => '_insert_or_update_price_type',
131
+				'args'       => ['new_price_type' => false],
132
+				'noheader'   => true,
133
+				'capability' => 'ee_edit_default_price_type',
134
+				'obj_id'     => $PRT_ID,
135
+			],
136
+			'trash_price_type'            => [
137
+				'func'       => '_trash_or_restore_price_type',
138
+				'args'       => ['trash' => true],
139
+				'noheader'   => true,
140
+				'capability' => 'ee_delete_default_price_type',
141
+				'obj_id'     => $PRT_ID,
142
+			],
143
+			'restore_price_type'          => [
144
+				'func'       => '_trash_or_restore_price_type',
145
+				'args'       => ['trash' => false],
146
+				'noheader'   => true,
147
+				'capability' => 'ee_delete_default_price_type',
148
+				'obj_id'     => $PRT_ID,
149
+			],
150
+			'delete_price_type'           => [
151
+				'func'       => '_delete_price_type',
152
+				'noheader'   => true,
153
+				'capability' => 'ee_delete_default_price_type',
154
+				'obj_id'     => $PRT_ID,
155
+			],
156
+			'tax_settings'                => [
157
+				'func'       => '_tax_settings',
158
+				'capability' => 'manage_options',
159
+			],
160
+			'update_tax_settings'         => [
161
+				'func'       => '_update_tax_settings',
162
+				'capability' => 'manage_options',
163
+				'noheader'   => true,
164
+			],
165
+		];
166
+	}
167
+
168
+
169
+	protected function _set_page_config()
170
+	{
171
+		$PRC_ID             = $this->request->getRequestParam('id', 0, DataType::INTEGER);
172
+		$this->_page_config = [
173
+			'default'            => [
174
+				'nav'           => [
175
+					'label' => esc_html__('Default Pricing', 'event_espresso'),
176
+					'order' => 10,
177
+				],
178
+				'list_table'    => 'Prices_List_Table',
179
+				'metaboxes'     => $this->_default_espresso_metaboxes,
180
+				'help_tabs'     => [
181
+					'pricing_default_pricing_help_tab'                           => [
182
+						'title'    => esc_html__('Default Pricing', 'event_espresso'),
183
+						'filename' => 'pricing_default_pricing',
184
+					],
185
+					'pricing_default_pricing_table_column_headings_help_tab'     => [
186
+						'title'    => esc_html__('Default Pricing Table Column Headings', 'event_espresso'),
187
+						'filename' => 'pricing_default_pricing_table_column_headings',
188
+					],
189
+					'pricing_default_pricing_views_bulk_actions_search_help_tab' => [
190
+						'title'    => esc_html__('Default Pricing Views & Bulk Actions & Search', 'event_espresso'),
191
+						'filename' => 'pricing_default_pricing_views_bulk_actions_search',
192
+					],
193
+				],
194
+				'require_nonce' => false,
195
+			],
196
+			'add_new_price'      => [
197
+				'nav'           => [
198
+					'label'      => esc_html__('Add New Default Price', 'event_espresso'),
199
+					'order'      => 20,
200
+					'persistent' => false,
201
+				],
202
+				'help_tabs'     => [
203
+					'add_new_default_price_help_tab' => [
204
+						'title'    => esc_html__('Add New Default Price', 'event_espresso'),
205
+						'filename' => 'pricing_add_new_default_price',
206
+					],
207
+				],
208
+				'metaboxes'     => array_merge(
209
+					['_publish_post_box'],
210
+					$this->_default_espresso_metaboxes
211
+				),
212
+				'require_nonce' => false,
213
+			],
214
+			'edit_price'         => [
215
+				'nav'           => [
216
+					'label'      => esc_html__('Edit Default Price', 'event_espresso'),
217
+					'order'      => 20,
218
+					'url'        => $PRC_ID
219
+						? add_query_arg(['id' => $PRC_ID], $this->_current_page_view_url)
220
+						: $this->_admin_base_url,
221
+					'persistent' => false,
222
+				],
223
+				'metaboxes'     => array_merge(
224
+					['_publish_post_box'],
225
+					$this->_default_espresso_metaboxes
226
+				),
227
+				'help_tabs'     => [
228
+					'edit_default_price_help_tab' => [
229
+						'title'    => esc_html__('Edit Default Price', 'event_espresso'),
230
+						'filename' => 'pricing_edit_default_price',
231
+					],
232
+				],
233
+				'require_nonce' => false,
234
+			],
235
+			'price_types'        => [
236
+				'nav'           => [
237
+					'label' => esc_html__('Price Types', 'event_espresso'),
238
+					'order' => 30,
239
+				],
240
+				'list_table'    => 'Price_Types_List_Table',
241
+				'help_tabs'     => [
242
+					'pricing_price_types_help_tab'                           => [
243
+						'title'    => esc_html__('Price Types', 'event_espresso'),
244
+						'filename' => 'pricing_price_types',
245
+					],
246
+					'pricing_price_types_table_column_headings_help_tab'     => [
247
+						'title'    => esc_html__('Price Types Table Column Headings', 'event_espresso'),
248
+						'filename' => 'pricing_price_types_table_column_headings',
249
+					],
250
+					'pricing_price_types_views_bulk_actions_search_help_tab' => [
251
+						'title'    => esc_html__('Price Types Views & Bulk Actions & Search', 'event_espresso'),
252
+						'filename' => 'pricing_price_types_views_bulk_actions_search',
253
+					],
254
+				],
255
+				'metaboxes'     => $this->_default_espresso_metaboxes,
256
+				'require_nonce' => false,
257
+			],
258
+			'add_new_price_type' => [
259
+				'nav'           => [
260
+					'label'      => esc_html__('Add New Price Type', 'event_espresso'),
261
+					'order'      => 40,
262
+					'persistent' => false,
263
+				],
264
+				'help_tabs'     => [
265
+					'add_new_price_type_help_tab' => [
266
+						'title'    => esc_html__('Add New Price Type', 'event_espresso'),
267
+						'filename' => 'pricing_add_new_price_type',
268
+					],
269
+				],
270
+				'metaboxes'     => array_merge(
271
+					['_publish_post_box'],
272
+					$this->_default_espresso_metaboxes
273
+				),
274
+				'require_nonce' => false,
275
+			],
276
+			'edit_price_type'    => [
277
+				'nav'           => [
278
+					'label'      => esc_html__('Edit Price Type', 'event_espresso'),
279
+					'order'      => 40,
280
+					'persistent' => false,
281
+				],
282
+				'help_tabs'     => [
283
+					'edit_price_type_help_tab' => [
284
+						'title'    => esc_html__('Edit Price Type', 'event_espresso'),
285
+						'filename' => 'pricing_edit_price_type',
286
+					],
287
+				],
288
+				'metaboxes'     => array_merge(
289
+					['_publish_post_box'],
290
+					$this->_default_espresso_metaboxes
291
+				),
292
+				'require_nonce' => false,
293
+			],
294
+			'tax_settings'       => [
295
+				'nav'           => [
296
+					'label' => esc_html__('Tax Settings', 'event_espresso'),
297
+					'order' => 40,
298
+				],
299
+				'labels'        => [
300
+					'publishbox' => esc_html__('Update Tax Settings', 'event_espresso'),
301
+				],
302
+				'metaboxes'     => array_merge(
303
+					['_publish_post_box'],
304
+					$this->_default_espresso_metaboxes
305
+				),
306
+				'require_nonce' => true,
307
+			],
308
+		];
309
+	}
310
+
311
+
312
+	protected function _add_screen_options()
313
+	{
314
+		// todo
315
+	}
316
+
317
+
318
+	protected function _add_screen_options_default()
319
+	{
320
+		$this->_per_page_screen_option();
321
+	}
322
+
323
+
324
+	protected function _add_screen_options_price_types()
325
+	{
326
+		$page_title              = $this->_admin_page_title;
327
+		$this->_admin_page_title = esc_html__('Price Types', 'event_espresso');
328
+		$this->_per_page_screen_option();
329
+		$this->_admin_page_title = $page_title;
330
+	}
331
+
332
+
333
+	protected function _add_feature_pointers()
334
+	{
335
+	}
336
+
337
+
338
+	public function load_scripts_styles()
339
+	{
340
+		// styles
341
+		wp_enqueue_style('espresso-ui-theme');
342
+		wp_register_style(
343
+			'espresso_PRICING',
344
+			PRICING_ASSETS_URL . 'espresso_pricing_admin.css',
345
+			[],
346
+			EVENT_ESPRESSO_VERSION
347
+		);
348
+		wp_enqueue_style('espresso_PRICING');
349
+
350
+		// scripts
351
+		wp_enqueue_script('ee_admin_js');
352
+		wp_enqueue_script('jquery-ui-position');
353
+		wp_enqueue_script('jquery-ui-widget');
354
+		wp_register_script(
355
+			'espresso_PRICING',
356
+			PRICING_ASSETS_URL . 'espresso_pricing_admin.js',
357
+			['jquery'],
358
+			EVENT_ESPRESSO_VERSION,
359
+			true
360
+		);
361
+		wp_enqueue_script('espresso_PRICING');
362
+	}
363
+
364
+
365
+	public function load_scripts_styles_default()
366
+	{
367
+		wp_enqueue_script('espresso_ajax_table_sorting');
368
+	}
369
+
370
+
371
+	public function admin_footer_scripts()
372
+	{
373
+	}
374
+
375
+
376
+	public function admin_init()
377
+	{
378
+	}
379
+
380
+
381
+	public function admin_notices()
382
+	{
383
+	}
384
+
385
+
386
+	protected function _set_list_table_views_default()
387
+	{
388
+		$this->_views = [
389
+			'all' => [
390
+				'slug'        => 'all',
391
+				'label'       => esc_html__('View All Default Pricing', 'event_espresso'),
392
+				'count'       => 0,
393
+				'bulk_action' => [
394
+					'trash_price' => esc_html__('Move to Trash', 'event_espresso'),
395
+				],
396
+			],
397
+		];
398
+
399
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_default_prices', 'pricing_trash_price')) {
400
+			$this->_views['trashed'] = [
401
+				'slug'        => 'trashed',
402
+				'label'       => esc_html__('Trash', 'event_espresso'),
403
+				'count'       => 0,
404
+				'bulk_action' => [
405
+					'restore_price' => esc_html__('Restore from Trash', 'event_espresso'),
406
+					'delete_price'  => esc_html__('Delete Permanently', 'event_espresso'),
407
+				],
408
+			];
409
+		}
410
+	}
411
+
412
+
413
+	protected function _set_list_table_views_price_types()
414
+	{
415
+		$this->_views = [
416
+			'all' => [
417
+				'slug'        => 'all',
418
+				'label'       => esc_html__('All', 'event_espresso'),
419
+				'count'       => 0,
420
+				'bulk_action' => [
421
+					'trash_price_type' => esc_html__('Move to Trash', 'event_espresso'),
422
+				],
423
+			],
424
+		];
425
+
426
+		if (
427
+			EE_Registry::instance()->CAP->current_user_can(
428
+				'ee_delete_default_price_types',
429
+				'pricing_trash_price_type'
430
+			)
431
+		) {
432
+			$this->_views['trashed'] = [
433
+				'slug'        => 'trashed',
434
+				'label'       => esc_html__('Trash', 'event_espresso'),
435
+				'count'       => 0,
436
+				'bulk_action' => [
437
+					'restore_price_type' => esc_html__('Restore from Trash', 'event_espresso'),
438
+					'delete_price_type'  => esc_html__('Delete Permanently', 'event_espresso'),
439
+				],
440
+			];
441
+		}
442
+	}
443
+
444
+
445
+	/**
446
+	 * generates HTML for main Prices Admin page
447
+	 *
448
+	 * @return void
449
+	 * @throws EE_Error
450
+	 */
451
+	protected function _price_overview_list_table()
452
+	{
453
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
454
+			'add_new_price',
455
+			'add',
456
+			[],
457
+			'add-new-h2'
458
+		);
459
+		$this->_admin_page_title .= $this->_learn_more_about_pricing_link();
460
+		$this->_search_btn_label = esc_html__('Default Prices', 'event_espresso');
461
+		$this->display_admin_list_table_page_with_sidebar();
462
+	}
463
+
464
+
465
+	/**
466
+	 * retrieve data for Prices List table
467
+	 *
468
+	 * @param int  $per_page how many prices displayed per page
469
+	 * @param bool $count    return the count or objects
470
+	 * @param bool $trashed  whether the current view is of the trash can - eww yuck!
471
+	 * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
472
+	 * @throws EE_Error
473
+	 * @throws ReflectionException
474
+	 */
475
+	public function get_prices_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
476
+	{
477
+		// start with an empty array
478
+		$event_pricing = [];
479
+
480
+		require_once(PRICING_ADMIN . 'Prices_List_Table.class.php');
481
+
482
+		$orderby = $this->request->getRequestParam('orderby', '');
483
+		$order   = $this->request->getRequestParam('order', 'ASC');
484
+
485
+		switch ($orderby) {
486
+			case 'name':
487
+				$orderby = ['PRC_name' => $order];
488
+				break;
489
+			case 'type':
490
+				$orderby = ['Price_Type.PRT_name' => $order];
491
+				break;
492
+			case 'amount':
493
+				$orderby = ['PRC_amount' => $order];
494
+				break;
495
+			default:
496
+				$orderby = ['PRC_order' => $order, 'Price_Type.PRT_order' => $order, 'PRC_ID' => $order];
497
+		}
498
+
499
+		$current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
500
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
501
+
502
+		$where = [
503
+			'PRC_is_default' => 1,
504
+			'PRC_deleted'    => $trashed,
505
+		];
506
+
507
+		$offset = ($current_page - 1) * $per_page;
508
+		$limit  = [$offset, $per_page];
509
+
510
+		$search_term = $this->request->getRequestParam('s');
511
+		if ($search_term) {
512
+			$search_term = "%{$search_term}%";
513
+			$where['OR'] = [
514
+				'PRC_name'            => ['LIKE', $search_term],
515
+				'PRC_desc'            => ['LIKE', $search_term],
516
+				'PRC_amount'          => ['LIKE', $search_term],
517
+				'Price_Type.PRT_name' => ['LIKE', $search_term],
518
+			];
519
+		}
520
+
521
+		$query_params = [
522
+			$where,
523
+			'order_by' => $orderby,
524
+			'limit'    => $limit,
525
+			'group_by' => 'PRC_ID',
526
+		];
527
+
528
+		if ($count) {
529
+			return $trashed
530
+				? EEM_Price::instance()->count([$where])
531
+				: EEM_Price::instance()->count_deleted_and_undeleted([$where]);
532
+		}
533
+		return EEM_Price::instance()->get_all_deleted_and_undeleted($query_params);
534
+	}
535
+
536
+
537
+	/**
538
+	 * @return void
539
+	 * @throws EE_Error
540
+	 * @throws ReflectionException
541
+	 */
542
+	protected function _edit_price_details()
543
+	{
544
+		// grab price ID
545
+		$PRC_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
546
+		// change page title based on request action
547
+		switch ($this->_req_action) {
548
+			case 'add_new_price':
549
+				$this->_admin_page_title = esc_html__('Add New Price', 'event_espresso');
550
+				break;
551
+			case 'edit_price':
552
+				$this->_admin_page_title = esc_html__('Edit Price', 'event_espresso');
553
+				break;
554
+			default:
555
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
556
+		}
557
+		// add PRC_ID to title if editing
558
+		$this->_admin_page_title = $PRC_ID ? $this->_admin_page_title . ' # ' . $PRC_ID : $this->_admin_page_title;
559
+
560
+		if ($PRC_ID) {
561
+			$price                    = EEM_Price::instance()->get_one_by_ID($PRC_ID);
562
+			$additional_hidden_fields = [
563
+				'PRC_ID' => ['type' => 'hidden', 'value' => $PRC_ID],
564
+			];
565
+			$this->_set_add_edit_form_tags('update_price', $additional_hidden_fields);
566
+		} else {
567
+			$price = EEM_Price::instance()->get_new_price();
568
+			$this->_set_add_edit_form_tags('insert_price');
569
+		}
570
+
571
+		if (! $price instanceof EE_Price) {
572
+			throw new RuntimeException(
573
+				sprintf(
574
+					esc_html__(
575
+						'A valid Price could not be retrieved from the database with ID: %1$s',
576
+						'event_espresso'
577
+					),
578
+					$PRC_ID
579
+				)
580
+			);
581
+		}
582
+
583
+		$this->_template_args['PRC_ID'] = $PRC_ID;
584
+		$this->_template_args['price']  = $price;
585
+
586
+		$default_base_price = $price->type_obj() && $price->type_obj()->base_type() === 1;
587
+
588
+		$this->_template_args['default_base_price'] = $default_base_price;
589
+
590
+		// get price types
591
+		$price_types = EEM_Price_Type::instance()->get_all([['PBT_ID' => ['!=', 1]]]);
592
+		if (empty($price_types)) {
593
+			$msg = esc_html__(
594
+				'You have no price types defined. Please add a price type before adding a price.',
595
+				'event_espresso'
596
+			);
597
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
598
+			$this->display_admin_page_with_sidebar();
599
+		}
600
+		$attributes       = [];
601
+		$price_type_names = [];
602
+		$attributes[]     = 'id="PRT_ID"';
603
+		if ($default_base_price) {
604
+			$attributes[]       = 'disabled="disabled"';
605
+			$price_type_names[] = ['id' => 1, 'text' => esc_html__('Base Price', 'event_espresso')];
606
+		}
607
+		foreach ($price_types as $type) {
608
+			$price_type_names[] = ['id' => $type->ID(), 'text' => $type->name()];
609
+		}
610
+		$this->_template_args['attributes']  = implode(' ', $attributes);
611
+		$this->_template_args['price_types'] = $price_type_names;
612
+
613
+		$this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
614
+		$this->_template_args['admin_page_content']            = $this->_edit_price_details_meta_box();
615
+
616
+		$this->_set_publish_post_box_vars('id', $PRC_ID);
617
+		// the details template wrapper
618
+		$this->display_admin_page_with_sidebar();
619
+	}
620
+
621
+
622
+	/**
623
+	 *
624
+	 * @return string
625
+	 */
626
+	public function _edit_price_details_meta_box(): string
627
+	{
628
+		return EEH_Template::display_template(
629
+			PRICING_TEMPLATE_PATH . 'pricing_details_main_meta_box.template.php',
630
+			$this->_template_args,
631
+			true
632
+		);
633
+	}
634
+
635
+
636
+	/**
637
+	 * @return array
638
+	 * @throws EE_Error
639
+	 * @throws ReflectionException
640
+	 */
641
+	protected function set_price_column_values(): array
642
+	{
643
+		$PRC_order = 0;
644
+		$PRT_ID    = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
645
+		if ($PRT_ID) {
646
+			/** @var EE_Price_Type $price_type */
647
+			$price_type = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
648
+			if ($price_type instanceof EE_Price_Type) {
649
+				$PRC_order = $price_type->order();
650
+			}
651
+		}
652
+		return [
653
+			'PRT_ID'         => $PRT_ID,
654
+			'PRC_amount'     => $this->request->getRequestParam('PRC_amount', 0, DataType::FLOAT),
655
+			'PRC_name'       => $this->request->getRequestParam('PRC_name'),
656
+			'PRC_desc'       => $this->request->getRequestParam('PRC_desc'),
657
+			'PRC_is_default' => 1,
658
+			'PRC_overrides'  => null,
659
+			'PRC_order'      => $PRC_order,
660
+			'PRC_deleted'    => 0,
661
+			'PRC_parent'     => 0,
662
+		];
663
+	}
664
+
665
+
666
+	/**
667
+	 * @param bool $insert - whether to insert or update
668
+	 * @return void
669
+	 * @throws EE_Error
670
+	 * @throws ReflectionException
671
+	 */
672
+	protected function _insert_or_update_price(bool $insert = false)
673
+	{
674
+		// why be so pessimistic ???  : (
675
+		$updated = 0;
676
+
677
+		$set_column_values = $this->set_price_column_values();
678
+		// is this a new Price ?
679
+		if ($insert) {
680
+			// run the insert
681
+			$PRC_ID = EEM_Price::instance()->insert($set_column_values);
682
+			if ($PRC_ID) {
683
+				// make sure this new price modifier is attached to the ticket but ONLY if it is not a tax type
684
+				$price = EEM_price::instance()->get_one_by_ID($PRC_ID);
685
+				if (
686
+					$price instanceof EE_Price
687
+					&& $price->type_obj() instanceof EE_Price_type
688
+					&& $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax
689
+				) {
690
+					$ticket = EEM_Ticket::instance()->get_one_by_ID(1);
691
+					$ticket->_add_relation_to($price, 'Price');
692
+					$ticket->save();
693
+				}
694
+				$updated = 1;
695
+			}
696
+			$action_desc = 'created';
697
+		} else {
698
+			$PRC_ID = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
699
+			// run the update
700
+			$where_cols_n_values = ['PRC_ID' => $PRC_ID];
701
+			$updated             = EEM_Price::instance()->update($set_column_values, [$where_cols_n_values]);
702
+
703
+			$price = EEM_Price::instance()->get_one_by_ID($PRC_ID);
704
+			if ($price instanceof EE_Price && $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax) {
705
+				// if this is $PRC_ID == 1,
706
+				// then we need to update the default ticket attached to this price so the TKT_price value is updated.
707
+				if ($PRC_ID === 1) {
708
+					$ticket = $price->get_first_related('Ticket');
709
+					if ($ticket) {
710
+						$ticket->set('TKT_price', $price->get('PRC_amount'));
711
+						$ticket->set('TKT_name', $price->get('PRC_name'));
712
+						$ticket->set('TKT_description', $price->get('PRC_desc'));
713
+						$ticket->save();
714
+					}
715
+				} else {
716
+					// we make sure this price is attached to base ticket. but ONLY if its not a tax ticket type.
717
+					$ticket = EEM_Ticket::instance()->get_one_by_ID(1);
718
+					$ticket->_add_relation_to($PRC_ID, 'Price');
719
+					$ticket->save();
720
+				}
721
+			}
722
+
723
+			$action_desc = 'updated';
724
+		}
725
+
726
+		$query_args = ['action' => 'edit_price', 'id' => $PRC_ID];
727
+
728
+		$this->_redirect_after_action($updated, 'Prices', $action_desc, $query_args);
729
+	}
730
+
731
+
732
+	/**
733
+	 * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
734
+	 * @return void
735
+	 * @throws EE_Error
736
+	 * @throws ReflectionException
737
+	 */
738
+	protected function _trash_or_restore_price(bool $trash = true)
739
+	{
740
+		$entity_model = EEM_Price::instance();
741
+		$action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
742
+		$result       = $this->trashRestoreDeleteEntities(
743
+			$entity_model,
744
+			'id',
745
+			$action,
746
+			'PRC_deleted',
747
+			[$this, 'adjustTicketRelations']
748
+		);
749
+
750
+		if ($result) {
751
+			$msg = $trash
752
+				? esc_html(
753
+					_n(
754
+						'The Price has been trashed',
755
+						'The Prices have been trashed',
756
+						$result,
757
+						'event_espresso'
758
+					)
759
+				)
760
+				: esc_html(
761
+					_n(
762
+						'The Price has been restored',
763
+						'The Prices have been restored',
764
+						$result,
765
+						'event_espresso'
766
+					)
767
+				);
768
+			EE_Error::add_success($msg);
769
+		}
770
+
771
+		$this->_redirect_after_action(
772
+			$result,
773
+			_n('Price', 'Prices', $result, 'event_espresso'),
774
+			$trash ? 'trashed' : 'restored',
775
+			['action' => 'default'],
776
+			true
777
+		);
778
+	}
779
+
780
+
781
+	/**
782
+	 * @param EEM_Base   $entity_model
783
+	 * @param int|string $entity_ID
784
+	 * @param string     $action
785
+	 * @param int        $result
786
+	 * @throws EE_Error
787
+	 * @throws ReflectionException
788
+	 * @since $VID:$
789
+	 */
790
+	public function adjustTicketRelations(EEM_Base $entity_model, $entity_ID, string $action, int $result)
791
+	{
792
+		if (! $entity_ID || (float) $result < 1) {
793
+			return;
794
+		}
795
+
796
+		$entity = $entity_model->get_one_by_ID($entity_ID);
797
+		if (! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
798
+			return;
799
+		}
800
+
801
+		// get default tickets for updating
802
+		$default_tickets = EEM_Ticket::instance()->get_all_default_tickets();
803
+		foreach ($default_tickets as $default_ticket) {
804
+			if (! $default_ticket instanceof EE_Ticket) {
805
+				continue;
806
+			}
807
+			switch ($action) {
808
+				case EE_Admin_List_Table::ACTION_DELETE:
809
+				case EE_Admin_List_Table::ACTION_TRASH:
810
+					// if trashing then remove relations to base default ticket.
811
+					$default_ticket->_remove_relation_to($entity_ID, 'Price');
812
+					break;
813
+				case EE_Admin_List_Table::ACTION_RESTORE:
814
+					// if restoring then add back to base default ticket
815
+					$default_ticket->_add_relation_to($entity_ID, 'Price');
816
+					break;
817
+			}
818
+			$default_ticket->save();
819
+		}
820
+	}
821
+
822
+
823
+	/**
824
+	 * @return void
825
+	 * @throws EE_Error
826
+	 * @throws ReflectionException
827
+	 */
828
+	protected function _delete_price()
829
+	{
830
+		$entity_model = EEM_Price::instance();
831
+		$deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
832
+		$entity       = $entity_model->item_name($deleted);
833
+		$this->_redirect_after_action($deleted, $entity, 'deleted', ['action' => 'default']);
834
+	}
835
+
836
+
837
+	/**
838
+	 * @throws EE_Error
839
+	 * @throws ReflectionException
840
+	 */
841
+	public function update_price_order()
842
+	{
843
+		// grab our row IDs
844
+		$row_ids = $this->request->getRequestParam('row_ids', '');
845
+		$row_ids = explode(',', rtrim($row_ids, ','));
846
+
847
+		$all_updated = true;
848
+		foreach ($row_ids as $i => $row_id) {
849
+			// Update the prices when re-ordering
850
+			$fields_n_values = ['PRC_order' => $i + 1];
851
+			$query_params    = [['PRC_ID' => absint($row_id)]];
852
+			// any failure will toggle $all_updated to false
853
+			$all_updated = $row_id && EEM_Price::instance()->update($fields_n_values, $query_params) !== false
854
+				? $all_updated
855
+				: false;
856
+		}
857
+		$success = $all_updated ? esc_html__('Price order was updated successfully.', 'event_espresso') : false;
858
+		$errors  = ! $all_updated ? esc_html__('An error occurred. The price order was not updated.', 'event_espresso')
859
+			: false;
860
+
861
+		echo wp_json_encode(['return_data' => false, 'success' => $success, 'errors' => $errors]);
862
+		die();
863
+	}
864
+
865
+
866
+	/******************************************************************************************************************
867 867
      ***********************************************  TICKET PRICE TYPES  *********************************************
868 868
      ******************************************************************************************************************/
869 869
 
870 870
 
871
-    /**
872
-     * generates HTML for main Prices Admin page
873
-     *
874
-     * @return void
875
-     * @throws EE_Error
876
-     */
877
-    protected function _price_types_overview_list_table()
878
-    {
879
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
880
-            'add_new_price_type',
881
-            'add_type',
882
-            [],
883
-            'add-new-h2'
884
-        );
885
-        $this->_admin_page_title .= $this->_learn_more_about_pricing_link();
886
-        $this->_search_btn_label = esc_html__('Price Types', 'event_espresso');
887
-        $this->display_admin_list_table_page_with_sidebar();
888
-    }
889
-
890
-
891
-    /**
892
-     * retrieve data for Price Types List table
893
-     *
894
-     * @param int  $per_page how many prices displayed per page
895
-     * @param bool $count    return the count or objects
896
-     * @param bool $trashed  whether the current view is of the trash can - eww yuck!
897
-     * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
898
-     * @throws EE_Error
899
-     * @throws ReflectionException
900
-     */
901
-    public function get_price_types_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
902
-    {
903
-        // start with an empty array
904
-        require_once(PRICING_ADMIN . 'Price_Types_List_Table.class.php');
905
-
906
-        $orderby = $this->request->getRequestParam('orderby', '');
907
-        $order   = $this->request->getRequestParam('order', 'ASC');
908
-
909
-        switch ($orderby) {
910
-            case 'name':
911
-                $orderby = ['PRT_name' => $order];
912
-                break;
913
-            default:
914
-                $orderby = ['PRT_order' => $order];
915
-        }
916
-
917
-        $current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
918
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
919
-
920
-        $offset = ($current_page - 1) * $per_page;
921
-        $limit  = [$offset, $per_page];
922
-
923
-        $where = ['PRT_deleted' => $trashed, 'PBT_ID' => ['!=', 1]];
924
-
925
-        $search_term = $this->request->getRequestParam('s');
926
-        if ($search_term) {
927
-            $where['OR'] = [
928
-                'PRT_name' => ['LIKE', "%{$search_term}%"],
929
-            ];
930
-        }
931
-        $query_params = [
932
-            $where,
933
-            'order_by' => $orderby,
934
-            'limit'    => $limit,
935
-        ];
936
-        return $count
937
-            ? EEM_Price_Type::instance()->count_deleted_and_undeleted($query_params)
938
-            : EEM_Price_Type::instance()->get_all_deleted_and_undeleted($query_params);
939
-    }
940
-
941
-
942
-    /**
943
-     * _edit_price_type_details
944
-     *
945
-     * @return void
946
-     * @throws EE_Error
947
-     * @throws ReflectionException
948
-     */
949
-    protected function _edit_price_type_details()
950
-    {
951
-        // grab price type ID
952
-        $PRT_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
953
-        // change page title based on request action
954
-        switch ($this->_req_action) {
955
-            case 'add_new_price_type':
956
-                $this->_admin_page_title = esc_html__('Add New Price Type', 'event_espresso');
957
-                break;
958
-            case 'edit_price_type':
959
-                $this->_admin_page_title = esc_html__('Edit Price Type', 'event_espresso');
960
-                break;
961
-            default:
962
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
963
-        }
964
-        // add PRT_ID to title if editing
965
-        $this->_admin_page_title = $PRT_ID ? $this->_admin_page_title . ' # ' . $PRT_ID : $this->_admin_page_title;
966
-
967
-        if ($PRT_ID) {
968
-            $price_type               = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
969
-            $additional_hidden_fields = ['PRT_ID' => ['type' => 'hidden', 'value' => $PRT_ID]];
970
-            $this->_set_add_edit_form_tags('update_price_type', $additional_hidden_fields);
971
-        } else {
972
-            $price_type = EEM_Price_Type::instance()->get_new_price_type();
973
-            $this->_set_add_edit_form_tags('insert_price_type');
974
-        }
975
-
976
-        if (! $price_type instanceof EE_Price_Type) {
977
-            throw new RuntimeException(
978
-                sprintf(
979
-                    esc_html__(
980
-                        'A valid Price Type could not be retrieved from the database with ID: %1$s',
981
-                        'event_espresso'
982
-                    ),
983
-                    $PRT_ID
984
-                )
985
-            );
986
-        }
987
-
988
-        $this->_template_args['PRT_ID']     = $PRT_ID;
989
-        $this->_template_args['price_type'] = $price_type;
990
-
991
-        $base_types    = EEM_Price_Type::instance()->get_base_types();
992
-        $select_values = [];
993
-        foreach ($base_types as $ref => $text) {
994
-            if ($ref == EEM_Price_Type::base_type_base_price) {
995
-                // do not allow creation of base_type_base_prices because that's a system only base type.
996
-                continue;
997
-            }
998
-            $select_values[] = ['id' => $ref, 'text' => $text];
999
-        }
1000
-
1001
-        $this->_template_args['base_type_select'] = EEH_Form_Fields::select_input(
1002
-            'base_type',
1003
-            $select_values,
1004
-            $price_type->base_type(),
1005
-            'id="price-type-base-type-slct"'
1006
-        );
1007
-
1008
-        $this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
1009
-        $this->_template_args['admin_page_content']            = $this->_edit_price_type_details_meta_box();
1010
-
1011
-        $redirect_URL = add_query_arg(['action' => 'price_types'], $this->_admin_base_url);
1012
-        $this->_set_publish_post_box_vars('id', $PRT_ID, false, $redirect_URL);
1013
-        // the details template wrapper
1014
-        $this->display_admin_page_with_sidebar();
1015
-    }
1016
-
1017
-
1018
-    /**
1019
-     * _edit_price_type_details_meta_box
1020
-     *
1021
-     * @return string
1022
-     */
1023
-    public function _edit_price_type_details_meta_box(): string
1024
-    {
1025
-        return EEH_Template::display_template(
1026
-            PRICING_TEMPLATE_PATH . 'pricing_type_details_main_meta_box.template.php',
1027
-            $this->_template_args,
1028
-            true
1029
-        );
1030
-    }
1031
-
1032
-
1033
-    /**
1034
-     * @return array
1035
-     */
1036
-    protected function set_price_type_column_values(): array
1037
-    {
1038
-        $base_type  = $this->request->getRequestParam(
1039
-            'base_type',
1040
-            EEM_Price_Type::base_type_base_price,
1041
-            DataType::INTEGER
1042
-        );
1043
-        $is_percent = $this->request->getRequestParam('PRT_is_percent', 0, DataType::INTEGER);
1044
-        $order      = $this->request->getRequestParam('PRT_order', 0, DataType::INTEGER);
1045
-        switch ($base_type) {
1046
-            case EEM_Price_Type::base_type_base_price:
1047
-                $is_percent = 0;
1048
-                $order      = 0;
1049
-                break;
1050
-
1051
-            case EEM_Price_Type::base_type_discount:
1052
-            case EEM_Price_Type::base_type_surcharge:
1053
-                break;
1054
-
1055
-            case EEM_Price_Type::base_type_tax:
1056
-                $is_percent = 1;
1057
-                break;
1058
-        }
1059
-
1060
-        return [
1061
-            'PBT_ID'         => $base_type,
1062
-            'PRT_name'       => $this->request->getRequestParam('PRT_name', ''),
1063
-            'PRT_is_percent' => $is_percent,
1064
-            'PRT_order'      => $order,
1065
-            'PRT_deleted'    => 0,
1066
-        ];
1067
-    }
1068
-
1069
-
1070
-    /**
1071
-     * @param bool $new_price_type - whether to insert or update
1072
-     * @return void
1073
-     * @throws EE_Error
1074
-     * @throws ReflectionException
1075
-     */
1076
-    protected function _insert_or_update_price_type(bool $new_price_type = false)
1077
-    {
1078
-        // why be so pessimistic ???  : (
1079
-        $success = 0;
1080
-
1081
-        $set_column_values = $this->set_price_type_column_values();
1082
-        // is this a new Price ?
1083
-        if ($new_price_type) {
1084
-            // run the insert
1085
-            if ($PRT_ID = EEM_Price_Type::instance()->insert($set_column_values)) {
1086
-                $success = 1;
1087
-            }
1088
-            $action_desc = 'created';
1089
-        } else {
1090
-            $PRT_ID = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
1091
-            // run the update
1092
-            $where_cols_n_values = ['PRT_ID' => $PRT_ID];
1093
-            if (EEM_Price_Type::instance()->update($set_column_values, [$where_cols_n_values])) {
1094
-                $success = 1;
1095
-            }
1096
-            $action_desc = 'updated';
1097
-        }
1098
-
1099
-        $query_args = ['action' => 'edit_price_type', 'id' => $PRT_ID];
1100
-        $this->_redirect_after_action($success, 'Price Type', $action_desc, $query_args);
1101
-    }
1102
-
1103
-
1104
-    /**
1105
-     * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
1106
-     * @return void
1107
-     * @throws EE_Error
1108
-     * @throws ReflectionException
1109
-     */
1110
-    protected function _trash_or_restore_price_type(bool $trash = true)
1111
-    {
1112
-        $entity_model = EEM_Price_Type::instance();
1113
-        $action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
1114
-        $success      = $this->trashRestoreDeleteEntities($entity_model, 'id', $action, 'PRT_deleted');
1115
-        if ($success) {
1116
-            $msg = $trash
1117
-                ? esc_html(
1118
-                    _n(
1119
-                        'The Price Type has been trashed',
1120
-                        'The Price Types have been trashed',
1121
-                        $success,
1122
-                        'event_espresso'
1123
-                    )
1124
-                )
1125
-                : esc_html(
1126
-                    _n(
1127
-                        'The Price Type has been restored',
1128
-                        'The Price Types have been restored',
1129
-                        $success,
1130
-                        'event_espresso'
1131
-                    )
1132
-                );
1133
-            EE_Error::add_success($msg);
1134
-        }
1135
-        $this->_redirect_after_action('', '', '', ['action' => 'price_types'], true);
1136
-    }
1137
-
1138
-
1139
-    /**
1140
-     * @return void
1141
-     * @throws EE_Error
1142
-     * @throws ReflectionException
1143
-     */
1144
-    protected function _delete_price_type()
1145
-    {
1146
-        $entity_model = EEM_Price_Type::instance();
1147
-        $deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
1148
-        $this->_redirect_after_action(
1149
-            $deleted,
1150
-            $entity_model->item_name($deleted),
1151
-            'deleted',
1152
-            ['action' => 'price_types']
1153
-        );
1154
-    }
1155
-
1156
-
1157
-    /**
1158
-     * @return string
1159
-     */
1160
-    protected function _learn_more_about_pricing_link(): string
1161
-    {
1162
-        return '
871
+	/**
872
+	 * generates HTML for main Prices Admin page
873
+	 *
874
+	 * @return void
875
+	 * @throws EE_Error
876
+	 */
877
+	protected function _price_types_overview_list_table()
878
+	{
879
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
880
+			'add_new_price_type',
881
+			'add_type',
882
+			[],
883
+			'add-new-h2'
884
+		);
885
+		$this->_admin_page_title .= $this->_learn_more_about_pricing_link();
886
+		$this->_search_btn_label = esc_html__('Price Types', 'event_espresso');
887
+		$this->display_admin_list_table_page_with_sidebar();
888
+	}
889
+
890
+
891
+	/**
892
+	 * retrieve data for Price Types List table
893
+	 *
894
+	 * @param int  $per_page how many prices displayed per page
895
+	 * @param bool $count    return the count or objects
896
+	 * @param bool $trashed  whether the current view is of the trash can - eww yuck!
897
+	 * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
898
+	 * @throws EE_Error
899
+	 * @throws ReflectionException
900
+	 */
901
+	public function get_price_types_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
902
+	{
903
+		// start with an empty array
904
+		require_once(PRICING_ADMIN . 'Price_Types_List_Table.class.php');
905
+
906
+		$orderby = $this->request->getRequestParam('orderby', '');
907
+		$order   = $this->request->getRequestParam('order', 'ASC');
908
+
909
+		switch ($orderby) {
910
+			case 'name':
911
+				$orderby = ['PRT_name' => $order];
912
+				break;
913
+			default:
914
+				$orderby = ['PRT_order' => $order];
915
+		}
916
+
917
+		$current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
918
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
919
+
920
+		$offset = ($current_page - 1) * $per_page;
921
+		$limit  = [$offset, $per_page];
922
+
923
+		$where = ['PRT_deleted' => $trashed, 'PBT_ID' => ['!=', 1]];
924
+
925
+		$search_term = $this->request->getRequestParam('s');
926
+		if ($search_term) {
927
+			$where['OR'] = [
928
+				'PRT_name' => ['LIKE', "%{$search_term}%"],
929
+			];
930
+		}
931
+		$query_params = [
932
+			$where,
933
+			'order_by' => $orderby,
934
+			'limit'    => $limit,
935
+		];
936
+		return $count
937
+			? EEM_Price_Type::instance()->count_deleted_and_undeleted($query_params)
938
+			: EEM_Price_Type::instance()->get_all_deleted_and_undeleted($query_params);
939
+	}
940
+
941
+
942
+	/**
943
+	 * _edit_price_type_details
944
+	 *
945
+	 * @return void
946
+	 * @throws EE_Error
947
+	 * @throws ReflectionException
948
+	 */
949
+	protected function _edit_price_type_details()
950
+	{
951
+		// grab price type ID
952
+		$PRT_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
953
+		// change page title based on request action
954
+		switch ($this->_req_action) {
955
+			case 'add_new_price_type':
956
+				$this->_admin_page_title = esc_html__('Add New Price Type', 'event_espresso');
957
+				break;
958
+			case 'edit_price_type':
959
+				$this->_admin_page_title = esc_html__('Edit Price Type', 'event_espresso');
960
+				break;
961
+			default:
962
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
963
+		}
964
+		// add PRT_ID to title if editing
965
+		$this->_admin_page_title = $PRT_ID ? $this->_admin_page_title . ' # ' . $PRT_ID : $this->_admin_page_title;
966
+
967
+		if ($PRT_ID) {
968
+			$price_type               = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
969
+			$additional_hidden_fields = ['PRT_ID' => ['type' => 'hidden', 'value' => $PRT_ID]];
970
+			$this->_set_add_edit_form_tags('update_price_type', $additional_hidden_fields);
971
+		} else {
972
+			$price_type = EEM_Price_Type::instance()->get_new_price_type();
973
+			$this->_set_add_edit_form_tags('insert_price_type');
974
+		}
975
+
976
+		if (! $price_type instanceof EE_Price_Type) {
977
+			throw new RuntimeException(
978
+				sprintf(
979
+					esc_html__(
980
+						'A valid Price Type could not be retrieved from the database with ID: %1$s',
981
+						'event_espresso'
982
+					),
983
+					$PRT_ID
984
+				)
985
+			);
986
+		}
987
+
988
+		$this->_template_args['PRT_ID']     = $PRT_ID;
989
+		$this->_template_args['price_type'] = $price_type;
990
+
991
+		$base_types    = EEM_Price_Type::instance()->get_base_types();
992
+		$select_values = [];
993
+		foreach ($base_types as $ref => $text) {
994
+			if ($ref == EEM_Price_Type::base_type_base_price) {
995
+				// do not allow creation of base_type_base_prices because that's a system only base type.
996
+				continue;
997
+			}
998
+			$select_values[] = ['id' => $ref, 'text' => $text];
999
+		}
1000
+
1001
+		$this->_template_args['base_type_select'] = EEH_Form_Fields::select_input(
1002
+			'base_type',
1003
+			$select_values,
1004
+			$price_type->base_type(),
1005
+			'id="price-type-base-type-slct"'
1006
+		);
1007
+
1008
+		$this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
1009
+		$this->_template_args['admin_page_content']            = $this->_edit_price_type_details_meta_box();
1010
+
1011
+		$redirect_URL = add_query_arg(['action' => 'price_types'], $this->_admin_base_url);
1012
+		$this->_set_publish_post_box_vars('id', $PRT_ID, false, $redirect_URL);
1013
+		// the details template wrapper
1014
+		$this->display_admin_page_with_sidebar();
1015
+	}
1016
+
1017
+
1018
+	/**
1019
+	 * _edit_price_type_details_meta_box
1020
+	 *
1021
+	 * @return string
1022
+	 */
1023
+	public function _edit_price_type_details_meta_box(): string
1024
+	{
1025
+		return EEH_Template::display_template(
1026
+			PRICING_TEMPLATE_PATH . 'pricing_type_details_main_meta_box.template.php',
1027
+			$this->_template_args,
1028
+			true
1029
+		);
1030
+	}
1031
+
1032
+
1033
+	/**
1034
+	 * @return array
1035
+	 */
1036
+	protected function set_price_type_column_values(): array
1037
+	{
1038
+		$base_type  = $this->request->getRequestParam(
1039
+			'base_type',
1040
+			EEM_Price_Type::base_type_base_price,
1041
+			DataType::INTEGER
1042
+		);
1043
+		$is_percent = $this->request->getRequestParam('PRT_is_percent', 0, DataType::INTEGER);
1044
+		$order      = $this->request->getRequestParam('PRT_order', 0, DataType::INTEGER);
1045
+		switch ($base_type) {
1046
+			case EEM_Price_Type::base_type_base_price:
1047
+				$is_percent = 0;
1048
+				$order      = 0;
1049
+				break;
1050
+
1051
+			case EEM_Price_Type::base_type_discount:
1052
+			case EEM_Price_Type::base_type_surcharge:
1053
+				break;
1054
+
1055
+			case EEM_Price_Type::base_type_tax:
1056
+				$is_percent = 1;
1057
+				break;
1058
+		}
1059
+
1060
+		return [
1061
+			'PBT_ID'         => $base_type,
1062
+			'PRT_name'       => $this->request->getRequestParam('PRT_name', ''),
1063
+			'PRT_is_percent' => $is_percent,
1064
+			'PRT_order'      => $order,
1065
+			'PRT_deleted'    => 0,
1066
+		];
1067
+	}
1068
+
1069
+
1070
+	/**
1071
+	 * @param bool $new_price_type - whether to insert or update
1072
+	 * @return void
1073
+	 * @throws EE_Error
1074
+	 * @throws ReflectionException
1075
+	 */
1076
+	protected function _insert_or_update_price_type(bool $new_price_type = false)
1077
+	{
1078
+		// why be so pessimistic ???  : (
1079
+		$success = 0;
1080
+
1081
+		$set_column_values = $this->set_price_type_column_values();
1082
+		// is this a new Price ?
1083
+		if ($new_price_type) {
1084
+			// run the insert
1085
+			if ($PRT_ID = EEM_Price_Type::instance()->insert($set_column_values)) {
1086
+				$success = 1;
1087
+			}
1088
+			$action_desc = 'created';
1089
+		} else {
1090
+			$PRT_ID = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
1091
+			// run the update
1092
+			$where_cols_n_values = ['PRT_ID' => $PRT_ID];
1093
+			if (EEM_Price_Type::instance()->update($set_column_values, [$where_cols_n_values])) {
1094
+				$success = 1;
1095
+			}
1096
+			$action_desc = 'updated';
1097
+		}
1098
+
1099
+		$query_args = ['action' => 'edit_price_type', 'id' => $PRT_ID];
1100
+		$this->_redirect_after_action($success, 'Price Type', $action_desc, $query_args);
1101
+	}
1102
+
1103
+
1104
+	/**
1105
+	 * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
1106
+	 * @return void
1107
+	 * @throws EE_Error
1108
+	 * @throws ReflectionException
1109
+	 */
1110
+	protected function _trash_or_restore_price_type(bool $trash = true)
1111
+	{
1112
+		$entity_model = EEM_Price_Type::instance();
1113
+		$action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
1114
+		$success      = $this->trashRestoreDeleteEntities($entity_model, 'id', $action, 'PRT_deleted');
1115
+		if ($success) {
1116
+			$msg = $trash
1117
+				? esc_html(
1118
+					_n(
1119
+						'The Price Type has been trashed',
1120
+						'The Price Types have been trashed',
1121
+						$success,
1122
+						'event_espresso'
1123
+					)
1124
+				)
1125
+				: esc_html(
1126
+					_n(
1127
+						'The Price Type has been restored',
1128
+						'The Price Types have been restored',
1129
+						$success,
1130
+						'event_espresso'
1131
+					)
1132
+				);
1133
+			EE_Error::add_success($msg);
1134
+		}
1135
+		$this->_redirect_after_action('', '', '', ['action' => 'price_types'], true);
1136
+	}
1137
+
1138
+
1139
+	/**
1140
+	 * @return void
1141
+	 * @throws EE_Error
1142
+	 * @throws ReflectionException
1143
+	 */
1144
+	protected function _delete_price_type()
1145
+	{
1146
+		$entity_model = EEM_Price_Type::instance();
1147
+		$deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
1148
+		$this->_redirect_after_action(
1149
+			$deleted,
1150
+			$entity_model->item_name($deleted),
1151
+			'deleted',
1152
+			['action' => 'price_types']
1153
+		);
1154
+	}
1155
+
1156
+
1157
+	/**
1158
+	 * @return string
1159
+	 */
1160
+	protected function _learn_more_about_pricing_link(): string
1161
+	{
1162
+		return '
1163 1163
             <a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >
1164 1164
                 ' . esc_html__('learn more about how pricing works', 'event_espresso') . '
1165 1165
             </a>';
1166
-    }
1167
-
1168
-
1169
-    /**
1170
-     * @throws EE_Error
1171
-     */
1172
-    protected function _tax_settings()
1173
-    {
1174
-        $this->_set_add_edit_form_tags('update_tax_settings');
1175
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1176
-        $this->_template_args['admin_page_content'] = $this->tax_settings_form()->get_html();
1177
-        $this->display_admin_page_with_sidebar();
1178
-    }
1179
-
1180
-
1181
-    /**
1182
-     * @return EE_Form_Section_Proper
1183
-     * @throws EE_Error
1184
-     */
1185
-    protected function tax_settings_form(): EE_Form_Section_Proper
1186
-    {
1187
-        $tax_settings = EE_Config::instance()->tax_settings;
1188
-        return new EE_Form_Section_Proper(
1189
-            [
1190
-                'name'            => 'tax_settings_form',
1191
-                'html_id'         => 'tax_settings_form',
1192
-                'html_class'      => 'padding',
1193
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1194
-                'subsections'     => apply_filters(
1195
-                    'FHEE__Pricing_Admin_Page__tax_settings_form__form_subsections',
1196
-                    [
1197
-                        'tax_settings' => new EE_Form_Section_Proper(
1198
-                            [
1199
-                                'name'            => 'tax_settings_tbl',
1200
-                                'html_id'         => 'tax_settings_tbl',
1201
-                                'html_class'      => 'form-table',
1202
-                                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1203
-                                'subsections'     => [
1204
-                                    'prices_displayed_including_taxes' => new EE_Yes_No_Input(
1205
-                                        [
1206
-                                            'html_label_text'         => esc_html__(
1207
-                                                'Show Prices With Taxes Included?',
1208
-                                                'event_espresso'
1209
-                                            ),
1210
-                                            'html_help_text'          => esc_html__(
1211
-                                                'Indicates whether or not to display prices with the taxes included',
1212
-                                                'event_espresso'
1213
-                                            ),
1214
-                                            'default'                 => $tax_settings->prices_displayed_including_taxes
1215
-                                                                         ?? true,
1216
-                                            'display_html_label_text' => false,
1217
-                                        ]
1218
-                                    ),
1219
-                                ],
1220
-                            ]
1221
-                        ),
1222
-                    ]
1223
-                ),
1224
-            ]
1225
-        );
1226
-    }
1227
-
1228
-
1229
-    /**
1230
-     * _update_tax_settings
1231
-     *
1232
-     * @return void
1233
-     * @throws EE_Error
1234
-     * @throws ReflectionException
1235
-     * @since 4.9.13
1236
-     */
1237
-    public function _update_tax_settings()
1238
-    {
1239
-        $tax_settings = EE_Config::instance()->tax_settings;
1240
-        if (! $tax_settings instanceof EE_Tax_Config) {
1241
-            $tax_settings = new EE_Tax_Config();
1242
-        }
1243
-        try {
1244
-            $tax_form = $this->tax_settings_form();
1245
-            // check for form submission
1246
-            if ($tax_form->was_submitted()) {
1247
-                // capture form data
1248
-                $tax_form->receive_form_submission();
1249
-                // validate form data
1250
-                if ($tax_form->is_valid()) {
1251
-                    // grab validated data from form
1252
-                    $valid_data = $tax_form->valid_data();
1253
-                    // set data on config
1254
-                    $tax_settings->prices_displayed_including_taxes =
1255
-                        $valid_data['tax_settings']['prices_displayed_including_taxes'];
1256
-                } else {
1257
-                    if ($tax_form->submission_error_message() !== '') {
1258
-                        EE_Error::add_error(
1259
-                            $tax_form->submission_error_message(),
1260
-                            __FILE__,
1261
-                            __FUNCTION__,
1262
-                            __LINE__
1263
-                        );
1264
-                    }
1265
-                }
1266
-            }
1267
-        } catch (EE_Error $e) {
1268
-            EE_Error::add_error($e->get_error(), __FILE__, __FUNCTION__, __LINE__);
1269
-        }
1270
-
1271
-        $what    = 'Tax Settings';
1272
-        $success = $this->_update_espresso_configuration(
1273
-            $what,
1274
-            $tax_settings,
1275
-            __FILE__,
1276
-            __FUNCTION__,
1277
-            __LINE__
1278
-        );
1279
-        $this->_redirect_after_action($success, $what, 'updated', ['action' => 'tax_settings']);
1280
-    }
1166
+	}
1167
+
1168
+
1169
+	/**
1170
+	 * @throws EE_Error
1171
+	 */
1172
+	protected function _tax_settings()
1173
+	{
1174
+		$this->_set_add_edit_form_tags('update_tax_settings');
1175
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1176
+		$this->_template_args['admin_page_content'] = $this->tax_settings_form()->get_html();
1177
+		$this->display_admin_page_with_sidebar();
1178
+	}
1179
+
1180
+
1181
+	/**
1182
+	 * @return EE_Form_Section_Proper
1183
+	 * @throws EE_Error
1184
+	 */
1185
+	protected function tax_settings_form(): EE_Form_Section_Proper
1186
+	{
1187
+		$tax_settings = EE_Config::instance()->tax_settings;
1188
+		return new EE_Form_Section_Proper(
1189
+			[
1190
+				'name'            => 'tax_settings_form',
1191
+				'html_id'         => 'tax_settings_form',
1192
+				'html_class'      => 'padding',
1193
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1194
+				'subsections'     => apply_filters(
1195
+					'FHEE__Pricing_Admin_Page__tax_settings_form__form_subsections',
1196
+					[
1197
+						'tax_settings' => new EE_Form_Section_Proper(
1198
+							[
1199
+								'name'            => 'tax_settings_tbl',
1200
+								'html_id'         => 'tax_settings_tbl',
1201
+								'html_class'      => 'form-table',
1202
+								'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1203
+								'subsections'     => [
1204
+									'prices_displayed_including_taxes' => new EE_Yes_No_Input(
1205
+										[
1206
+											'html_label_text'         => esc_html__(
1207
+												'Show Prices With Taxes Included?',
1208
+												'event_espresso'
1209
+											),
1210
+											'html_help_text'          => esc_html__(
1211
+												'Indicates whether or not to display prices with the taxes included',
1212
+												'event_espresso'
1213
+											),
1214
+											'default'                 => $tax_settings->prices_displayed_including_taxes
1215
+																		 ?? true,
1216
+											'display_html_label_text' => false,
1217
+										]
1218
+									),
1219
+								],
1220
+							]
1221
+						),
1222
+					]
1223
+				),
1224
+			]
1225
+		);
1226
+	}
1227
+
1228
+
1229
+	/**
1230
+	 * _update_tax_settings
1231
+	 *
1232
+	 * @return void
1233
+	 * @throws EE_Error
1234
+	 * @throws ReflectionException
1235
+	 * @since 4.9.13
1236
+	 */
1237
+	public function _update_tax_settings()
1238
+	{
1239
+		$tax_settings = EE_Config::instance()->tax_settings;
1240
+		if (! $tax_settings instanceof EE_Tax_Config) {
1241
+			$tax_settings = new EE_Tax_Config();
1242
+		}
1243
+		try {
1244
+			$tax_form = $this->tax_settings_form();
1245
+			// check for form submission
1246
+			if ($tax_form->was_submitted()) {
1247
+				// capture form data
1248
+				$tax_form->receive_form_submission();
1249
+				// validate form data
1250
+				if ($tax_form->is_valid()) {
1251
+					// grab validated data from form
1252
+					$valid_data = $tax_form->valid_data();
1253
+					// set data on config
1254
+					$tax_settings->prices_displayed_including_taxes =
1255
+						$valid_data['tax_settings']['prices_displayed_including_taxes'];
1256
+				} else {
1257
+					if ($tax_form->submission_error_message() !== '') {
1258
+						EE_Error::add_error(
1259
+							$tax_form->submission_error_message(),
1260
+							__FILE__,
1261
+							__FUNCTION__,
1262
+							__LINE__
1263
+						);
1264
+					}
1265
+				}
1266
+			}
1267
+		} catch (EE_Error $e) {
1268
+			EE_Error::add_error($e->get_error(), __FILE__, __FUNCTION__, __LINE__);
1269
+		}
1270
+
1271
+		$what    = 'Tax Settings';
1272
+		$success = $this->_update_espresso_configuration(
1273
+			$what,
1274
+			$tax_settings,
1275
+			__FILE__,
1276
+			__FUNCTION__,
1277
+			__LINE__
1278
+		);
1279
+		$this->_redirect_after_action($success, $what, 'updated', ['action' => 'tax_settings']);
1280
+	}
1281 1281
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_List_Table.core.php 1 patch
Indentation   +878 added lines, -878 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 if (! class_exists('WP_List_Table')) {
4
-    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
4
+	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
5 5
 }
6 6
 
7 7
 
@@ -19,891 +19,891 @@  discard block
 block discarded – undo
19 19
  */
20 20
 abstract class EE_Admin_List_Table extends WP_List_Table
21 21
 {
22
-    const ACTION_COPY    = 'duplicate';
23
-
24
-    const ACTION_DELETE  = 'delete';
25
-
26
-    const ACTION_EDIT    = 'edit';
27
-
28
-    const ACTION_RESTORE = 'restore';
29
-
30
-    const ACTION_TRASH   = 'trash';
31
-
32
-    protected static $actions = [
33
-        self::ACTION_COPY,
34
-        self::ACTION_DELETE,
35
-        self::ACTION_EDIT,
36
-        self::ACTION_RESTORE,
37
-        self::ACTION_TRASH,
38
-    ];
39
-
40
-    /**
41
-     * holds the data that will be processed for the table
42
-     *
43
-     * @var array $_data
44
-     */
45
-    protected $_data;
46
-
47
-
48
-    /**
49
-     * This holds the value of all the data available for the given view (for all pages).
50
-     *
51
-     * @var int $_all_data_count
52
-     */
53
-    protected $_all_data_count;
54
-
55
-
56
-    /**
57
-     * Will contain the count of trashed items for the view label.
58
-     *
59
-     * @var int $_trashed_count
60
-     */
61
-    protected $_trashed_count;
62
-
63
-
64
-    /**
65
-     * This is what will be referenced as the slug for the current screen
66
-     *
67
-     * @var string $_screen
68
-     */
69
-    protected $_screen;
70
-
71
-
72
-    /**
73
-     * this is the EE_Admin_Page object
74
-     *
75
-     * @var EE_Admin_Page $_admin_page
76
-     */
77
-    protected $_admin_page;
78
-
79
-
80
-    /**
81
-     * The current view
82
-     *
83
-     * @var string $_view
84
-     */
85
-    protected $_view;
86
-
87
-
88
-    /**
89
-     * array of possible views for this table
90
-     *
91
-     * @var array $_views
92
-     */
93
-    protected $_views;
94
-
95
-
96
-    /**
97
-     * An array of key => value pairs containing information about the current table
98
-     * array(
99
-     *        'plural' => 'plural label',
100
-     *        'singular' => 'singular label',
101
-     *        'ajax' => false, //whether to use ajax or not
102
-     *        'screen' => null, //string used to reference what screen this is
103
-     *        (WP_List_table converts to screen object)
104
-     * )
105
-     *
106
-     * @var array $_wp_list_args
107
-     */
108
-    protected $_wp_list_args;
109
-
110
-    /**
111
-     * an array of column names
112
-     * array(
113
-     *    'internal-name' => 'Title'
114
-     * )
115
-     *
116
-     * @var array $_columns
117
-     */
118
-    protected $_columns;
119
-
120
-    /**
121
-     * An array of sortable columns
122
-     * array(
123
-     *    'internal-name' => 'orderby' //or
124
-     *    'internal-name' => array( 'orderby', true )
125
-     * )
126
-     *
127
-     * @var array $_sortable_columns
128
-     */
129
-    protected $_sortable_columns;
130
-
131
-    /**
132
-     * callback method used to perform AJAX row reordering
133
-     *
134
-     * @var string $_ajax_sorting_callback
135
-     */
136
-    protected $_ajax_sorting_callback;
137
-
138
-    /**
139
-     * An array of hidden columns (if needed)
140
-     * array('internal-name', 'internal-name')
141
-     *
142
-     * @var array $_hidden_columns
143
-     */
144
-    protected $_hidden_columns;
145
-
146
-    /**
147
-     * holds the per_page value
148
-     *
149
-     * @var int $_per_page
150
-     */
151
-    protected $_per_page;
152
-
153
-    /**
154
-     * holds what page number is currently being viewed
155
-     *
156
-     * @var int $_current_page
157
-     */
158
-    protected $_current_page;
159
-
160
-    /**
161
-     * the reference string for the nonce_action
162
-     *
163
-     * @var string $_nonce_action_ref
164
-     */
165
-    protected $_nonce_action_ref;
166
-
167
-    /**
168
-     * property to hold incoming request data (as set by the admin_page_core)
169
-     *
170
-     * @var array $_req_data
171
-     */
172
-    protected $_req_data;
173
-
174
-
175
-    /**
176
-     * yes / no array for admin form fields
177
-     *
178
-     * @var array $_yes_no
179
-     */
180
-    protected $_yes_no = [];
181
-
182
-    /**
183
-     * Array describing buttons that should appear at the bottom of the page
184
-     * Keys are strings that represent the button's function (specifically a key in _labels['buttons']),
185
-     * and the values are another array with the following keys
186
-     * array(
187
-     *    'route' => 'page_route',
188
-     *    'extra_request' => array('evt_id' => 1 ); //extra request vars that need to be included in the button.
189
-     * )
190
-     *
191
-     * @var array $_bottom_buttons
192
-     */
193
-    protected $_bottom_buttons = [];
194
-
195
-
196
-    /**
197
-     * Used to indicate what should be the primary column for the list table.
198
-     * If not present then falls back to what WP calculates
199
-     * as the primary column.
200
-     *
201
-     * @type string $_primary_column
202
-     */
203
-    protected $_primary_column = '';
204
-
205
-
206
-    /**
207
-     * Used to indicate whether the table has a checkbox column or not.
208
-     *
209
-     * @type bool $_has_checkbox_column
210
-     */
211
-    protected $_has_checkbox_column = false;
212
-
213
-
214
-    /**
215
-     * @param EE_Admin_Page $admin_page we use this for obtaining everything we need in the list table
216
-     */
217
-    public function __construct(EE_Admin_Page $admin_page)
218
-    {
219
-        $this->_admin_page   = $admin_page;
220
-        $this->_req_data     = $this->_admin_page->get_request_data();
221
-        $this->_view         = $this->_admin_page->get_view();
222
-        $this->_views        = empty($this->_views) ? $this->_admin_page->get_list_table_view_RLs() : $this->_views;
223
-        $this->_current_page = $this->get_pagenum();
224
-        $this->_screen       = $this->_admin_page->get_current_page() . '_' . $this->_admin_page->get_current_view();
225
-        $this->_yes_no       = [
226
-            esc_html__('No', 'event_espresso'),
227
-            esc_html__('Yes', 'event_espresso')
228
-        ];
229
-
230
-        $this->_per_page = $this->get_items_per_page($this->_screen . '_per_page');
231
-
232
-        $this->_setup_data();
233
-        $this->_add_view_counts();
234
-
235
-        $this->_nonce_action_ref = $this->_view;
236
-
237
-        $this->_set_properties();
238
-
239
-        // set primary column
240
-        add_filter('list_table_primary_column', [$this, 'set_primary_column']);
241
-
242
-        // set parent defaults
243
-        parent::__construct($this->_wp_list_args);
244
-
245
-        $this->prepare_items();
246
-    }
247
-
248
-
249
-    /**
250
-     * _setup_data
251
-     * this method is used to setup the $_data, $_all_data_count, and _per_page properties
252
-     *
253
-     * @return void
254
-     * @uses $this->_admin_page
255
-     */
256
-    abstract protected function _setup_data();
257
-
258
-
259
-    /**
260
-     * set the properties that this class needs to be able to execute wp_list_table properly
261
-     * properties set:
262
-     * _wp_list_args = what the arguments required for the parent _wp_list_table.
263
-     * _columns = set the columns in an array.
264
-     * _sortable_columns = columns that are sortable (array).
265
-     * _hidden_columns = columns that are hidden (array)
266
-     * _default_orderby = the default orderby for sorting.
267
-     *
268
-     * @abstract
269
-     * @access protected
270
-     * @return void
271
-     */
272
-    abstract protected function _set_properties();
273
-
274
-
275
-    /**
276
-     * _get_table_filters
277
-     * We use this to assemble and return any filters that are associated with this table that help further refine what
278
-     * gets shown in the table.
279
-     *
280
-     * @abstract
281
-     * @access protected
282
-     * @return string
283
-     */
284
-    abstract protected function _get_table_filters();
285
-
286
-
287
-    /**
288
-     * this is a method that child class will do to add counts to the views array so when views are displayed the
289
-     * counts of the views is accurate.
290
-     *
291
-     * @abstract
292
-     * @access protected
293
-     * @return void
294
-     */
295
-    abstract protected function _add_view_counts();
296
-
297
-
298
-    /**
299
-     * _get_hidden_fields
300
-     * returns a html string of hidden fields so if any table filters are used the current view will be respected.
301
-     *
302
-     * @return string
303
-     */
304
-    protected function _get_hidden_fields()
305
-    {
306
-        $action = isset($this->_req_data['route']) ? $this->_req_data['route'] : '';
307
-        $action = empty($action) && isset($this->_req_data['action']) ? $this->_req_data['action'] : $action;
308
-        // if action is STILL empty, then we set it to default
309
-        $action = empty($action) ? 'default' : $action;
310
-        $field  = '<input type="hidden" name="page" value="' . esc_attr($this->_req_data['page']) . '" />' . "\n";
311
-        $field  .= '<input type="hidden" name="route" value="' . esc_attr($action) . '" />' . "\n";
312
-        $field  .= '<input type="hidden" name="perpage" value="' . esc_attr($this->_per_page) . '" />' . "\n";
313
-
314
-        $bulk_actions = $this->_get_bulk_actions();
315
-        foreach ($bulk_actions as $bulk_action => $label) {
316
-            $field .= '<input type="hidden" name="' . $bulk_action . '_nonce"'
317
-                      . ' value="' . wp_create_nonce($bulk_action . '_nonce') . '" />' . "\n";
318
-        }
319
-
320
-        return $field;
321
-    }
322
-
323
-
324
-    /**
325
-     * _set_column_info
326
-     * we're using this to set the column headers property.
327
-     *
328
-     * @access protected
329
-     * @return void
330
-     */
331
-    protected function _set_column_info()
332
-    {
333
-        $columns   = $this->get_columns();
334
-        $hidden    = $this->get_hidden_columns();
335
-        $_sortable = $this->get_sortable_columns();
336
-
337
-        /**
338
-         * Dynamic hook allowing for adding sortable columns in this list table.
339
-         * Note that $this->screen->id is in the format
340
-         * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
341
-         * table it is: event-espresso_page_espresso_messages.
342
-         * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
343
-         * hook prefix ("event-espresso") will be different.
344
-         *
345
-         * @var array
346
-         */
347
-        $_sortable = apply_filters("FHEE_manage_{$this->screen->id}_sortable_columns", $_sortable, $this->_screen);
348
-
349
-        $sortable = [];
350
-        foreach ($_sortable as $id => $data) {
351
-            if (empty($data)) {
352
-                continue;
353
-            }
354
-            // fix for offset errors with WP_List_Table default get_columninfo()
355
-            if (is_array($data)) {
356
-                $_data[0] = key($data);
357
-                $_data[1] = isset($data[1]) ? $data[1] : false;
358
-            } else {
359
-                $_data[0] = $data;
360
-            }
361
-
362
-            $data = (array) $data;
363
-
364
-            if (! isset($data[1])) {
365
-                $_data[1] = false;
366
-            }
367
-
368
-            $sortable[ $id ] = $_data;
369
-        }
370
-        $primary               = $this->get_primary_column_name();
371
-        $this->_column_headers = [$columns, $hidden, $sortable, $primary];
372
-    }
373
-
374
-
375
-    /**
376
-     * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
377
-     *
378
-     * @return string
379
-     */
380
-    protected function get_primary_column_name()
381
-    {
382
-        foreach (class_parents($this) as $parent) {
383
-            if ($parent === 'WP_List_Table' && method_exists($parent, 'get_primary_column_name')) {
384
-                return parent::get_primary_column_name();
385
-            }
386
-        }
387
-        return $this->_primary_column;
388
-    }
389
-
390
-
391
-    /**
392
-     * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
393
-     *
394
-     * @param EE_Base_Class $item
395
-     * @param string        $column_name
396
-     * @param string        $primary
397
-     * @return string
398
-     */
399
-    protected function handle_row_actions($item, $column_name, $primary)
400
-    {
401
-        foreach (class_parents($this) as $parent) {
402
-            if ($parent === 'WP_List_Table' && method_exists($parent, 'handle_row_actions')) {
403
-                return parent::handle_row_actions($item, $column_name, $primary);
404
-            }
405
-        }
406
-        return '';
407
-    }
408
-
409
-
410
-    /**
411
-     * _get_bulk_actions
412
-     * This is a wrapper called by WP_List_Table::get_bulk_actions()
413
-     *
414
-     * @access protected
415
-     * @return array bulk_actions
416
-     */
417
-    protected function _get_bulk_actions()
418
-    {
419
-        $actions = [];
420
-        // the _views property should have the bulk_actions, so let's go through and extract them into a properly
421
-        // formatted array for the wp_list_table();
422
-        foreach ($this->_views as $view => $args) {
423
-            if ($this->_view === $view && isset($args['bulk_action']) && is_array($args['bulk_action'])) {
424
-                // each bulk action will correspond with a admin page route, so we can check whatever the capability is
425
-                // for that page route and skip adding the bulk action if no access for the current logged in user.
426
-                foreach ($args['bulk_action'] as $route => $label) {
427
-                    if ($this->_admin_page->check_user_access($route, true)) {
428
-                        $actions[ $route ] = $label;
429
-                    }
430
-                }
431
-            }
432
-        }
433
-        return $actions;
434
-    }
435
-
436
-
437
-    /**
438
-     * Generate the table navigation above or below the table.
439
-     * Overrides the parent table nav in WP_List_Table so we can hide the bulk action div if there are no bulk actions.
440
-     *
441
-     * @throws EE_Error
442
-     * @since 4.9.44.rc.001
443
-     */
444
-    public function display_tablenav($which)
445
-    {
446
-        if ('top' === $which) {
447
-            wp_nonce_field('bulk-' . $this->_args['plural']);
448
-        }
449
-        ?>
22
+	const ACTION_COPY    = 'duplicate';
23
+
24
+	const ACTION_DELETE  = 'delete';
25
+
26
+	const ACTION_EDIT    = 'edit';
27
+
28
+	const ACTION_RESTORE = 'restore';
29
+
30
+	const ACTION_TRASH   = 'trash';
31
+
32
+	protected static $actions = [
33
+		self::ACTION_COPY,
34
+		self::ACTION_DELETE,
35
+		self::ACTION_EDIT,
36
+		self::ACTION_RESTORE,
37
+		self::ACTION_TRASH,
38
+	];
39
+
40
+	/**
41
+	 * holds the data that will be processed for the table
42
+	 *
43
+	 * @var array $_data
44
+	 */
45
+	protected $_data;
46
+
47
+
48
+	/**
49
+	 * This holds the value of all the data available for the given view (for all pages).
50
+	 *
51
+	 * @var int $_all_data_count
52
+	 */
53
+	protected $_all_data_count;
54
+
55
+
56
+	/**
57
+	 * Will contain the count of trashed items for the view label.
58
+	 *
59
+	 * @var int $_trashed_count
60
+	 */
61
+	protected $_trashed_count;
62
+
63
+
64
+	/**
65
+	 * This is what will be referenced as the slug for the current screen
66
+	 *
67
+	 * @var string $_screen
68
+	 */
69
+	protected $_screen;
70
+
71
+
72
+	/**
73
+	 * this is the EE_Admin_Page object
74
+	 *
75
+	 * @var EE_Admin_Page $_admin_page
76
+	 */
77
+	protected $_admin_page;
78
+
79
+
80
+	/**
81
+	 * The current view
82
+	 *
83
+	 * @var string $_view
84
+	 */
85
+	protected $_view;
86
+
87
+
88
+	/**
89
+	 * array of possible views for this table
90
+	 *
91
+	 * @var array $_views
92
+	 */
93
+	protected $_views;
94
+
95
+
96
+	/**
97
+	 * An array of key => value pairs containing information about the current table
98
+	 * array(
99
+	 *        'plural' => 'plural label',
100
+	 *        'singular' => 'singular label',
101
+	 *        'ajax' => false, //whether to use ajax or not
102
+	 *        'screen' => null, //string used to reference what screen this is
103
+	 *        (WP_List_table converts to screen object)
104
+	 * )
105
+	 *
106
+	 * @var array $_wp_list_args
107
+	 */
108
+	protected $_wp_list_args;
109
+
110
+	/**
111
+	 * an array of column names
112
+	 * array(
113
+	 *    'internal-name' => 'Title'
114
+	 * )
115
+	 *
116
+	 * @var array $_columns
117
+	 */
118
+	protected $_columns;
119
+
120
+	/**
121
+	 * An array of sortable columns
122
+	 * array(
123
+	 *    'internal-name' => 'orderby' //or
124
+	 *    'internal-name' => array( 'orderby', true )
125
+	 * )
126
+	 *
127
+	 * @var array $_sortable_columns
128
+	 */
129
+	protected $_sortable_columns;
130
+
131
+	/**
132
+	 * callback method used to perform AJAX row reordering
133
+	 *
134
+	 * @var string $_ajax_sorting_callback
135
+	 */
136
+	protected $_ajax_sorting_callback;
137
+
138
+	/**
139
+	 * An array of hidden columns (if needed)
140
+	 * array('internal-name', 'internal-name')
141
+	 *
142
+	 * @var array $_hidden_columns
143
+	 */
144
+	protected $_hidden_columns;
145
+
146
+	/**
147
+	 * holds the per_page value
148
+	 *
149
+	 * @var int $_per_page
150
+	 */
151
+	protected $_per_page;
152
+
153
+	/**
154
+	 * holds what page number is currently being viewed
155
+	 *
156
+	 * @var int $_current_page
157
+	 */
158
+	protected $_current_page;
159
+
160
+	/**
161
+	 * the reference string for the nonce_action
162
+	 *
163
+	 * @var string $_nonce_action_ref
164
+	 */
165
+	protected $_nonce_action_ref;
166
+
167
+	/**
168
+	 * property to hold incoming request data (as set by the admin_page_core)
169
+	 *
170
+	 * @var array $_req_data
171
+	 */
172
+	protected $_req_data;
173
+
174
+
175
+	/**
176
+	 * yes / no array for admin form fields
177
+	 *
178
+	 * @var array $_yes_no
179
+	 */
180
+	protected $_yes_no = [];
181
+
182
+	/**
183
+	 * Array describing buttons that should appear at the bottom of the page
184
+	 * Keys are strings that represent the button's function (specifically a key in _labels['buttons']),
185
+	 * and the values are another array with the following keys
186
+	 * array(
187
+	 *    'route' => 'page_route',
188
+	 *    'extra_request' => array('evt_id' => 1 ); //extra request vars that need to be included in the button.
189
+	 * )
190
+	 *
191
+	 * @var array $_bottom_buttons
192
+	 */
193
+	protected $_bottom_buttons = [];
194
+
195
+
196
+	/**
197
+	 * Used to indicate what should be the primary column for the list table.
198
+	 * If not present then falls back to what WP calculates
199
+	 * as the primary column.
200
+	 *
201
+	 * @type string $_primary_column
202
+	 */
203
+	protected $_primary_column = '';
204
+
205
+
206
+	/**
207
+	 * Used to indicate whether the table has a checkbox column or not.
208
+	 *
209
+	 * @type bool $_has_checkbox_column
210
+	 */
211
+	protected $_has_checkbox_column = false;
212
+
213
+
214
+	/**
215
+	 * @param EE_Admin_Page $admin_page we use this for obtaining everything we need in the list table
216
+	 */
217
+	public function __construct(EE_Admin_Page $admin_page)
218
+	{
219
+		$this->_admin_page   = $admin_page;
220
+		$this->_req_data     = $this->_admin_page->get_request_data();
221
+		$this->_view         = $this->_admin_page->get_view();
222
+		$this->_views        = empty($this->_views) ? $this->_admin_page->get_list_table_view_RLs() : $this->_views;
223
+		$this->_current_page = $this->get_pagenum();
224
+		$this->_screen       = $this->_admin_page->get_current_page() . '_' . $this->_admin_page->get_current_view();
225
+		$this->_yes_no       = [
226
+			esc_html__('No', 'event_espresso'),
227
+			esc_html__('Yes', 'event_espresso')
228
+		];
229
+
230
+		$this->_per_page = $this->get_items_per_page($this->_screen . '_per_page');
231
+
232
+		$this->_setup_data();
233
+		$this->_add_view_counts();
234
+
235
+		$this->_nonce_action_ref = $this->_view;
236
+
237
+		$this->_set_properties();
238
+
239
+		// set primary column
240
+		add_filter('list_table_primary_column', [$this, 'set_primary_column']);
241
+
242
+		// set parent defaults
243
+		parent::__construct($this->_wp_list_args);
244
+
245
+		$this->prepare_items();
246
+	}
247
+
248
+
249
+	/**
250
+	 * _setup_data
251
+	 * this method is used to setup the $_data, $_all_data_count, and _per_page properties
252
+	 *
253
+	 * @return void
254
+	 * @uses $this->_admin_page
255
+	 */
256
+	abstract protected function _setup_data();
257
+
258
+
259
+	/**
260
+	 * set the properties that this class needs to be able to execute wp_list_table properly
261
+	 * properties set:
262
+	 * _wp_list_args = what the arguments required for the parent _wp_list_table.
263
+	 * _columns = set the columns in an array.
264
+	 * _sortable_columns = columns that are sortable (array).
265
+	 * _hidden_columns = columns that are hidden (array)
266
+	 * _default_orderby = the default orderby for sorting.
267
+	 *
268
+	 * @abstract
269
+	 * @access protected
270
+	 * @return void
271
+	 */
272
+	abstract protected function _set_properties();
273
+
274
+
275
+	/**
276
+	 * _get_table_filters
277
+	 * We use this to assemble and return any filters that are associated with this table that help further refine what
278
+	 * gets shown in the table.
279
+	 *
280
+	 * @abstract
281
+	 * @access protected
282
+	 * @return string
283
+	 */
284
+	abstract protected function _get_table_filters();
285
+
286
+
287
+	/**
288
+	 * this is a method that child class will do to add counts to the views array so when views are displayed the
289
+	 * counts of the views is accurate.
290
+	 *
291
+	 * @abstract
292
+	 * @access protected
293
+	 * @return void
294
+	 */
295
+	abstract protected function _add_view_counts();
296
+
297
+
298
+	/**
299
+	 * _get_hidden_fields
300
+	 * returns a html string of hidden fields so if any table filters are used the current view will be respected.
301
+	 *
302
+	 * @return string
303
+	 */
304
+	protected function _get_hidden_fields()
305
+	{
306
+		$action = isset($this->_req_data['route']) ? $this->_req_data['route'] : '';
307
+		$action = empty($action) && isset($this->_req_data['action']) ? $this->_req_data['action'] : $action;
308
+		// if action is STILL empty, then we set it to default
309
+		$action = empty($action) ? 'default' : $action;
310
+		$field  = '<input type="hidden" name="page" value="' . esc_attr($this->_req_data['page']) . '" />' . "\n";
311
+		$field  .= '<input type="hidden" name="route" value="' . esc_attr($action) . '" />' . "\n";
312
+		$field  .= '<input type="hidden" name="perpage" value="' . esc_attr($this->_per_page) . '" />' . "\n";
313
+
314
+		$bulk_actions = $this->_get_bulk_actions();
315
+		foreach ($bulk_actions as $bulk_action => $label) {
316
+			$field .= '<input type="hidden" name="' . $bulk_action . '_nonce"'
317
+					  . ' value="' . wp_create_nonce($bulk_action . '_nonce') . '" />' . "\n";
318
+		}
319
+
320
+		return $field;
321
+	}
322
+
323
+
324
+	/**
325
+	 * _set_column_info
326
+	 * we're using this to set the column headers property.
327
+	 *
328
+	 * @access protected
329
+	 * @return void
330
+	 */
331
+	protected function _set_column_info()
332
+	{
333
+		$columns   = $this->get_columns();
334
+		$hidden    = $this->get_hidden_columns();
335
+		$_sortable = $this->get_sortable_columns();
336
+
337
+		/**
338
+		 * Dynamic hook allowing for adding sortable columns in this list table.
339
+		 * Note that $this->screen->id is in the format
340
+		 * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
341
+		 * table it is: event-espresso_page_espresso_messages.
342
+		 * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
343
+		 * hook prefix ("event-espresso") will be different.
344
+		 *
345
+		 * @var array
346
+		 */
347
+		$_sortable = apply_filters("FHEE_manage_{$this->screen->id}_sortable_columns", $_sortable, $this->_screen);
348
+
349
+		$sortable = [];
350
+		foreach ($_sortable as $id => $data) {
351
+			if (empty($data)) {
352
+				continue;
353
+			}
354
+			// fix for offset errors with WP_List_Table default get_columninfo()
355
+			if (is_array($data)) {
356
+				$_data[0] = key($data);
357
+				$_data[1] = isset($data[1]) ? $data[1] : false;
358
+			} else {
359
+				$_data[0] = $data;
360
+			}
361
+
362
+			$data = (array) $data;
363
+
364
+			if (! isset($data[1])) {
365
+				$_data[1] = false;
366
+			}
367
+
368
+			$sortable[ $id ] = $_data;
369
+		}
370
+		$primary               = $this->get_primary_column_name();
371
+		$this->_column_headers = [$columns, $hidden, $sortable, $primary];
372
+	}
373
+
374
+
375
+	/**
376
+	 * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
377
+	 *
378
+	 * @return string
379
+	 */
380
+	protected function get_primary_column_name()
381
+	{
382
+		foreach (class_parents($this) as $parent) {
383
+			if ($parent === 'WP_List_Table' && method_exists($parent, 'get_primary_column_name')) {
384
+				return parent::get_primary_column_name();
385
+			}
386
+		}
387
+		return $this->_primary_column;
388
+	}
389
+
390
+
391
+	/**
392
+	 * Added for WP4.1 backward compat (@see https://events.codebasehq.com/projects/event-espresso/tickets/8814)
393
+	 *
394
+	 * @param EE_Base_Class $item
395
+	 * @param string        $column_name
396
+	 * @param string        $primary
397
+	 * @return string
398
+	 */
399
+	protected function handle_row_actions($item, $column_name, $primary)
400
+	{
401
+		foreach (class_parents($this) as $parent) {
402
+			if ($parent === 'WP_List_Table' && method_exists($parent, 'handle_row_actions')) {
403
+				return parent::handle_row_actions($item, $column_name, $primary);
404
+			}
405
+		}
406
+		return '';
407
+	}
408
+
409
+
410
+	/**
411
+	 * _get_bulk_actions
412
+	 * This is a wrapper called by WP_List_Table::get_bulk_actions()
413
+	 *
414
+	 * @access protected
415
+	 * @return array bulk_actions
416
+	 */
417
+	protected function _get_bulk_actions()
418
+	{
419
+		$actions = [];
420
+		// the _views property should have the bulk_actions, so let's go through and extract them into a properly
421
+		// formatted array for the wp_list_table();
422
+		foreach ($this->_views as $view => $args) {
423
+			if ($this->_view === $view && isset($args['bulk_action']) && is_array($args['bulk_action'])) {
424
+				// each bulk action will correspond with a admin page route, so we can check whatever the capability is
425
+				// for that page route and skip adding the bulk action if no access for the current logged in user.
426
+				foreach ($args['bulk_action'] as $route => $label) {
427
+					if ($this->_admin_page->check_user_access($route, true)) {
428
+						$actions[ $route ] = $label;
429
+					}
430
+				}
431
+			}
432
+		}
433
+		return $actions;
434
+	}
435
+
436
+
437
+	/**
438
+	 * Generate the table navigation above or below the table.
439
+	 * Overrides the parent table nav in WP_List_Table so we can hide the bulk action div if there are no bulk actions.
440
+	 *
441
+	 * @throws EE_Error
442
+	 * @since 4.9.44.rc.001
443
+	 */
444
+	public function display_tablenav($which)
445
+	{
446
+		if ('top' === $which) {
447
+			wp_nonce_field('bulk-' . $this->_args['plural']);
448
+		}
449
+		?>
450 450
         <div class="tablenav <?php echo esc_attr($which); ?>">
451 451
             <?php if ($this->_get_bulk_actions()) { ?>
452 452
                 <div class="alignleft actions bulkactions">
453 453
                     <?php $this->bulk_actions(); ?>
454 454
                 </div>
455 455
             <?php }
456
-            $this->extra_tablenav($which);
457
-            $this->pagination($which);
458
-            ?>
456
+			$this->extra_tablenav($which);
457
+			$this->pagination($which);
458
+			?>
459 459
 
460 460
             <br class="clear" />
461 461
         </div>
462 462
         <?php
463
-    }
464
-
465
-
466
-    /**
467
-     * _filters
468
-     * This receives the filters array from children _get_table_filters() and assembles the string including the filter
469
-     * button.
470
-     *
471
-     * @access private
472
-     * @return void  echos html showing filters
473
-     */
474
-    private function _filters()
475
-    {
476
-        $classname = get_class($this);
477
-        $filters   = apply_filters(
478
-            "FHEE__{$classname}__filters",
479
-            (array) $this->_get_table_filters(),
480
-            $this,
481
-            $this->_screen
482
-        );
483
-
484
-        if (empty($filters)) {
485
-            return;
486
-        }
487
-        foreach ($filters as $filter) {
488
-            echo $filter; // already escaped
489
-        }
490
-        // add filter button at end
491
-        echo '<input type="submit" class="button-secondary" value="'
492
-             . esc_html__('Filter', 'event_espresso')
493
-             . '" id="post-query-submit" />';
494
-        // add reset filters button at end
495
-        echo '<a class="button button-secondary"  href="'
496
-             . esc_url_raw($this->_admin_page->get_current_page_view_url())
497
-             . '" style="display:inline-block">'
498
-             . esc_html__('Reset Filters', 'event_espresso')
499
-             . '</a>';
500
-    }
501
-
502
-
503
-    /**
504
-     * Callback for 'list_table_primary_column' WordPress filter
505
-     * If child EE_Admin_List_Table classes set the _primary_column property then that will be set as the primary
506
-     * column when class is instantiated.
507
-     *
508
-     * @param string $column_name
509
-     * @return string
510
-     * @see WP_List_Table::get_primary_column_name
511
-     */
512
-    public function set_primary_column($column_name)
513
-    {
514
-        return ! empty($this->_primary_column) ? $this->_primary_column : $column_name;
515
-    }
516
-
517
-
518
-    /**
519
-     *
520
-     */
521
-    public function prepare_items()
522
-    {
523
-
524
-        $this->_set_column_info();
525
-        // $this->_column_headers = $this->get_column_info();
526
-        $total_items = $this->_all_data_count;
527
-        $this->process_bulk_action();
528
-
529
-        $this->items = $this->_data;
530
-        $this->set_pagination_args(
531
-            [
532
-                'total_items' => $total_items,
533
-                'per_page'    => $this->_per_page,
534
-                'total_pages' => ceil($total_items / $this->_per_page),
535
-            ]
536
-        );
537
-    }
538
-
539
-
540
-    /**
541
-     * @param object|array $item
542
-     * @return string html content for the column
543
-     */
544
-    protected function column_cb($item)
545
-    {
546
-        return '';
547
-    }
548
-
549
-
550
-    /**
551
-     * This column is the default for when there is no defined column method for a registered column.
552
-     * This can be overridden by child classes, but allows for hooking in for custom columns.
553
-     *
554
-     * @param EE_Base_Class $item
555
-     * @param string        $column_name The column being called.
556
-     * @return string html content for the column
557
-     */
558
-    public function column_default($item, $column_name)
559
-    {
560
-        /**
561
-         * Dynamic hook allowing for adding additional column content in this list table.
562
-         * Note that $this->screen->id is in the format
563
-         * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
564
-         * table it is: event-espresso_page_espresso_messages.
565
-         * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
566
-         * hook prefix ("event-espresso") will be different.
567
-         */
568
-        ob_start();
569
-        do_action(
570
-            'AHEE__EE_Admin_List_Table__column_' . $column_name . '__' . $this->screen->id,
571
-            $item,
572
-            $this->_screen
573
-        );
574
-        return ob_get_clean();
575
-    }
576
-
577
-
578
-    /**
579
-     * Get a list of columns. The format is:
580
-     * 'internal-name' => 'Title'
581
-     *
582
-     * @return array
583
-     * @since  3.1.0
584
-     * @access public
585
-     * @abstract
586
-     */
587
-    public function get_columns()
588
-    {
589
-        /**
590
-         * Dynamic hook allowing for adding additional columns in this list table.
591
-         * Note that $this->screen->id is in the format
592
-         * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
593
-         * table it is: event-espresso_page_espresso_messages.
594
-         * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
595
-         * hook prefix ("event-espresso") will be different.
596
-         *
597
-         * @var array
598
-         */
599
-        return apply_filters('FHEE_manage_' . $this->screen->id . '_columns', $this->_columns, $this->_screen);
600
-    }
601
-
602
-
603
-    /**
604
-     * Get an associative array ( id => link ) with the list
605
-     * of views available on this table.
606
-     *
607
-     * @return array
608
-     * @since  3.1.0
609
-     * @access protected
610
-     */
611
-    public function get_views()
612
-    {
613
-        return $this->_views;
614
-    }
615
-
616
-
617
-    /**
618
-     * Generate the views html.
619
-     */
620
-    public function display_views()
621
-    {
622
-        $views           = $this->get_views();
623
-        $assembled_views = [];
624
-
625
-        if (empty($views)) {
626
-            return;
627
-        }
628
-        echo "<ul class='subsubsub'>\n";
629
-        foreach ($views as $view) {
630
-            $count = isset($view['count']) && ! empty($view['count']) ? absint($view['count']) : 0;
631
-            if (isset($view['slug'], $view['class'], $view['url'], $view['label'])) {
632
-                $filter = "<li";
633
-                $filter .= $view['class'] ? " class='" . esc_attr($view['class']) . "'" : '';
634
-                $filter .= ">";
635
-                $filter .= '<a href="' . esc_url_raw($view['url']) . '">' . esc_html($view['label']) . '</a>';
636
-                $filter .= '<span class="count">(' . $count . ')</span>';
637
-                $filter .= '</li>';
638
-                $assembled_views[ $view['slug'] ] = $filter;
639
-            }
640
-        }
641
-
642
-        echo ! empty($assembled_views)
643
-            ? implode("<li style='margin:0 .5rem;'>|</li>", $assembled_views)
644
-            : '';
645
-        echo "</ul>";
646
-    }
647
-
648
-
649
-    /**
650
-     * Generates content for a single row of the table
651
-     *
652
-     * @param EE_Base_Class $item The current item
653
-     * @since  4.1
654
-     * @access public
655
-     */
656
-    public function single_row($item)
657
-    {
658
-        $row_class = $this->_get_row_class($item);
659
-        echo '<tr class="' . esc_attr($row_class) . '">';
660
-        $this->single_row_columns($item); // already escaped
661
-        echo '</tr>';
662
-    }
663
-
664
-
665
-    /**
666
-     * This simply sets up the row class for the table rows.
667
-     * Allows for easier overriding of child methods for setting up sorting.
668
-     *
669
-     * @param EE_Base_Class $item the current item
670
-     * @return string
671
-     */
672
-    protected function _get_row_class($item)
673
-    {
674
-        static $row_class = '';
675
-        $row_class = ($row_class === '' ? 'alternate' : '');
676
-
677
-        $new_row_class = $row_class;
678
-
679
-        if (! empty($this->_ajax_sorting_callback)) {
680
-            $new_row_class .= ' rowsortable';
681
-        }
682
-
683
-        return $new_row_class;
684
-    }
685
-
686
-
687
-    /**
688
-     * @return array
689
-     */
690
-    public function get_sortable_columns()
691
-    {
692
-        return (array) $this->_sortable_columns;
693
-    }
694
-
695
-
696
-    /**
697
-     * @return string
698
-     */
699
-    public function get_ajax_sorting_callback()
700
-    {
701
-        return $this->_ajax_sorting_callback;
702
-    }
703
-
704
-
705
-    /**
706
-     * @return array
707
-     */
708
-    public function get_hidden_columns()
709
-    {
710
-        $user_id     = get_current_user_id();
711
-        $has_default = get_user_option('default' . $this->screen->id . 'columnshidden', $user_id);
712
-        if (empty($has_default) && ! empty($this->_hidden_columns)) {
713
-            update_user_option($user_id, 'default' . $this->screen->id . 'columnshidden', true);
714
-            update_user_option($user_id, 'manage' . $this->screen->id . 'columnshidden', $this->_hidden_columns, true);
715
-        }
716
-        $ref = 'manage' . $this->screen->id . 'columnshidden';
717
-        return (array) get_user_option($ref, $user_id);
718
-    }
719
-
720
-
721
-    /**
722
-     * Generates the columns for a single row of the table.
723
-     * Overridden from wp_list_table so as to allow us to filter the column content for a given
724
-     * column.
725
-     *
726
-     * @param EE_Base_Class $item The current item
727
-     * @since 3.1.0
728
-     */
729
-    public function single_row_columns($item)
730
-    {
731
-        [$columns, $hidden, $sortable, $primary] = $this->get_column_info();
732
-
733
-        foreach ($columns as $column_name => $column_display_name) {
734
-
735
-            /**
736
-             * With WordPress version 4.3.RC+ WordPress started using the hidden css class to control whether columns
737
-             * are hidden or not instead of using "display:none;".  This bit of code provides backward compat.
738
-             */
739
-            $hidden_class = in_array($column_name, $hidden) ? ' hidden' : '';
740
-
741
-            $classes = $column_name . ' column-' . $column_name . $hidden_class;
742
-            if ($primary === $column_name) {
743
-                $classes .= ' has-row-actions column-primary';
744
-            }
745
-
746
-            $data = ' data-colname="' . wp_strip_all_tags($column_display_name) . '"';
747
-
748
-            $class = 'class="' . esc_attr($classes) . '"';
749
-
750
-            $attributes = "{$class}{$data}";
751
-
752
-            if ($column_name === 'cb') {
753
-                echo '<th scope="row" class="check-column">';
754
-                echo apply_filters(
755
-                    'FHEE__EE_Admin_List_Table__single_row_columns__column_cb_content',
756
-                    $this->column_cb($item), // already escaped
757
-                    $item,
758
-                    $this
759
-                );
760
-                echo '</th>';
761
-            } elseif (method_exists($this, 'column_' . $column_name)) {
762
-                echo "<td $attributes>"; // already escaped
763
-                echo apply_filters(
764
-                    'FHEE__EE_Admin_List_Table__single_row_columns__column_' . $column_name . '__column_content',
765
-                    call_user_func([$this, 'column_' . $column_name], $item),
766
-                    $item,
767
-                    $this
768
-                );
769
-                echo $this->handle_row_actions($item, $column_name, $primary);
770
-                echo "</td>";
771
-            } else {
772
-                echo "<td $attributes>"; // already escaped
773
-                echo apply_filters(
774
-                    'FHEE__EE_Admin_List_Table__single_row_columns__column_default__column_content',
775
-                    $this->column_default($item, $column_name),
776
-                    $item,
777
-                    $column_name,
778
-                    $this
779
-                );
780
-                echo $this->handle_row_actions($item, $column_name, $primary);
781
-                echo "</td>";
782
-            }
783
-        }
784
-    }
785
-
786
-
787
-    /**
788
-     * Extra controls to be displayed between bulk actions and pagination
789
-     *
790
-     * @access public
791
-     * @param string $which
792
-     * @throws EE_Error
793
-     */
794
-    public function extra_tablenav($which)
795
-    {
796
-        if ($which === 'top') {
797
-            $this->_filters();
798
-            echo $this->_get_hidden_fields(); // already escaped
799
-        } else {
800
-            echo '<div class="list-table-bottom-buttons alignleft actions">';
801
-            foreach ($this->_bottom_buttons as $type => $action) {
802
-                $route         = isset($action['route']) ? $action['route'] : '';
803
-                $extra_request = isset($action['extra_request']) ? $action['extra_request'] : '';
804
-                // already escaped
805
-                echo $this->_admin_page->get_action_link_or_button(
806
-                    $route,
807
-                    $type,
808
-                    $extra_request,
809
-                    'button button-secondary'
810
-                );
811
-            }
812
-            do_action('AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', $this, $this->_screen);
813
-            echo '</div>';
814
-        }
815
-    }
816
-
817
-
818
-    /**
819
-     * Get an associative array ( option_name => option_title ) with the list
820
-     * of bulk actions available on this table.
821
-     *
822
-     * @return array
823
-     * @since  3.1.0
824
-     * @access protected
825
-     */
826
-    public function get_bulk_actions()
827
-    {
828
-        return (array) $this->_get_bulk_actions();
829
-    }
830
-
831
-
832
-    /**
833
-     * Processing bulk actions.
834
-     */
835
-    public function process_bulk_action()
836
-    {
837
-        // this is not used it is handled by the child EE_Admin_Page class (routes).  However, including here for
838
-        // reference in case there is a case where it gets used.
839
-    }
840
-
841
-
842
-    /**
843
-     * returns the EE admin page this list table is associated with
844
-     *
845
-     * @return EE_Admin_Page
846
-     */
847
-    public function get_admin_page()
848
-    {
849
-        return $this->_admin_page;
850
-    }
851
-
852
-
853
-    /**
854
-     * A "helper" function for all children to provide an html string of
855
-     * actions to output in their content.  It is preferable for child classes
856
-     * to use this method for generating their actions content so that it's
857
-     * filterable by plugins
858
-     *
859
-     * @param string        $action_container           what are the html container
860
-     *                                                  elements for this actions string?
861
-     * @param string        $action_class               What class is for the container
862
-     *                                                  element.
863
-     * @param string        $action_items               The contents for the action items
864
-     *                                                  container.  This is filtered before
865
-     *                                                  returned.
866
-     * @param string        $action_id                  What id (optional) is used for the
867
-     *                                                  container element.
868
-     * @param EE_Base_Class $item                       The object for the column displaying
869
-     *                                                  the actions.
870
-     * @return string The assembled action elements container.
871
-     */
872
-    protected function _action_string(
873
-        $action_items,
874
-        $item,
875
-        $action_container = 'ul',
876
-        $action_class = '',
877
-        $action_id = ''
878
-    ) {
879
-        $action_class = ! empty($action_class) ? ' class="' . esc_attr($action_class) . '"' : '';
880
-        $action_id    = ! empty($action_id) ? ' id="' . esc_attr($action_id) . '"' : '';
881
-        $open_tag     = ! empty($action_container) ? '<' . $action_container . $action_class . $action_id . '>' : '';
882
-        $close_tag    = ! empty($action_container) ? '</' . $action_container . '>' : '';
883
-        try {
884
-            $content = apply_filters(
885
-                'FHEE__EE_Admin_List_Table___action_string__action_items',
886
-                $action_items,
887
-                $item,
888
-                $this
889
-            );
890
-        } catch (Exception $e) {
891
-            if (WP_DEBUG) {
892
-                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
893
-            }
894
-            $content = $action_items;
895
-        }
896
-        return "{$open_tag}{$content}{$close_tag}";
897
-    }
898
-
899
-
900
-    /**
901
-     * @return string
902
-     */
903
-    protected function getReturnUrl()
904
-    {
905
-        $host = $this->_admin_page->get_request()->getServerParam('HTTP_HOST');
906
-        $uri  = $this->_admin_page->get_request()->getServerParam('REQUEST_URI');
907
-        return urlencode(esc_url_raw("//{$host}{$uri}"));
908
-    }
463
+	}
464
+
465
+
466
+	/**
467
+	 * _filters
468
+	 * This receives the filters array from children _get_table_filters() and assembles the string including the filter
469
+	 * button.
470
+	 *
471
+	 * @access private
472
+	 * @return void  echos html showing filters
473
+	 */
474
+	private function _filters()
475
+	{
476
+		$classname = get_class($this);
477
+		$filters   = apply_filters(
478
+			"FHEE__{$classname}__filters",
479
+			(array) $this->_get_table_filters(),
480
+			$this,
481
+			$this->_screen
482
+		);
483
+
484
+		if (empty($filters)) {
485
+			return;
486
+		}
487
+		foreach ($filters as $filter) {
488
+			echo $filter; // already escaped
489
+		}
490
+		// add filter button at end
491
+		echo '<input type="submit" class="button-secondary" value="'
492
+			 . esc_html__('Filter', 'event_espresso')
493
+			 . '" id="post-query-submit" />';
494
+		// add reset filters button at end
495
+		echo '<a class="button button-secondary"  href="'
496
+			 . esc_url_raw($this->_admin_page->get_current_page_view_url())
497
+			 . '" style="display:inline-block">'
498
+			 . esc_html__('Reset Filters', 'event_espresso')
499
+			 . '</a>';
500
+	}
501
+
502
+
503
+	/**
504
+	 * Callback for 'list_table_primary_column' WordPress filter
505
+	 * If child EE_Admin_List_Table classes set the _primary_column property then that will be set as the primary
506
+	 * column when class is instantiated.
507
+	 *
508
+	 * @param string $column_name
509
+	 * @return string
510
+	 * @see WP_List_Table::get_primary_column_name
511
+	 */
512
+	public function set_primary_column($column_name)
513
+	{
514
+		return ! empty($this->_primary_column) ? $this->_primary_column : $column_name;
515
+	}
516
+
517
+
518
+	/**
519
+	 *
520
+	 */
521
+	public function prepare_items()
522
+	{
523
+
524
+		$this->_set_column_info();
525
+		// $this->_column_headers = $this->get_column_info();
526
+		$total_items = $this->_all_data_count;
527
+		$this->process_bulk_action();
528
+
529
+		$this->items = $this->_data;
530
+		$this->set_pagination_args(
531
+			[
532
+				'total_items' => $total_items,
533
+				'per_page'    => $this->_per_page,
534
+				'total_pages' => ceil($total_items / $this->_per_page),
535
+			]
536
+		);
537
+	}
538
+
539
+
540
+	/**
541
+	 * @param object|array $item
542
+	 * @return string html content for the column
543
+	 */
544
+	protected function column_cb($item)
545
+	{
546
+		return '';
547
+	}
548
+
549
+
550
+	/**
551
+	 * This column is the default for when there is no defined column method for a registered column.
552
+	 * This can be overridden by child classes, but allows for hooking in for custom columns.
553
+	 *
554
+	 * @param EE_Base_Class $item
555
+	 * @param string        $column_name The column being called.
556
+	 * @return string html content for the column
557
+	 */
558
+	public function column_default($item, $column_name)
559
+	{
560
+		/**
561
+		 * Dynamic hook allowing for adding additional column content in this list table.
562
+		 * Note that $this->screen->id is in the format
563
+		 * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
564
+		 * table it is: event-espresso_page_espresso_messages.
565
+		 * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
566
+		 * hook prefix ("event-espresso") will be different.
567
+		 */
568
+		ob_start();
569
+		do_action(
570
+			'AHEE__EE_Admin_List_Table__column_' . $column_name . '__' . $this->screen->id,
571
+			$item,
572
+			$this->_screen
573
+		);
574
+		return ob_get_clean();
575
+	}
576
+
577
+
578
+	/**
579
+	 * Get a list of columns. The format is:
580
+	 * 'internal-name' => 'Title'
581
+	 *
582
+	 * @return array
583
+	 * @since  3.1.0
584
+	 * @access public
585
+	 * @abstract
586
+	 */
587
+	public function get_columns()
588
+	{
589
+		/**
590
+		 * Dynamic hook allowing for adding additional columns in this list table.
591
+		 * Note that $this->screen->id is in the format
592
+		 * {sanitize_title($top_level_menu_label)}_page_{$espresso_admin_page_slug}.  So for the messages list
593
+		 * table it is: event-espresso_page_espresso_messages.
594
+		 * However, take note that if the top level menu label has been translated (i.e. "Event Espresso"). then the
595
+		 * hook prefix ("event-espresso") will be different.
596
+		 *
597
+		 * @var array
598
+		 */
599
+		return apply_filters('FHEE_manage_' . $this->screen->id . '_columns', $this->_columns, $this->_screen);
600
+	}
601
+
602
+
603
+	/**
604
+	 * Get an associative array ( id => link ) with the list
605
+	 * of views available on this table.
606
+	 *
607
+	 * @return array
608
+	 * @since  3.1.0
609
+	 * @access protected
610
+	 */
611
+	public function get_views()
612
+	{
613
+		return $this->_views;
614
+	}
615
+
616
+
617
+	/**
618
+	 * Generate the views html.
619
+	 */
620
+	public function display_views()
621
+	{
622
+		$views           = $this->get_views();
623
+		$assembled_views = [];
624
+
625
+		if (empty($views)) {
626
+			return;
627
+		}
628
+		echo "<ul class='subsubsub'>\n";
629
+		foreach ($views as $view) {
630
+			$count = isset($view['count']) && ! empty($view['count']) ? absint($view['count']) : 0;
631
+			if (isset($view['slug'], $view['class'], $view['url'], $view['label'])) {
632
+				$filter = "<li";
633
+				$filter .= $view['class'] ? " class='" . esc_attr($view['class']) . "'" : '';
634
+				$filter .= ">";
635
+				$filter .= '<a href="' . esc_url_raw($view['url']) . '">' . esc_html($view['label']) . '</a>';
636
+				$filter .= '<span class="count">(' . $count . ')</span>';
637
+				$filter .= '</li>';
638
+				$assembled_views[ $view['slug'] ] = $filter;
639
+			}
640
+		}
641
+
642
+		echo ! empty($assembled_views)
643
+			? implode("<li style='margin:0 .5rem;'>|</li>", $assembled_views)
644
+			: '';
645
+		echo "</ul>";
646
+	}
647
+
648
+
649
+	/**
650
+	 * Generates content for a single row of the table
651
+	 *
652
+	 * @param EE_Base_Class $item The current item
653
+	 * @since  4.1
654
+	 * @access public
655
+	 */
656
+	public function single_row($item)
657
+	{
658
+		$row_class = $this->_get_row_class($item);
659
+		echo '<tr class="' . esc_attr($row_class) . '">';
660
+		$this->single_row_columns($item); // already escaped
661
+		echo '</tr>';
662
+	}
663
+
664
+
665
+	/**
666
+	 * This simply sets up the row class for the table rows.
667
+	 * Allows for easier overriding of child methods for setting up sorting.
668
+	 *
669
+	 * @param EE_Base_Class $item the current item
670
+	 * @return string
671
+	 */
672
+	protected function _get_row_class($item)
673
+	{
674
+		static $row_class = '';
675
+		$row_class = ($row_class === '' ? 'alternate' : '');
676
+
677
+		$new_row_class = $row_class;
678
+
679
+		if (! empty($this->_ajax_sorting_callback)) {
680
+			$new_row_class .= ' rowsortable';
681
+		}
682
+
683
+		return $new_row_class;
684
+	}
685
+
686
+
687
+	/**
688
+	 * @return array
689
+	 */
690
+	public function get_sortable_columns()
691
+	{
692
+		return (array) $this->_sortable_columns;
693
+	}
694
+
695
+
696
+	/**
697
+	 * @return string
698
+	 */
699
+	public function get_ajax_sorting_callback()
700
+	{
701
+		return $this->_ajax_sorting_callback;
702
+	}
703
+
704
+
705
+	/**
706
+	 * @return array
707
+	 */
708
+	public function get_hidden_columns()
709
+	{
710
+		$user_id     = get_current_user_id();
711
+		$has_default = get_user_option('default' . $this->screen->id . 'columnshidden', $user_id);
712
+		if (empty($has_default) && ! empty($this->_hidden_columns)) {
713
+			update_user_option($user_id, 'default' . $this->screen->id . 'columnshidden', true);
714
+			update_user_option($user_id, 'manage' . $this->screen->id . 'columnshidden', $this->_hidden_columns, true);
715
+		}
716
+		$ref = 'manage' . $this->screen->id . 'columnshidden';
717
+		return (array) get_user_option($ref, $user_id);
718
+	}
719
+
720
+
721
+	/**
722
+	 * Generates the columns for a single row of the table.
723
+	 * Overridden from wp_list_table so as to allow us to filter the column content for a given
724
+	 * column.
725
+	 *
726
+	 * @param EE_Base_Class $item The current item
727
+	 * @since 3.1.0
728
+	 */
729
+	public function single_row_columns($item)
730
+	{
731
+		[$columns, $hidden, $sortable, $primary] = $this->get_column_info();
732
+
733
+		foreach ($columns as $column_name => $column_display_name) {
734
+
735
+			/**
736
+			 * With WordPress version 4.3.RC+ WordPress started using the hidden css class to control whether columns
737
+			 * are hidden or not instead of using "display:none;".  This bit of code provides backward compat.
738
+			 */
739
+			$hidden_class = in_array($column_name, $hidden) ? ' hidden' : '';
740
+
741
+			$classes = $column_name . ' column-' . $column_name . $hidden_class;
742
+			if ($primary === $column_name) {
743
+				$classes .= ' has-row-actions column-primary';
744
+			}
745
+
746
+			$data = ' data-colname="' . wp_strip_all_tags($column_display_name) . '"';
747
+
748
+			$class = 'class="' . esc_attr($classes) . '"';
749
+
750
+			$attributes = "{$class}{$data}";
751
+
752
+			if ($column_name === 'cb') {
753
+				echo '<th scope="row" class="check-column">';
754
+				echo apply_filters(
755
+					'FHEE__EE_Admin_List_Table__single_row_columns__column_cb_content',
756
+					$this->column_cb($item), // already escaped
757
+					$item,
758
+					$this
759
+				);
760
+				echo '</th>';
761
+			} elseif (method_exists($this, 'column_' . $column_name)) {
762
+				echo "<td $attributes>"; // already escaped
763
+				echo apply_filters(
764
+					'FHEE__EE_Admin_List_Table__single_row_columns__column_' . $column_name . '__column_content',
765
+					call_user_func([$this, 'column_' . $column_name], $item),
766
+					$item,
767
+					$this
768
+				);
769
+				echo $this->handle_row_actions($item, $column_name, $primary);
770
+				echo "</td>";
771
+			} else {
772
+				echo "<td $attributes>"; // already escaped
773
+				echo apply_filters(
774
+					'FHEE__EE_Admin_List_Table__single_row_columns__column_default__column_content',
775
+					$this->column_default($item, $column_name),
776
+					$item,
777
+					$column_name,
778
+					$this
779
+				);
780
+				echo $this->handle_row_actions($item, $column_name, $primary);
781
+				echo "</td>";
782
+			}
783
+		}
784
+	}
785
+
786
+
787
+	/**
788
+	 * Extra controls to be displayed between bulk actions and pagination
789
+	 *
790
+	 * @access public
791
+	 * @param string $which
792
+	 * @throws EE_Error
793
+	 */
794
+	public function extra_tablenav($which)
795
+	{
796
+		if ($which === 'top') {
797
+			$this->_filters();
798
+			echo $this->_get_hidden_fields(); // already escaped
799
+		} else {
800
+			echo '<div class="list-table-bottom-buttons alignleft actions">';
801
+			foreach ($this->_bottom_buttons as $type => $action) {
802
+				$route         = isset($action['route']) ? $action['route'] : '';
803
+				$extra_request = isset($action['extra_request']) ? $action['extra_request'] : '';
804
+				// already escaped
805
+				echo $this->_admin_page->get_action_link_or_button(
806
+					$route,
807
+					$type,
808
+					$extra_request,
809
+					'button button-secondary'
810
+				);
811
+			}
812
+			do_action('AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', $this, $this->_screen);
813
+			echo '</div>';
814
+		}
815
+	}
816
+
817
+
818
+	/**
819
+	 * Get an associative array ( option_name => option_title ) with the list
820
+	 * of bulk actions available on this table.
821
+	 *
822
+	 * @return array
823
+	 * @since  3.1.0
824
+	 * @access protected
825
+	 */
826
+	public function get_bulk_actions()
827
+	{
828
+		return (array) $this->_get_bulk_actions();
829
+	}
830
+
831
+
832
+	/**
833
+	 * Processing bulk actions.
834
+	 */
835
+	public function process_bulk_action()
836
+	{
837
+		// this is not used it is handled by the child EE_Admin_Page class (routes).  However, including here for
838
+		// reference in case there is a case where it gets used.
839
+	}
840
+
841
+
842
+	/**
843
+	 * returns the EE admin page this list table is associated with
844
+	 *
845
+	 * @return EE_Admin_Page
846
+	 */
847
+	public function get_admin_page()
848
+	{
849
+		return $this->_admin_page;
850
+	}
851
+
852
+
853
+	/**
854
+	 * A "helper" function for all children to provide an html string of
855
+	 * actions to output in their content.  It is preferable for child classes
856
+	 * to use this method for generating their actions content so that it's
857
+	 * filterable by plugins
858
+	 *
859
+	 * @param string        $action_container           what are the html container
860
+	 *                                                  elements for this actions string?
861
+	 * @param string        $action_class               What class is for the container
862
+	 *                                                  element.
863
+	 * @param string        $action_items               The contents for the action items
864
+	 *                                                  container.  This is filtered before
865
+	 *                                                  returned.
866
+	 * @param string        $action_id                  What id (optional) is used for the
867
+	 *                                                  container element.
868
+	 * @param EE_Base_Class $item                       The object for the column displaying
869
+	 *                                                  the actions.
870
+	 * @return string The assembled action elements container.
871
+	 */
872
+	protected function _action_string(
873
+		$action_items,
874
+		$item,
875
+		$action_container = 'ul',
876
+		$action_class = '',
877
+		$action_id = ''
878
+	) {
879
+		$action_class = ! empty($action_class) ? ' class="' . esc_attr($action_class) . '"' : '';
880
+		$action_id    = ! empty($action_id) ? ' id="' . esc_attr($action_id) . '"' : '';
881
+		$open_tag     = ! empty($action_container) ? '<' . $action_container . $action_class . $action_id . '>' : '';
882
+		$close_tag    = ! empty($action_container) ? '</' . $action_container . '>' : '';
883
+		try {
884
+			$content = apply_filters(
885
+				'FHEE__EE_Admin_List_Table___action_string__action_items',
886
+				$action_items,
887
+				$item,
888
+				$this
889
+			);
890
+		} catch (Exception $e) {
891
+			if (WP_DEBUG) {
892
+				EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
893
+			}
894
+			$content = $action_items;
895
+		}
896
+		return "{$open_tag}{$content}{$close_tag}";
897
+	}
898
+
899
+
900
+	/**
901
+	 * @return string
902
+	 */
903
+	protected function getReturnUrl()
904
+	{
905
+		$host = $this->_admin_page->get_request()->getServerParam('HTTP_HOST');
906
+		$uri  = $this->_admin_page->get_request()->getServerParam('REQUEST_URI');
907
+		return urlencode(esc_url_raw("//{$host}{$uri}"));
908
+	}
909 909
 }
Please login to merge, or discard this patch.